diff --git a/apps/blade/src/app/kevin-rodriguez/_components/about-section.tsx b/apps/blade/src/app/kevin-rodriguez/_components/about-section.tsx new file mode 100644 index 00000000..2123395a --- /dev/null +++ b/apps/blade/src/app/kevin-rodriguez/_components/about-section.tsx @@ -0,0 +1,67 @@ +"use client"; + +import { Card } from "@forge/ui/card"; +import { useScrollAnimation } from "../_hooks/useScrollAnimation"; + +export function AboutSection() { + const { ref, isVisible } = useScrollAnimation(0.2); + + return ( +
+ {/* Animated background bubbles */} +
+ {[...Array(8)].map((_, i) => ( +
+ ))} +
+ +
+

+ About Me +

+ + +
+

+ Hi! I'm Kevin Rodriguez, a passionate full-stack developer with a love for building + web applications. I'm excited about the opportunity to join the Knight Hacks dev team + and contribute to creating amazing experiences for the hackathon community. +

+ +

+ I believe in writing clean, maintainable code and continuously learning new + technologies. My goal is to not only contribute technically but also to collaborate + with the team to solve challenging problems and deliver impactful solutions. +

+ +
+ + {/* Stats*/} +
+
+
5+
+
Years Coding
+
+
+
4+
+
Projects Built
+
+
+
+
+
+ ); +} diff --git a/apps/blade/src/app/kevin-rodriguez/_components/hero-section.tsx b/apps/blade/src/app/kevin-rodriguez/_components/hero-section.tsx new file mode 100644 index 00000000..c5ac8637 --- /dev/null +++ b/apps/blade/src/app/kevin-rodriguez/_components/hero-section.tsx @@ -0,0 +1,77 @@ +"use client"; + +import { Button } from "@forge/ui/button"; +import pfp from '../icons/chibi_icon.png'; + +export function HeroSection() { + const handleLinkedIn = () => { + window.open("https://linkedin.com/in/kevinarodriguez25", "_blank"); + }; + + return ( +
+ {/* Animated background bubbles */} +
+
+
+
+
+
+ + {/* Main content */} +
+ {/* Profile picture/avatar */} +
+
+
+ Kevin Rodriguez +
+
+ 💻 +
+
+
+ + {/* Hero text */} +

+ Kevin Rodriguez +

+

+ Full-Stack Developer +

+

+ Knight Hacks Dev Team Application +

+ + {/* Call-to-action buttons */} +
+ +
+
+
+ ); +} diff --git a/apps/blade/src/app/kevin-rodriguez/_components/projects-section.tsx b/apps/blade/src/app/kevin-rodriguez/_components/projects-section.tsx new file mode 100644 index 00000000..07365f1a --- /dev/null +++ b/apps/blade/src/app/kevin-rodriguez/_components/projects-section.tsx @@ -0,0 +1,202 @@ +"use client"; + +import { Card } from "@forge/ui/card"; +import { Badge } from "@forge/ui/badge"; +import { useState } from "react"; +import { useScrollAnimation } from "../_hooks/useScrollAnimation"; + +// Import images +import cyclopBackpack from "../projects-images/cyclops/cyclops-backpack.jpg"; +import testRun from "../projects-images/cyclops/test-run.PNG"; +import emailVerif from "../projects-images/playedit/email-verif.png"; +import gameCover from "../projects-images/playedit/game-cover.png"; +import gamesList from "../projects-images/playedit/games-list.png"; + +interface Project { + title: string; + subtitle: string; + date: string; + description: string[]; + technologies: string[]; + images: any[]; +} + +const projects: Project[] = [ + { + title: "Cyclops - KnightHacks VIII", + subtitle: "AI-Driven Safety System", + date: "Jan. 2025 - Present", + description: [ + "Engineered an AI-driven backpack-mounted safety system that achieved 90% accuracy in detecting potential threats using YOLOv11 and DeepSORT for real-time object tracking.", + "Integrated Firebase Cloud Messaging with an Android app to deliver sub-2-second alerts when suspicious activity was detected in the user's blind spot.", + "Enhanced environmental awareness by fusing ultrasonic sensor data (Arduino) with CV outputs, improving detection confidence by 20%." + ], + technologies: ["YOLOv11", "DeepSORT", "Gemini API", "Firebase", "Arduino", "Android"], + images: [cyclopBackpack, testRun] + }, + { + title: "PlayedIt", + subtitle: "Game Discovery & Recommendation Platform", + date: "Sept. 2025 - Nov. 2025", + description: [ + "Designed and implemented 30+ RESTful API endpoints to support authentication, user/developer profiles, game listings, and personalized recommendations—reducing backend response times by ~40%.", + "Engineered a scalable MongoDB data model and optimized retrieval using Mongoose aggregation pipelines, cutting database load by ~30% during high-traffic operations.", + "Integrated external IGDB-style game metadata to support advanced search, sorting, pagination, and dynamic cover fetching—enabling 50,000+ games to be browsed smoothly." + ], + technologies: ["MongoDB", "Express.js", "React", "Node.js", "IGDB API", "Machine Learning"], + images: [emailVerif, gameCover, gamesList] + } +]; + +function ProjectCard({ project, index }: { project: Project; index: number }) { + const [currentImageIndex, setCurrentImageIndex] = useState(0); + const { ref, isVisible } = useScrollAnimation(0.1); + + const goToPrevious = () => { + setCurrentImageIndex((prev) => (prev - 1 + project.images.length) % project.images.length); + }; + + const goToNext = () => { + setCurrentImageIndex((prev) => (prev + 1) % project.images.length); + }; + + return ( +
+ +
+ {/* Screenshot Carousel */} +
+ {project.images[currentImageIndex] && ( + {`${project.title} + )} + + {/* Left/Right navigation buttons */} + {project.images.length > 1 && ( + <> + + + + )} + + {/* Image indicators */} +
+ {project.images.map((_, idx) => ( +
+
+ + {/* Project Details */} +
+
+

{project.title}

+

{project.subtitle}

+

{project.date}

+
+ + {/* Tech Stack */} +
+ {project.technologies.map((tech) => ( + + {tech} + + ))} +
+ + {/* Description */} +
    + {project.description.map((item, idx) => ( +
  • + + {item} +
  • + ))} +
+
+
+
+
+ ); +} + +export function ProjectsSection() { + const { ref, isVisible } = useScrollAnimation(0.1); + + return ( +
+ {/* Animated background */} +
+ {[...Array(6)].map((_, i) => ( +
+ ))} +
+ +
+

+ Featured Projects +

+

+ A selection of my recent work and hackathon projects +

+ +
+ {projects.map((project, index) => ( + + ))} +
+
+
+ ); +} diff --git a/apps/blade/src/app/kevin-rodriguez/_components/skills-section.tsx b/apps/blade/src/app/kevin-rodriguez/_components/skills-section.tsx new file mode 100644 index 00000000..4de85a50 --- /dev/null +++ b/apps/blade/src/app/kevin-rodriguez/_components/skills-section.tsx @@ -0,0 +1,88 @@ +"use client"; + +import { Card } from "@forge/ui/card"; +import { Badge } from "@forge/ui/badge"; +import { useScrollAnimation } from "../_hooks/useScrollAnimation"; + +const skills = [ + { name: "JavaScript", icon: "💛" }, + { name: "TypeScript", icon: "💙" }, + { name: "React", icon: "⚛️" }, + { name: "Next.js", icon: "▲" }, + { name: "Node.js", icon: "🟢" }, + { name: "Express", icon: "🚂" }, + { name: "PostgreSQL", icon: "🐘" }, + { name: "Tailwind CSS", icon: "🎨" }, + { name: "Git", icon: "📦" }, + { name: "REST APIs", icon: "🔌" }, + { name: "HTML/CSS", icon: "🌐" }, + { name: "Python", icon: "🐍" }, +]; + +const interests = [ + "Full-Stack Development", + "UI/UX Design", + "Open Source", + "Backend Systems", + "Developer Tools", + "Database Management", +]; + +export function SkillsSection() { + const { ref, isVisible } = useScrollAnimation(0.2); + + return ( +
+ {/* Gradient background */} +
+ +
+

+ Skills & Technologies +

+ + + {/* Skills Grid */} +
+ {skills.map((skill, index) => ( + + {skill.icon} + {skill.name} + + ))} +
+ + {/* Divider */} +
+ + {/* Interests Section */} +
+

Areas of Interest

+
+ {interests.map((interest, index) => ( + + {interest} + + ))} +
+
+ +
+
+ ); +} diff --git a/apps/blade/src/app/kevin-rodriguez/_hooks/useScrollAnimation.ts b/apps/blade/src/app/kevin-rodriguez/_hooks/useScrollAnimation.ts new file mode 100644 index 00000000..17f165f9 --- /dev/null +++ b/apps/blade/src/app/kevin-rodriguez/_hooks/useScrollAnimation.ts @@ -0,0 +1,31 @@ +"use client"; + +import { useEffect, useRef, useState } from "react"; + +export function useScrollAnimation(threshold = 0.1) { + const ref = useRef(null); + const [isVisible, setIsVisible] = useState(false); + + useEffect(() => { + const element = ref.current; + if (!element) return; + + const observer = new IntersectionObserver( + ([entry]) => { + if (entry && entry.isIntersecting) { + setIsVisible(true); + observer.unobserve(element); + } + }, + { threshold } + ); + + observer.observe(element); + + return () => { + observer.disconnect(); + }; + }, [threshold]); + + return { ref, isVisible }; +} diff --git a/apps/blade/src/app/kevin-rodriguez/_styles/animations.css b/apps/blade/src/app/kevin-rodriguez/_styles/animations.css new file mode 100644 index 00000000..5584a064 --- /dev/null +++ b/apps/blade/src/app/kevin-rodriguez/_styles/animations.css @@ -0,0 +1,112 @@ +/* Floating animation */ +@keyframes float { + 0%, 100% { + transform: translateY(0px); + } + 50% { + transform: translateY(-20px); + } +} + +/* Slide up animation */ +@keyframes slide-up { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* Fade in animation */ +@keyframes fade-in { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +/* Bubble float animation */ +@keyframes bubble-float { + 0%, 100% { + transform: translateY(0) translateX(0); + } + 25% { + transform: translateY(-30px) translateX(10px); + } + 50% { + transform: translateY(-15px) translateX(-10px); + } + 75% { + transform: translateY(-35px) translateX(5px); + } +} + +/* Gradient animation */ +@keyframes gradient-shift { + 0% { + background-position: 0% 50%; + } + 50% { + background-position: 100% 50%; + } + 100% { + background-position: 0% 50%; + } +} + +/* Typing animation */ +@keyframes typing { + from { + width: 0; + } + to { + width: 100%; + } +} + +/* Blinking caret */ +@keyframes blink-caret { + from, to { + border-color: transparent; + } + 50% { + border-color: var(--primary); + } +} + +/* Apply animations */ +.animate-float { + animation: float 5s ease-in-out infinite; +} + +.animate-slide-up { + animation: slide-up 0.6s ease-out forwards; + opacity: 0; +} + +.animate-fade-in { + animation: fade-in 0.8s ease-out forwards; +} + +.animate-bubble-float { + animation: bubble-float 4s ease-in-out infinite; +} + +.animate-gradient { + background-size: 200% 200%; + animation: gradient-shift 6s ease infinite; +} + +.typing-animation { + overflow: hidden; + border-right: 2px solid var(--primary); + white-space: nowrap; + animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite; + width: fit-content; + display: inline-block; +} diff --git a/apps/blade/src/app/kevin-rodriguez/icons/chibi_icon.png b/apps/blade/src/app/kevin-rodriguez/icons/chibi_icon.png new file mode 100644 index 00000000..d5c2ed80 Binary files /dev/null and b/apps/blade/src/app/kevin-rodriguez/icons/chibi_icon.png differ diff --git a/apps/blade/src/app/kevin-rodriguez/page.tsx b/apps/blade/src/app/kevin-rodriguez/page.tsx new file mode 100644 index 00000000..4ecd46a9 --- /dev/null +++ b/apps/blade/src/app/kevin-rodriguez/page.tsx @@ -0,0 +1,24 @@ +import type { Metadata } from "next"; + +import "./_styles/animations.css"; + +import { HeroSection } from "./_components/hero-section"; +import { AboutSection } from "./_components/about-section"; +import { SkillsSection } from "./_components/skills-section"; +import { ProjectsSection } from "./_components/projects-section"; + +export const metadata: Metadata = { + title: "Kevin Rodriguez | Dev Team Application", + description: "Knight Hacks Dev Team Application - Kevin Rodriguez", +}; + +export default function KevinRodriguezPage() { + return ( +
+ + + + +
+ ); +} diff --git a/apps/blade/src/app/kevin-rodriguez/projects-images/cyclops/cyclops-backpack.jpg b/apps/blade/src/app/kevin-rodriguez/projects-images/cyclops/cyclops-backpack.jpg new file mode 100644 index 00000000..93ead40a Binary files /dev/null and b/apps/blade/src/app/kevin-rodriguez/projects-images/cyclops/cyclops-backpack.jpg differ diff --git a/apps/blade/src/app/kevin-rodriguez/projects-images/cyclops/test-run.PNG b/apps/blade/src/app/kevin-rodriguez/projects-images/cyclops/test-run.PNG new file mode 100644 index 00000000..31b67fe7 Binary files /dev/null and b/apps/blade/src/app/kevin-rodriguez/projects-images/cyclops/test-run.PNG differ diff --git a/apps/blade/src/app/kevin-rodriguez/projects-images/images.d.ts b/apps/blade/src/app/kevin-rodriguez/projects-images/images.d.ts new file mode 100644 index 00000000..6681b95f --- /dev/null +++ b/apps/blade/src/app/kevin-rodriguez/projects-images/images.d.ts @@ -0,0 +1,4 @@ +declare module "*.PNG" { + const value: any; + export default value; +} diff --git a/apps/blade/src/app/kevin-rodriguez/projects-images/playedit/email-verif.png b/apps/blade/src/app/kevin-rodriguez/projects-images/playedit/email-verif.png new file mode 100644 index 00000000..7f764d95 Binary files /dev/null and b/apps/blade/src/app/kevin-rodriguez/projects-images/playedit/email-verif.png differ diff --git a/apps/blade/src/app/kevin-rodriguez/projects-images/playedit/game-cover.png b/apps/blade/src/app/kevin-rodriguez/projects-images/playedit/game-cover.png new file mode 100644 index 00000000..1bd09908 Binary files /dev/null and b/apps/blade/src/app/kevin-rodriguez/projects-images/playedit/game-cover.png differ diff --git a/apps/blade/src/app/kevin-rodriguez/projects-images/playedit/games-list.png b/apps/blade/src/app/kevin-rodriguez/projects-images/playedit/games-list.png new file mode 100644 index 00000000..52ed7fae Binary files /dev/null and b/apps/blade/src/app/kevin-rodriguez/projects-images/playedit/games-list.png differ