| import { useState } from "react"; |
| import { AnimatePresence, motion } from "framer-motion"; |
| import { ExternalLink, FileText, Github, Linkedin } from "lucide-react"; |
| import { CONTACT_EMAIL, GITHUB_URL, HUGGING_FACE_URL, LINKEDIN_URL } from "@/lib/links"; |
|
|
| type Project = { |
| id: string; |
| era: "UNT - Graduate" | "Accenture" | "Undergrad" | "Independent"; |
| title: string; |
| tagline: string; |
| period: string; |
| details: string[]; |
| stack: string[]; |
| links?: { |
| label: string; |
| href: string; |
| }[]; |
| }; |
|
|
| const projects: Project[] = [ |
| { |
| id: "alive-agents", |
| era: "Independent", |
| title: "Alive - AI Agent Orchestrator", |
| tagline: "Full-stack platform that assembles AI dev teams for any coding task.", |
| period: "2026", |
| details: [ |
| "Spawns 5 role-based agents (Team Lead, Architect, FE Dev, BE Dev, Tester) per project.", |
| "Each agent runs on a different AI provider (DeepSeek, Qwen, Kimi, GLM, GPT) - all in parallel.", |
| "Isolated git worktrees per agent, real-time progress tracking, and live iframe preview.", |
| ], |
| stack: ["TypeScript", "Next.js", "Multi-Agent AI", "React", "Prisma"], |
| links: [ |
| { |
| label: "View Code", |
| href: "https://github.com/im-mj/Agents-", |
| }, |
| ], |
| }, |
| { |
| id: "nimbus-bank", |
| era: "Independent", |
| title: "Nimbus Bank - AI Triage System", |
| tagline: "LangGraph multi-agent pipeline for banking customer support.", |
| period: "Apr 2026", |
| details: [ |
| "Built a LangGraph multi-agent system to classify and route banking support tickets.", |
| "Agents handle intent detection, policy lookup, escalation, and resolution - end to end.", |
| "Delivered full PRD, architecture diagram, and live Streamlit demo for Wipro pre-screening.", |
| ], |
| stack: ["Python", "LangGraph", "LLM", "Streamlit", "Multi-Agent"], |
| links: [ |
| { |
| label: "View Code", |
| href: "https://github.com/im-mj/Nimbus-Bank-Triage", |
| }, |
| ], |
| }, |
| { |
| id: "ghost-job-hunter", |
| era: "Independent", |
| title: "Ghost Job Hunter", |
| tagline: "Chrome extension concept for spotting suspicious or stale job posts.", |
| period: "2026", |
| details: [ |
| "Flags ghost-job warning signs such as stale listings, repeated postings, vague role signals, and weak hiring intent.", |
| "Uses an AI-assisted scoring flow to help job seekers focus on real opportunities instead of wasting applications.", |
| "Connects analytics, recruiting pain points, and browser automation into a practical job-search tool.", |
| ], |
| stack: ["Chrome Extension", "JavaScript", "AI Scoring", "Job Analytics"], |
| links: [ |
| { |
| label: "View Code", |
| href: "https://github.com/im-mj/Ghost-Job-Hunter", |
| }, |
| ], |
| }, |
| { |
| id: "smartscreen", |
| era: "UNT - Graduate", |
| title: "SmartScreen - AI Resume Analyzer", |
| tagline: "AI-driven resume scoring & ATS-match feedback.", |
| period: "Jan 2025 - May 2025", |
| details: [ |
| "Designed an AI scoring engine that grades resumes against a target JD and highlights ATS-killing gaps.", |
| "Generates targeted feedback so candidates can iterate quickly instead of guessing.", |
| "Built as an end-to-end concept: parsing -> scoring -> recommendations.", |
| ], |
| stack: ["Python", "NLP", "AI", "Data Analysis"], |
| }, |
| { |
| id: "cvs", |
| era: "UNT - Graduate", |
| title: "CVS Pharmacy Strategy Thesis", |
| tagline: "Analytics-backed strategy across Finance, Marketing, Ops, HR & AI.", |
| period: "Jan 2025 - May 2025", |
| details: [ |
| "Deep-dived 10-K filings and market data to build a cross-functional growth thesis.", |
| "Layered AI/automation recommendations on top of traditional strategy frames.", |
| "Delivered as a board-style presentation with prioritized initiatives.", |
| ], |
| stack: ["Research", "10-K Analysis", "Strategy", "Presentations"], |
| }, |
| { |
| id: "jobs", |
| era: "UNT - Graduate", |
| title: "Job Market Analysis", |
| tagline: "Interactive Tableau dashboards on hiring trends & skills demand.", |
| period: "Aug 2024 - Dec 2024", |
| details: [ |
| "Cleaned and modeled a multi-source job postings dataset.", |
| "Built dashboards that surface skill demand, salary bands, and role trajectories.", |
| "Designed for non-technical stakeholders to filter and self-serve.", |
| ], |
| stack: ["Tableau", "Data Viz", "SQL"], |
| }, |
| { |
| id: "spend", |
| era: "UNT - Graduate", |
| title: "Student Spending Analysis", |
| tagline: "Regression + ANOVA on monthly student spend patterns.", |
| period: "Aug 2024 - Dec 2024", |
| details: [ |
| "Collected and cleaned a primary dataset from student respondents.", |
| "Used regression and ANOVA to identify which factors actually moved spend.", |
| "Translated stats into plain-English recommendations.", |
| ], |
| stack: ["Minitab", "Excel", "Statistics"], |
| }, |
| { |
| id: "smile", |
| era: "UNT - Graduate", |
| title: "Smile Buddy 3000 - Marketing Concept", |
| tagline: "Superhero-themed product campaign with positioning + messaging.", |
| period: "Jul 2025 - Sep 2025", |
| details: [ |
| "Built persona, value prop, and a launch narrative around a fun mascot.", |
| "Designed campaign assets and a phased go-to-market plan.", |
| ], |
| stack: ["Marketing Strategy", "Brand", "Advertising"], |
| }, |
| { |
| id: "secondlife", |
| era: "UNT - Graduate", |
| title: "Second Life - Organ Matching ML", |
| tagline: "ML pipeline for patient-organ matching and hospital triage.", |
| period: "2025", |
| details: [ |
| "Built end-to-end ML pipeline with tiered matching, feature engineering, and model evaluation.", |
| "Modeled patient and hospital journeys; benchmarked classifiers for match scoring accuracy.", |
| "Deployed on HuggingFace Spaces with full architecture diagrams and a presentation deck.", |
| ], |
| stack: ["Python", "ML", "Flask", "SQL", "HuggingFace"], |
| links: [ |
| { |
| label: "View Code", |
| href: "https://github.com/im-mj/SecondLife", |
| }, |
| ], |
| }, |
| { |
| id: "firewall-auto", |
| era: "Accenture", |
| title: "Firewall Rule Automation", |
| tagline: "Cut manual firewall-rule work by ~40% across enterprise estates.", |
| period: "2022 - 2024", |
| details: [ |
| "Wrote scripts to push and validate firewall rule updates across multiple devices.", |
| "Reduced manual ticket cycle time and configuration drift.", |
| "Improved rule consistency across Telstra Global's hybrid environments.", |
| ], |
| stack: ["Python", "Shell", "Firewalls", "Automation"], |
| }, |
| { |
| id: "malicious-url", |
| era: "Undergrad", |
| title: "Malicious URL Detection (ML)", |
| tagline: "Final-year ML project classifying URLs as safe vs malicious.", |
| period: "Nov 2020 - Feb 2021", |
| details: [ |
| "Led a team during lockdown to build, train and evaluate the classifier.", |
| "Engineered URL features and benchmarked multiple ML models.", |
| "Presented results in multiple seminars to faculty and peers.", |
| ], |
| stack: ["Python", "Machine Learning", "Team Lead"], |
| links: [ |
| { |
| label: "Research Details", |
| href: "#research-publications", |
| }, |
| ], |
| }, |
| { |
| id: "mask", |
| era: "Undergrad", |
| title: "COVID Face Mask Detection", |
| tagline: "Computer vision classifier on a custom dataset.", |
| period: "Mar 2020 - May 2020", |
| details: [ |
| "Built a face-mask detector with a friend-collected custom dataset.", |
| "Iterated remotely during the early pandemic.", |
| ], |
| stack: ["Python", "ML", "Computer Vision"], |
| }, |
| { |
| id: "eeg", |
| era: "Undergrad", |
| title: "Emotion Recognition from EEG Signals", |
| tagline: "Internship concept project applying ML to EEG.", |
| period: "Dec 2019", |
| details: [ |
| "Explored ML approaches for classifying emotions from EEG signals.", |
| "Collaborated with multi-location team and a hackathon.", |
| ], |
| stack: ["Python", "ML", "Signal Processing"], |
| }, |
| ]; |
|
|
| const researchDetails = [ |
| "Presented at BIGS 2025 and published for SWDSI 2026.", |
| "Built around AI-driven malicious URL detection using deep learning and BERT architecture.", |
| "Connects cybersecurity experience with machine learning research and business analytics storytelling.", |
| "Shows research writing, model evaluation, and technical presentation experience.", |
| ]; |
|
|
| function HuggingFaceMark() { |
| return ( |
| <span className="flex h-5 w-5 items-center justify-center rounded-md bg-amber-100 text-xs font-black text-amber-700"> |
| HF |
| </span> |
| ); |
| } |
|
|
| const workLinks = [ |
| { |
| label: "LinkedIn", |
| href: LINKEDIN_URL, |
| note: "career profile", |
| icon: <Linkedin className="h-5 w-5" />, |
| }, |
| { |
| label: "GitHub", |
| href: GITHUB_URL, |
| note: "code projects", |
| icon: <Github className="h-5 w-5" />, |
| }, |
| { |
| label: "Hugging Face", |
| href: HUGGING_FACE_URL, |
| note: "AI work", |
| icon: <HuggingFaceMark />, |
| }, |
| { |
| label: "Research Paper", |
| href: "#research-publications", |
| note: "BIGS & SWDSI", |
| icon: <FileText className="h-5 w-5" />, |
| }, |
| ]; |
|
|
| const eraColors: Record<Project["era"], string> = { |
| "UNT - Graduate": "bg-accent/15 text-accent border-accent/30", |
| Accenture: "bg-chakra/15 text-chakra border-chakra/30", |
| Undergrad: "bg-navy/10 text-navy border-navy/20", |
| Independent: "bg-emerald-600/10 text-emerald-700 border-emerald-600/25", |
| }; |
|
|
| export function FeaturedProjectsSection() { |
| const [open, setOpen] = useState<string | null>(null); |
| const [researchOpen, setResearchOpen] = useState(false); |
|
|
| return ( |
| <section id="projects" className="py-24"> |
| <div className="mx-auto max-w-6xl px-6"> |
| <div className="flex items-end justify-between flex-wrap gap-4"> |
| <div> |
| <p className="font-display text-accent text-2xl tracking-widest">PROJECTS</p> |
| <h2 className="mt-2 font-display text-5xl text-navy">Featured Work</h2> |
| </div> |
| <p className="text-sm text-muted-foreground max-w-sm"> |
| Hover or tap a card to read the story behind it. |
| </p> |
| </div> |
| |
| <div className="mt-8 grid gap-3 sm:grid-cols-2 lg:grid-cols-4"> |
| {workLinks.map((link) => ( |
| <a |
| key={link.label} |
| href={link.href} |
| target={link.href.startsWith("#") ? undefined : "_blank"} |
| rel={link.href.startsWith("#") ? undefined : "noreferrer"} |
| className="group flex items-center justify-between gap-3 rounded-2xl border border-border bg-card px-4 py-4 text-left transition-all hover:border-accent/45 hover:bg-accent/10 hover:shadow-lg hover:shadow-accent/10" |
| > |
| <span className="flex items-center gap-3"> |
| <span className="flex h-10 w-10 items-center justify-center rounded-xl border border-border bg-background text-navy transition-colors group-hover:border-accent/35 group-hover:text-accent"> |
| {link.icon} |
| </span> |
| <span> |
| <span className="block font-display text-xl leading-none text-navy">{link.label}</span> |
| <span className="mt-1 block text-xs uppercase tracking-[0.14em] text-muted-foreground"> |
| {link.note} |
| </span> |
| </span> |
| </span> |
| <ExternalLink className="h-4 w-4 text-muted-foreground transition-colors group-hover:text-accent" /> |
| </a> |
| ))} |
| </div> |
| |
| <motion.div |
| id="research-publications" |
| role="button" |
| tabIndex={0} |
| onClick={() => setResearchOpen((current) => !current)} |
| onKeyDown={(event) => { |
| if (event.key === "Enter" || event.key === " ") { |
| event.preventDefault(); |
| setResearchOpen((current) => !current); |
| } |
| }} |
| onMouseEnter={() => setResearchOpen(true)} |
| onMouseLeave={() => setResearchOpen(false)} |
| layout |
| className={`group mt-8 cursor-pointer rounded-2xl border bg-card px-6 py-5 shadow-sm transition-all ${ |
| researchOpen ? "border-accent shadow-xl shadow-accent/10" : "border-accent/25 hover:border-accent/40" |
| }`} |
| > |
| <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between"> |
| <div> |
| <p className="font-display text-2xl text-navy">Research Publications</p> |
| <p className="mt-1 text-sm text-foreground/75"> |
| AI-Driven Malicious URL Detection using Deep Learning and BERT Architecture. |
| </p> |
| </div> |
| <span className="inline-flex w-fit rounded-full border border-accent/30 bg-card px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-accent"> |
| Published at BIGS 2025 & SWDSI 2026 |
| </span> |
| </div> |
| |
| <AnimatePresence initial={false}> |
| {researchOpen && ( |
| <motion.div |
| key="research-details" |
| initial={{ opacity: 0, height: 0 }} |
| animate={{ opacity: 1, height: "auto" }} |
| exit={{ opacity: 0, height: 0 }} |
| transition={{ duration: 0.25 }} |
| className="overflow-hidden" |
| > |
| <ul className="mt-5 grid gap-2 text-sm text-foreground/80 md:grid-cols-2 list-disc list-inside"> |
| {researchDetails.map((detail) => ( |
| <li key={detail}>{detail}</li> |
| ))} |
| </ul> |
| </motion.div> |
| )} |
| </AnimatePresence> |
| </motion.div> |
| |
| <div className="mt-12 grid sm:grid-cols-2 lg:grid-cols-3 gap-5"> |
| {projects.map((p) => { |
| const isOpen = open === p.id; |
| const projectLinks = |
| p.links ?? [ |
| { |
| label: "Request Details", |
| href: `mailto:${CONTACT_EMAIL}?subject=${encodeURIComponent(`Project details: ${p.title}`)}`, |
| }, |
| ]; |
| return ( |
| <motion.div |
| key={p.id} |
| role="button" |
| tabIndex={0} |
| onClick={() => setOpen(isOpen ? null : p.id)} |
| onKeyDown={(event) => { |
| if (event.key === "Enter" || event.key === " ") { |
| event.preventDefault(); |
| setOpen(isOpen ? null : p.id); |
| } |
| }} |
| onMouseEnter={() => setOpen(p.id)} |
| onMouseLeave={() => setOpen(null)} |
| layout |
| className={`group relative text-left rounded-2xl border bg-card p-5 overflow-hidden transition-all ${ |
| isOpen ? "border-accent shadow-xl shadow-accent/10" : "border-border hover:border-accent/40" |
| }`} |
| > |
| <div className="flex items-center justify-between gap-2"> |
| <span className={`inline-block text-xs uppercase tracking-[0.18em] font-semibold rounded-full border px-2 py-0.5 ${eraColors[p.era]}`}> |
| {p.era} |
| </span> |
| <span className="text-xs text-muted-foreground">{p.period}</span> |
| </div> |
| <h3 className="mt-3 font-display text-xl text-navy leading-tight">{p.title}</h3> |
| <p className="mt-2 text-sm text-foreground/75 tracking-wide">{p.tagline}</p> |
| |
| <AnimatePresence initial={false}> |
| {isOpen && ( |
| <motion.div |
| key="details" |
| initial={{ opacity: 0, height: 0 }} |
| animate={{ opacity: 1, height: "auto" }} |
| exit={{ opacity: 0, height: 0 }} |
| transition={{ duration: 0.25 }} |
| className="overflow-hidden" |
| > |
| <ul className="mt-4 space-y-2 text-base text-foreground/80 list-disc list-inside tracking-wide leading-relaxed"> |
| {p.details.map((d) => ( |
| <li key={d}>{d}</li> |
| ))} |
| </ul> |
| <div className="mt-4 flex flex-wrap gap-2"> |
| {projectLinks.map((link) => ( |
| <a |
| key={link.label} |
| href={link.href} |
| target={link.href.startsWith("#") || link.href.startsWith("mailto:") ? undefined : "_blank"} |
| rel={link.href.startsWith("#") || link.href.startsWith("mailto:") ? undefined : "noreferrer"} |
| onClick={(event) => event.stopPropagation()} |
| className="inline-flex rounded-full border border-navy/20 px-4 py-2 text-xs font-semibold text-navy hover:border-accent hover:text-accent transition-colors" |
| > |
| {link.label} |
| </a> |
| ))} |
| </div> |
| </motion.div> |
| )} |
| </AnimatePresence> |
| |
| <div className="mt-4 flex flex-wrap gap-1.5"> |
| {p.stack.map((s) => ( |
| <span key={s} className="rounded-md bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground tracking-wide"> |
| {s} |
| </span> |
| ))} |
| </div> |
| |
| <span className="absolute right-4 bottom-4 text-accent text-xs opacity-0 group-hover:opacity-100 transition-opacity"> |
| {isOpen ? "-" : "+"} |
| </span> |
| </motion.div> |
| ); |
| })} |
| </div> |
| </div> |
| </section> |
| ); |
| } |
|
|