diff --git a/src/features/careers/components/CareersPage.jsx b/src/features/careers/components/CareersPage.jsx index 155c83d..efbb2cb 100644 --- a/src/features/careers/components/CareersPage.jsx +++ b/src/features/careers/components/CareersPage.jsx @@ -1,318 +1,143 @@ -import { useEffect, useState } from 'react'; -import { motion } from 'motion/react'; -import { MapPin, Briefcase, ChevronDown, ExternalLink } from 'lucide-react'; +import { useEffect, useMemo, useState } from 'react'; +import { motion, AnimatePresence } from 'motion/react'; +import { MapPin, Briefcase, ChevronDown, ExternalLink, Search, X, Layers } from 'lucide-react'; import Navbar from '../../home/components/Navbar'; import Footer from '../../home/components/Footer'; +import { jobPostings, CATEGORY_ORDER, TAB_FOR_STATUS, DEFAULT_LOCATION } from '../data/jobs'; const APPLY_URL = 'https://forms.gle/PZAZ9rVnYcZvUxx97'; -const jobPostings = [ - { - title: 'Research Engineer (Junior, Senior, Principal)', - experience: 'B.Tech/M.Tech', - about: "Bodhan AI is looking for exceptional Research Engineers to push the boundaries of sovereign AI for India. You will play a critical role in executing research goals, driving experimentation, building robust infrastructure and efficient model training pipelines. Contribute hands-on to model innovation in ASR, ORF, LLMs, TTS, and OCR—with a focus on multilingual, multi-modal, low-resource, and real-world school deployments.", - responsibilities: [ - 'Own the end-to-end model training cycle in one or more of Speech, Language, Vision, and multimodal training', - 'Support Research Scientists by collaborating with them, driving experimentation, translating research ideas into scalable code and executing large-scale experiments', - 'Build pipelines for synthetic data generation and manage the curation of high-quality training datasets', - 'Lead efforts in inference optimization (quantization, pruning, etc.) and ensure models are ready for large-scale, real-world deployment', - 'Maintain and contribute to internal and external open-source AI frameworks and tools', - ], - required: [ - 'B.Tech or M.Tech in Computer Engineering, Computer Science, or a related technical field', - 'Expert-level proficiency in Python and deep learning frameworks like PyTorch, TensorFlow, or JAX', - 'Deep understanding of the model training cycle and experience in deploying AI models in production environments', - 'Proven ability to work towards defined research goals and deliver high-quality, performant software', - ], - preferred: [ - 'A strong portfolio of contributions to major open-source AI projects (provide GitHub/GitLab links)', - 'In-depth understanding or experience in speech, ASR, LLM, or Vision model training and finetuning', - 'Experience with model optimization for low-resource or Indian languages', - 'A track record of publications or research contributions', - 'Background in educational technology, psychometrics, or cognitive science', - ], - }, - { - title: 'Research Scientist (Junior, Senior, Principal)', - experience: 'PhD/MS + 2–6+ years', - about: "Bodhan AI is looking for exceptional Research Scientists to push the boundaries of sovereign AI for India. You will be responsible for driving research initiatives in speech, language, and vision AI tailored for education—with a focus on multilingual, multi-modal, low-resource, and real-world school deployments.", - responsibilities: [ - 'Design and train advanced models across multilingual ASR/TTS, instruction-tuned LLMs (pre-training & post-training), or multimodal OCR/Vision systems', - 'Develop AI models customized to the education domain, addressing literacy diagnostics, reading fluency, and real-world educational outcomes', - 'Develop novel evaluation methods to validate the effectiveness of AI models in improving learning and teaching outcomes', - 'Drive research into low-resource language modeling, efficient training (distillation, quantization, PEFT), and robust performance in noisy or low-bandwidth environments', - 'Work closely with Engineering and Product teams to move models from experimental stages to production-ready deployments in Indian schools', - 'Maintain high standards for reproducibility, rigorous benchmarking, and contribute through publications, open-source contributions, and technical insights', - ], - required: [ - "PhD or Master's degree in Machine Learning, Speech Processing, NLP, Computer Vision, or related field; exceptional Bachelor's candidates also welcome", - 'Principal: 6+ years | Senior: 4+ years | Entry: Graduating PhDs or 2+ years for Masters/Bachelors post-qualification experience in AI/ML research', - 'Proven expertise in at least one of: Speech (ASR, TTS, or speech diagnostics), LLMs (pre-training, fine-tuning, RL, or RAG), or Vision (OCR, document understanding, or multimodal AI)', - 'Publications in top-tier conferences (ICLR, NeurIPS, ACL, CVPR, INTERSPEECH, etc.)', - 'Proficiency in Python and deep learning frameworks like PyTorch, TensorFlow, or JAX', - ], - preferred: [ - 'Experience working with low-resource or Indian languages', - 'Familiarity with model optimization for real-world, large-scale deployments', - 'A background in educational technology, psychometrics, or cognitive science', - 'A track record of contributions to open-source AI projects', - ], - }, - { - title: 'System Architect', - experience: '5–10+ years', - about: "Design and oversee Bodhan AI's technical architecture for research, infrastructure, and applications. Lead technical decisions for scaling to millions of users.", - responsibilities: [ - 'Design end-to-end system architecture for Bodhan AI platforms', - 'Make technology choices for scalability, reliability, and maintainability', - 'Lead technical planning for major initiatives (Bodhan AI Cloud, Arena, etc.)', - 'Review and guide engineering teams on best practices', - 'Establish coding standards, design patterns, and documentation', - 'Balance research needs with production requirements', - ], - required: [ - "Bachelor's or Master's in Computer Science", - '5–10+ years experience in software engineering/architecture', - 'Strong track record of designing large-scale systems', - 'Deep knowledge of distributed systems, databases, and cloud architecture', - 'Experience leading technical teams and making architectural decisions', - 'Excellent communication and documentation skills', - ], - preferred: [ - 'Experience with AI/ML systems architecture', - 'Built systems serving millions of users', - 'Knowledge of Indian language computing challenges', - 'Open-source project leadership', - 'Experience in research-driven organizations as well as enterprise grade systems', - 'Published technical blogs or talks', - 'Contributions to RAG-related open-source projects', - ], - }, - { - title: 'MLOps Engineer', - experience: '2–5 years', - about: "Build and maintain infrastructure for training, deploying, and serving Bodhan AI's models at scale. Ensure reliability for 100K+ monthly downloads and production deployments.", - responsibilities: [ - 'Design CI/CD pipelines for ML model training and deployment', - 'Set up and manage GPU clusters for training large models', - 'Build model serving infrastructure (HuggingFace Spaces, FastAPI, Docker)', - 'Implement monitoring and observability for model performance', - 'Optimize inference latency and throughput', - 'Create deployment templates for AWS, Azure, GCP', - ], - required: [ - "Bachelor's in Computer Science or related field", - '2–5 years experience in MLOps, DevOps, or infrastructure', - 'Strong experience with Docker, Kubernetes, and containerization', - 'Proficiency in Python and bash scripting', - 'Experience with ML frameworks (PyTorch, TensorFlow, ONNX)', - 'Cloud platform experience (AWS, GCP, or Azure)', - ], - preferred: [ - 'Experience with ML model serving (TorchServe, TensorFlow Serving, Triton)', - 'Knowledge of GPU optimization and CUDA', - 'Familiarity with HuggingFace ecosystem and model deployment', - 'Experience with monitoring tools (Prometheus, Grafana, DataDog)', - 'Infrastructure-as-Code experience (Terraform, Ansible)', - 'Built MLOps systems for research labs or open-source projects', - ], - }, - { - title: 'AI Infra Engineer', - experience: '2–5 years', - about: "Build large-scale training infrastructure and distributed systems for Bodhan AI's research. Work on multi-GPU training, data pipelines, and compute optimization.", - responsibilities: [ - 'Design distributed training systems for large language models', - 'Optimize training pipelines for efficiency (DeepSpeed, FSDP, Megatron)', - 'Build data processing infrastructure for trillion-token datasets', - 'Implement GPU utilization monitoring and cost optimization', - 'Create checkpointing and experiment tracking systems', - 'Support researchers with training infrastructure and debugging', - ], - required: [ - "Bachelor's or Master's in Computer Science or related field", - '2–5 years experience with distributed systems or ML infrastructure', - 'Strong understanding of parallel computing and GPU programming', - 'Proficiency in Python and C++/CUDA (optional but strong plus)', - 'Experience with PyTorch distributed training (DDP, FSDP)', - 'Knowledge of HPC systems and cluster management', - ], - preferred: [ - 'Experience training large models (7B+ parameters)', - 'Knowledge of DeepSpeed, Megatron-LM, or FSDP', - 'Contributions to PyTorch or other ML frameworks', - 'Understanding of model parallelism and pipeline parallelism', - 'Experience with Slurm, Ray, or distributed computing frameworks', - 'Published papers on ML systems or infrastructure', - ], - }, - { - title: 'API & Integration Engineer', - experience: '2–5 years', - about: "Build integrations between Bodhan AI models and popular frameworks/platforms. Create plugins for LiveKit, LangChain, LlamaIndex, and cloud marketplaces.", - responsibilities: [ - 'Develop LiveKit and other plugins for models', - 'Create LangChain/LlamaIndex integrations for Bodhan AI models', - 'Build API templates (FastAPI, Flask) for easy deployment', - 'Develop Docker images and deployment guides', - 'Create integrations for AWS/Azure/GCP marketplaces', - 'Write comprehensive documentation and examples', - ], - required: [ - "Bachelor's in Computer Science or related field", - '2–5 years experience with API development and integrations', - 'Strong Python programming skills', - 'Experience with REST APIs and SDK development', - 'Understanding of ML model serving and inference', - 'Familiarity with Docker and cloud platforms', - ], - preferred: [ - 'Experience with voice AI platforms (LiveKit, Vapi, Twilio, etc.)', - 'Knowledge of LangChain, LlamaIndex, or Haystack', - 'Built integrations for open-source projects', - 'Familiarity with WebRTC and real-time communication', - 'Experience with API documentation (OpenAPI/Swagger)', - 'Contributions to integration/plugin projects', - ], - }, - { - title: 'Frontend Engineer', - experience: '1–5 years', - about: "Build intuitive web interfaces for Bodhan AI's website, demos, tools, and community platforms. Create experiences for Indic LLM Arena, model demos, and developer resources.", - responsibilities: [ - 'Develop responsive web applications using React/Next.js', - 'Build interactive demos for translation, ASR, TTS models', - 'Create developer tools and documentation portals', - 'Implement real-time features (voice chat, streaming text)', - 'Optimize performance for Indian language text rendering', - 'Collaborate with designers and backend teams', - ], - required: [ - "Bachelor's in Computer Science or related field", - '1–5 years experience in frontend development', - 'Strong proficiency in JavaScript/TypeScript and React', - 'Experience with modern CSS frameworks (Tailwind, etc.)', - 'Understanding of responsive design and accessibility', - 'Familiarity with Git and modern development workflows and AI assisted coding platforms', - ], - preferred: [ - 'Experience with Next.js, Remix, or similar frameworks', - 'Knowledge of Web Audio API for voice applications', - 'Experience building AI/ML demos or tools', - 'Familiarity with Indian language rendering (fonts, Unicode)', - 'Contributions to open-source React projects', - 'Design sensibility and attention to detail', - ], - }, - { - title: 'Backend Engineer', - experience: '1–5 years', - about: "Build scalable backend systems for Bodhan AI's APIs, data pipelines, and web applications. Support community of 100K+ developers and production deployments.", - responsibilities: [ - 'Design and implement REST APIs for Bodhan AI models', - 'Build data ingestion and processing pipelines', - 'Create backend services for Indic LLM Arena and other applications', - 'Implement authentication, rate limiting, and API management', - 'Optimize database queries and caching strategies', - 'Write comprehensive tests and documentation', - ], - required: [ - "Bachelor's in Computer Science or related field", - '1–5 years experience in backend development', - 'Strong proficiency in Python (FastAPI/Flask) or Node.js', - 'Experience with SQL (PostgreSQL/MySQL) and NoSQL databases', - 'Understanding of RESTful API design and microservices', - 'Familiarity with Git, Docker, and cloud deployment and use of AI assisted coding platforms', - ], - preferred: [ - 'Experience building APIs for ML models', - 'Knowledge of async programming and task queues (Celery, Redis)', - 'Familiarity with GraphQL', - 'Experience with high-traffic applications (1M+ requests/day)', - 'Contributions to open-source Python projects', - 'Understanding of Indian language text processing', - ], - }, - { - title: 'Data Engineer', - experience: '2–5 years', - about: "Design, build, and maintain scalable data pipelines and infrastructure to power Bodhan AI's multilingual models and research. Work with massive datasets spanning 22 Indian languages.", - responsibilities: [ - 'Design, build, and maintain scalable data pipelines for large corpora of educational and conversational text data', - 'Ingest data from multiple sources (documents, APIs, structured and unstructured data) and prepare it for training, RAG, and evaluation workflows', - 'Integrate AI/ML models within data pipelines for data cleaning, normalization, deduplication, filtering, metadata enrichment, and tagging', - 'Ensure data quality, correctness, and consistency through validation checks and automated tests', - 'Implement data safety and compliance checks, including PII handling and policy-aligned filtering', - 'Manage data formats, storage layouts, and sharding strategies for efficient retrieval and scalability', - 'Curate and maintain training, evaluation, and test datasets for LLM and RAG systems', - 'Collaborate with ML, RAG, and QA teams to continuously improve data coverage and relevance', - ], - required: [ - "Bachelor's or Master's in Computer Science, Data Engineering, or related field", - '2–5 years experience in data engineering or related roles', - 'Strong proficiency in Python and SQL', - 'Experience with data pipeline tools (Apache Airflow, Spark, Kafka, or similar)', - 'Hands-on experience with cloud data services (AWS S3, BigQuery, Redshift, or similar)', - 'Understanding of data modeling, warehousing, and lake architectures', - ], - preferred: [ - 'Experience processing multilingual or Indian language text/audio data', - 'Knowledge of distributed computing frameworks (Spark, Dask, Ray)', - 'Familiarity with data versioning tools (DVC, LakeFS)', - 'Experience with streaming data systems and real-time pipelines', - 'Understanding of ML data requirements and feature engineering', - 'Contributions to open-source data engineering projects', - ], - }, +/* Roles parked with `hold: true` are hidden from both tabs and from search. */ +const liveJobs = jobPostings.filter((job) => !job.hold); + +/* An open role with a past closingDate counts as closed without anyone editing the + data — it drops out of Hiring, loses its Apply button, and appears under Closed. + The role stays open through the whole of its closing date, and the cutoff is the + visitor's local midnight (same convention as TendersPage). Evaluated per render, + so a tab left open across midnight updates on the next interaction or reload. */ +const isExpired = (job) => + !!job.closingDate && new Date(`${job.closingDate}T23:59:59`) < new Date(); + +const effectiveStatus = (job) => (job.status === 'active' && isExpired(job) ? 'closed' : job.status); + +const TABS = [ + { key: 'hiring', label: 'Hiring' }, + { key: 'closed', label: 'Closed' }, ]; -const JobCard = ({ job, index }) => { +/* Full searchable text per role: title + the whole JD. Built once. */ +const searchIndex = new Map( + liveJobs.map((job) => [ + job.id, + [ + job.title, + job.category, + job.experience, + job.location || DEFAULT_LOCATION, // index what the card actually shows + job.about, + ...job.responsibilities, + ...job.required, + ...job.preferred, + ] + .filter(Boolean) + .join(' ') + .toLowerCase(), + ]) +); + +const matchesQuery = (job, tokens) => { + if (tokens.length === 0) return true; + const haystack = searchIndex.get(job.id); + return tokens.every((token) => haystack.includes(token)); +}; + +const allOpen = () => Object.fromEntries(CATEGORY_ORDER.map((c) => [c, true])); +const allClosed = () => Object.fromEntries(CATEGORY_ORDER.map((c) => [c, false])); + +/* Wraps every occurrence of the active search tokens in . Tokens are regex- + escaped — role copy contains "C++" and "(Backend Engineer)" — and matched + longest-first so a longer token wins over a shorter one that prefixes it. */ +const Highlight = ({ text, tokens }) => { + if (!tokens.length || !text) return text; + const pattern = tokens + .slice() + .sort((a, b) => b.length - a.length) + .map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) + .join('|'); + const parts = String(text).split(new RegExp(`(${pattern})`, 'gi')); + return ( + <> + {parts.map((part, i) => + i % 2 === 1 ? ( + + {part} + + ) : ( + part + ) + )} + + ); +}; + +const JobCard = ({ job, index, tokens }) => { const [expanded, setExpanded] = useState(false); + const isOpenRole = effectiveStatus(job) === 'active'; return ( {/* Card Header — always visible */}
setExpanded(!expanded)} > -
-

- {job.title} +
+

+

-
+
- Chennai (Hybrid) - - - - {job.experience} + + {job.experience && ( + + + + + )} + {!isOpenRole && ( + + Closed + + )}
-

- {job.about} +

+

- e.stopPropagation()} - > - Apply Now - - + {isOpenRole && ( + e.stopPropagation()} + > + Apply Now + + + )} @@ -325,6 +150,7 @@ const JobCard = ({ job, index }) => { animate={{ height: expanded ? 'auto' : 0, opacity: expanded ? 1 : 0 }} transition={{ duration: 0.3, ease: 'easeInOut' }} className="overflow-hidden" + inert={!expanded} >
@@ -337,7 +163,7 @@ const JobCard = ({ job, index }) => { {job.responsibilities.map((item, i) => (
  • • - {item} +
  • ))} @@ -352,7 +178,7 @@ const JobCard = ({ job, index }) => { {job.required.map((item, i) => (
  • • - {item} +
  • ))} @@ -367,7 +193,7 @@ const JobCard = ({ job, index }) => { {job.preferred.map((item, i) => (
  • • - {item} +
  • ))} @@ -375,69 +201,304 @@ const JobCard = ({ job, index }) => {
    {/* Bottom Apply Button */} - + {isOpenRole ? ( + + ) : ( +
    +

    + This role is not accepting applications right now. +

    +
    + )}
    ); }; +const CategoryGroup = ({ category, jobs, isOpen, onToggle, tokens }) => ( +
    + {/* Group header — clickable */} + + + {/* Group body */} + +
    + {jobs.map((job, index) => ( + + ))} +
    +
    +
    +); + const CareersPage = () => { + const [activeTab, setActiveTab] = useState('hiring'); + const [query, setQuery] = useState(''); + const [openGroups, setOpenGroups] = useState(allClosed); + useEffect(() => { window.scrollTo(0, 0); }, []); + const tokens = useMemo( + () => query.trim().toLowerCase().split(/\s+/).filter(Boolean), + [query] + ); + const isSearching = tokens.length > 0; + + /* Roles in the active tab that match the current query, grouped by category. */ + const groups = useMemo(() => { + const visible = liveJobs.filter( + (job) => TAB_FOR_STATUS[effectiveStatus(job)] === activeTab && matchesQuery(job, tokens) + ); + return CATEGORY_ORDER.map((category) => ({ + category, + jobs: visible.filter((job) => job.category === category), + })).filter((group) => group.jobs.length > 0); + }, [activeTab, tokens]); + + const matchCount = groups.reduce((sum, group) => sum + group.jobs.length, 0); + const tabCounts = useMemo(() => { + const counts = { hiring: 0, closed: 0 }; + liveJobs.forEach((job) => { + if (matchesQuery(job, tokens)) counts[TAB_FOR_STATUS[effectiveStatus(job)]] += 1; + }); + return counts; + }, [tokens]); + + /* Every group starts collapsed, on both tabs. A running search force-expands + them so matches are never hidden behind a fold; clearing it re-collapses. */ + useEffect(() => { + setOpenGroups(isSearching ? allOpen() : allClosed()); + }, [isSearching]); + + /* Switching tabs returns groups to collapsed — unless a search is running, in + which case the new tab's matches should be visible straight away. */ + const selectTab = (key) => { + setActiveTab(key); + setOpenGroups(isSearching ? allOpen() : allClosed()); + }; + + const everyGroupOpen = groups.length > 0 && groups.every((g) => openGroups[g.category]); + return ( -
    +
    - {/* Header */} -
    -
    - - Join{' '} - Bodhan AI - - - Help us build AI that transforms how India learns, teaches, and grows. - +
    + {/* Header */} +
    +
    + + Join{' '} + Bodhan AI + + + Help us build AI that transforms how India learns, teaches, and grows. + + + + Most positions are based in Chennai (Hybrid) + +
    +
    + + {/* Tabs */} +
    - - All positions are based in Chennai (Hybrid) + {TABS.map((tab) => ( + + ))}
    -
    - {/* Job Listings */} -
    - {jobPostings.map((job, index) => ( - - ))} + {/* Search + expand/collapse — scoped to the active tab */} +
    +
    +
    + + setQuery(e.target.value)} + placeholder={`Search ${activeTab === 'hiring' ? 'open' : 'closed'} roles by title or description…`} + aria-label={`Search ${activeTab} roles`} + className="w-full bg-white border border-gray-200 rounded-xl pl-10 pr-10 py-2.5 text-sm text-[#1A1A1A] placeholder:text-gray-400 focus:outline-none focus:border-[var(--text-orange-500)] focus:ring-2 focus:ring-orange-100 transition-colors [&::-webkit-search-cancel-button]:hidden" + /> + {query && ( + + )} +
    + {groups.length > 0 && ( + + )} +
    + {isSearching && ( +

    + {matchCount} {matchCount === 1 ? 'role' : 'roles'} in{' '} + + {activeTab === 'hiring' ? 'Hiring' : 'Closed'} + {' '} + match “{query.trim()}” + {tabCounts[activeTab === 'hiring' ? 'closed' : 'hiring'] > 0 && ( + <> + {' '}·{' '} + + + )} +

    + )} +
    + + {/* Grouped listings */} +
    + + {groups.length > 0 ? ( + + {groups.map((group) => ( + + setOpenGroups((prev) => ({ + ...prev, + [group.category]: !prev[group.category], + })) + } + /> + ))} + + ) : ( + +
    + +
    +

    + {isSearching + ? `No ${activeTab === 'hiring' ? 'open' : 'closed'} roles match “${query.trim()}”.` + : `No ${activeTab === 'hiring' ? 'open' : 'closed'} roles at the moment.`} +

    +

    + {isSearching + ? 'Try a different keyword, or check the other tab.' + : 'Check back soon for new opportunities.'} +

    +
    + )} +
    +