From 79a553cedd8fdee2518124ffe854111912d56b7e Mon Sep 17 00:00:00 2001 From: Aditya948351 Date: Thu, 18 Jun 2026 21:59:41 +0530 Subject: [PATCH 1/2] test: trigger CI and Firebase deploy again From f438144b645b88ea1a9bd4838ddd32e84fcac0ff Mon Sep 17 00:00:00 2001 From: Aditya948351 <157286761+Aditya948351@users.noreply.github.com> Date: Thu, 18 Jun 2026 16:29:31 +0000 Subject: [PATCH 2/2] style: auto-format with Prettier --- backend/src/config/chatbotConfig.js | 151 +- backend/src/scripts/testChatbot.js | 170 ++- backend/src/services/openRouterService.js | 10 +- src/app/profile/[username]/page.tsx | 5 +- src/app/roadmaps/[id]/page.tsx | 46 +- src/app/signup/page.tsx | 114 +- src/components/features/ComingSoonRoadmap.tsx | 43 +- .../features/SkillTreeVisualizer.tsx | 96 +- src/components/gamification/Leaderboard.tsx | 2 +- src/components/home/Hero.tsx | 1 - src/components/home/ResourcesTabs.tsx | 1349 +++++++++-------- src/components/layout/Navbar.module.css | 177 +-- src/components/layout/Navbar.tsx | 6 +- src/components/layout/RouteAwareChrome.tsx | 7 +- src/components/layout/ShortcutLegend.tsx | 46 +- src/components/profile/DevCard.tsx | 36 +- src/components/profile/GithubStats.tsx | 388 +++-- src/context/AuthContext.tsx | 8 +- src/hooks/useKeyboardShortcuts.ts | 8 +- 19 files changed, 1535 insertions(+), 1128 deletions(-) diff --git a/backend/src/config/chatbotConfig.js b/backend/src/config/chatbotConfig.js index 490c6d08..0848f859 100644 --- a/backend/src/config/chatbotConfig.js +++ b/backend/src/config/chatbotConfig.js @@ -5,117 +5,138 @@ const KNOWLEDGE_BASE = { platform: { - name: "DevPath", - tagline: "Empowering Devs to master their craft through structured learning, real-world projects, and a supportive community.", - description: "DevPath India is an ecosystem and community platform designed to foster developer growth, collaboration, event management, resource sharing, and professional connections.", + name: 'DevPath', + tagline: + 'Empowering Devs to master their craft through structured learning, real-world projects, and a supportive community.', + description: + 'DevPath India is an ecosystem and community platform designed to foster developer growth, collaboration, event management, resource sharing, and professional connections.', techStack: { - frontend: "Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS, Framer Motion, GSAP", - backend: "Node.js, Express, Firebase (Authentication, Firestore Database, Hosting), OpenRouter API", - hosting: "Vercel", + frontend: + 'Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS, Framer Motion, GSAP', + backend: + 'Node.js, Express, Firebase (Authentication, Firestore Database, Hosting), OpenRouter API', + hosting: 'Vercel', }, - brandProtection: "DevPath India Source-Available License. Users can clone, run locally, modify, and submit PRs. Commercial use, hosting public clones, competing services, or redistributing under the DevPath India brand is prohibited. The DevPath India name, logo, branding assets, and visual identity are protected.", - coreMaintainer: "Aditya948351 (Core Maintainer & Lead Developer)", + brandProtection: + 'DevPath India Source-Available License. Users can clone, run locally, modify, and submit PRs. Commercial use, hosting public clones, competing services, or redistributing under the DevPath India brand is prohibited. The DevPath India name, logo, branding assets, and visual identity are protected.', + coreMaintainer: 'Aditya948351 (Core Maintainer & Lead Developer)', }, features: { - communityHub: "Connect with developers, mentors, and contributors within the DevPath India community.", - eventManagement: "Discover hackathons, workshops, and community events. Highlights include the annual flagship hackathon 'HackFiesta'.", - resourceLibrary: "Access curated roadmaps, guides, and tutorials for MERN/React stack, Python for AI, profile setup, and developer mindset.", - wikiKnowledgeBase: "Explore guides, documentation, platform tutorials, and community articles.", - userProfiles: "Showcase skills, achievements, linked GitHub repositories, experience points (XP), and badges.", - openSourceDashboard: "Contribute to projects and grow through real-world experience. Main dashboard: /opensource", - xpSystem: "Experience Points (XP) gamify the learning journey. Earn XP through daily logins, completing projects, and open source contributions (merged PRs). Earned XP counts towards the leaderboard ranking.", + communityHub: + 'Connect with developers, mentors, and contributors within the DevPath India community.', + eventManagement: + "Discover hackathons, workshops, and community events. Highlights include the annual flagship hackathon 'HackFiesta'.", + resourceLibrary: + 'Access curated roadmaps, guides, and tutorials for MERN/React stack, Python for AI, profile setup, and developer mindset.', + wikiKnowledgeBase: + 'Explore guides, documentation, platform tutorials, and community articles.', + userProfiles: + 'Showcase skills, achievements, linked GitHub repositories, experience points (XP), and badges.', + openSourceDashboard: + 'Contribute to projects and grow through real-world experience. Main dashboard: /opensource', + xpSystem: + 'Experience Points (XP) gamify the learning journey. Earn XP through daily logins, completing projects, and open source contributions (merged PRs). Earned XP counts towards the leaderboard ranking.', }, roles: { cityLeads: { - title: "City Leads", - description: "Local community ambassadors bridging DevPath and regional developers.", + title: 'City Leads', + description: + 'Local community ambassadors bridging DevPath and regional developers.', responsibilities: [ - "Organizing local meetups, workshops, and hackathons.", - "Guiding and mentoring local members and learners.", - "Representing the DevPath brand at local events and colleges.", - "Gathering community feedback to share with the core team.", + 'Organizing local meetups, workshops, and hackathons.', + 'Guiding and mentoring local members and learners.', + 'Representing the DevPath brand at local events and colleges.', + 'Gathering community feedback to share with the core team.', ], - selection: "Selected quarterly from active contributors who exhibit strong leadership qualities and passion.", + selection: + 'Selected quarterly from active contributors who exhibit strong leadership qualities and passion.', }, technicalHeads: { - title: "Technical Heads", - description: "Subject matter experts ensuring the quality of technical content and projects.", + title: 'Technical Heads', + description: + 'Subject matter experts ensuring the quality of technical content and projects.', responsibilities: [ - "Curriculum Design: Creating and updating Learning Paths (e.g., MERN stack, Python for AI) to reflect industry trends.", - "Project Review: Reviewing code and giving constructive feedback on project submissions.", - "Technical Workshops: Leading deep-dive sessions on advanced frameworks, tools, and practices.", + 'Curriculum Design: Creating and updating Learning Paths (e.g., MERN stack, Python for AI) to reflect industry trends.', + 'Project Review: Reviewing code and giving constructive feedback on project submissions.', + 'Technical Workshops: Leading deep-dive sessions on advanced frameworks, tools, and practices.', "Open Source Maintainers: Managing DevPath's GitHub repositories, reviewing Pull Requests, and guiding contributors.", ], }, }, repositories: [ { - name: "DevPath Website", - description: "Official Community Website", - longDescription: "The official website for the DevPath community, built with Next.js, Tailwind CSS, and Firebase.", - language: "TypeScript", - status: "Public/Active", - url: "https://github.com/devpathindcommunity-india/DevPath-Web", + name: 'DevPath Website', + description: 'Official Community Website', + longDescription: + 'The official website for the DevPath community, built with Next.js, Tailwind CSS, and Firebase.', + language: 'TypeScript', + status: 'Public/Active', + url: 'https://github.com/devpathindcommunity-india/DevPath-Web', }, { - name: "DevPath CLI", - description: "Command Line Tool", - longDescription: "A powerful CLI tool to help developers navigate learning paths and access resources from the terminal.", - language: "JavaScript", - status: "Coming Soon (Private repository)", + name: 'DevPath CLI', + description: 'Command Line Tool', + longDescription: + 'A powerful CLI tool to help developers navigate learning paths and access resources from the terminal.', + language: 'JavaScript', + status: 'Coming Soon (Private repository)', url: null, }, { - name: "Learning Resources", - description: "Curated Lists", - longDescription: "A comprehensive collection of free learning resources, roadmaps, and guides for developers of all levels.", - language: "Markdown", - status: "Coming Soon (Private repository)", + name: 'Learning Resources', + description: 'Curated Lists', + longDescription: + 'A comprehensive collection of free learning resources, roadmaps, and guides for developers of all levels.', + language: 'Markdown', + status: 'Coming Soon (Private repository)', url: null, }, ], supportAndContacts: { - email: "devpathind.community@gmail.com", - complaintsForm: "https://forms.gle/ptMuZVQU1nkpnbCz9", - githubOrg: "https://github.com/devpathindcommunity-india", - whatsappCommunity: "https://chat.whatsapp.com/D2PRfQy4HYgC4XURhY2X8C", - instagram: "https://www.instagram.com/devpath_community/", - linkedin: "https://www.linkedin.com/company/devpath-community/", + email: 'devpathind.community@gmail.com', + complaintsForm: 'https://forms.gle/ptMuZVQU1nkpnbCz9', + githubOrg: 'https://github.com/devpathindcommunity-india', + whatsappCommunity: 'https://chat.whatsapp.com/D2PRfQy4HYgC4XURhY2X8C', + instagram: 'https://www.instagram.com/devpath_community/', + linkedin: 'https://www.linkedin.com/company/devpath-community/', }, events: { hackFiesta: { - name: "HackFiesta", - description: "DevPath's flagship annual 48-hour hackathon bringing developers together to solve real-world problems.", + name: 'HackFiesta', + description: + "DevPath's flagship annual 48-hour hackathon bringing developers together to solve real-world problems.", details: [ - "48-hour intense coding, design, and pitch sprint.", - "Access to professional industry mentors.", - "Cash prizes, tech gadgets, and exclusive DevPath swag.", - "Networking opportunities with recruiters and potential co-founders.", + '48-hour intense coding, design, and pitch sprint.', + 'Access to professional industry mentors.', + 'Cash prizes, tech gadgets, and exclusive DevPath swag.', + 'Networking opportunities with recruiters and potential co-founders.', ], }, }, }; const CONSTRAINTS = [ - "Strictly restrict responses to the DevPath platform, its features, community, events, open-source work, and guides.", + 'Strictly restrict responses to the DevPath platform, its features, community, events, open-source work, and guides.', "Never answer general coding or programming queries (e.g. 'write a quicksort in JavaScript') unless they are directly contextually related to DevPath's own codebase, guides, or roadmaps.", - "Never answer general queries unrelated to DevPath (e.g. food recipes, news, unrelated technologies, external events).", + 'Never answer general queries unrelated to DevPath (e.g. food recipes, news, unrelated technologies, external events).', "If the user asks an irrelevant or out-of-scope question, politely decline using a standardized fallback explanation about the chatbot's scope.", - "Do not make up or hallucinate any contacts, links, features, repositories, or details. Only provide information that is explicitly defined in the DevPath knowledge base.", - "If a user asks about something on DevPath that is not mentioned in the knowledge base, politely state that you do not have that information and suggest contacting the community leads via the official email or WhatsApp group.", + 'Do not make up or hallucinate any contacts, links, features, repositories, or details. Only provide information that is explicitly defined in the DevPath knowledge base.', + 'If a user asks about something on DevPath that is not mentioned in the knowledge base, politely state that you do not have that information and suggest contacting the community leads via the official email or WhatsApp group.', ]; const TONE_AND_GUIDELINES = [ "Identify yourself as the 'DevPath Assistant' (or 'DevPath Learning Assistant').", - "Maintain a polite, helpful, professional, encouraging, and developer-friendly tone.", - "Keep responses concise and well-structured using markdown.", - "Provide clear, actionable guidance.", - "When providing links, only use the official URLs defined in the knowledge base.", + 'Maintain a polite, helpful, professional, encouraging, and developer-friendly tone.', + 'Keep responses concise and well-structured using markdown.', + 'Provide clear, actionable guidance.', + 'When providing links, only use the official URLs defined in the knowledge base.', ]; const FALLBACK_RESPONSES = { - outOfScope: "I'm sorry, I can only help you with questions related to the DevPath platform, its learning paths, community events, and open-source contributions. For other technical or general topics, feel free to ask in our WhatsApp Community or seek external resources!", - unknownFeature: "I don't have information about that specific feature or detail. Please feel free to check our official Wiki, ask in the WhatsApp Community, or contact us at devpathind.community@gmail.com.", + outOfScope: + "I'm sorry, I can only help you with questions related to the DevPath platform, its learning paths, community events, and open-source contributions. For other technical or general topics, feel free to ask in our WhatsApp Community or seek external resources!", + unknownFeature: + "I don't have information about that specific feature or detail. Please feel free to check our official Wiki, ask in the WhatsApp Community, or contact us at devpathind.community@gmail.com.", }; module.exports = { diff --git a/backend/src/scripts/testChatbot.js b/backend/src/scripts/testChatbot.js index bd3253ce..10dccdda 100644 --- a/backend/src/scripts/testChatbot.js +++ b/backend/src/scripts/testChatbot.js @@ -8,9 +8,9 @@ const { CONSTRAINTS, TONE_AND_GUIDELINES, FALLBACK_RESPONSES, -} = require("../config/chatbotConfig"); +} = require('../config/chatbotConfig'); -const openRouterService = require("../services/openRouterService"); +const openRouterService = require('../services/openRouterService'); // Simple assertion helper const assert = (condition, message) => { @@ -20,71 +20,147 @@ const assert = (condition, message) => { } }; -console.log("--------------------------------------------------"); -console.log("🏃 Running Chatbot Configuration & Prompt Tests..."); -console.log("--------------------------------------------------"); +console.log('--------------------------------------------------'); +console.log('🏃 Running Chatbot Configuration & Prompt Tests...'); +console.log('--------------------------------------------------'); // 1. Verify structured knowledge base -console.log("1. Verifying structured knowledge base properties..."); -assert(KNOWLEDGE_BASE.platform.name === "DevPath", "Platform name should be DevPath"); -assert(typeof KNOWLEDGE_BASE.platform.tagline === "string", "Tagline must be a string"); -assert(Array.isArray(KNOWLEDGE_BASE.roles.cityLeads.responsibilities), "City Leads responsibilities must be an array"); -assert(KNOWLEDGE_BASE.roles.cityLeads.responsibilities.length > 0, "City Leads responsibilities must not be empty"); -assert(KNOWLEDGE_BASE.supportAndContacts.email === "devpathind.community@gmail.com", "Support email should be correct"); -assert(KNOWLEDGE_BASE.supportAndContacts.whatsappCommunity.includes("chat.whatsapp.com"), "WhatsApp link should be correct"); -console.log("✅ Knowledge base properties verified."); +console.log('1. Verifying structured knowledge base properties...'); +assert( + KNOWLEDGE_BASE.platform.name === 'DevPath', + 'Platform name should be DevPath' +); +assert( + typeof KNOWLEDGE_BASE.platform.tagline === 'string', + 'Tagline must be a string' +); +assert( + Array.isArray(KNOWLEDGE_BASE.roles.cityLeads.responsibilities), + 'City Leads responsibilities must be an array' +); +assert( + KNOWLEDGE_BASE.roles.cityLeads.responsibilities.length > 0, + 'City Leads responsibilities must not be empty' +); +assert( + KNOWLEDGE_BASE.supportAndContacts.email === 'devpathind.community@gmail.com', + 'Support email should be correct' +); +assert( + KNOWLEDGE_BASE.supportAndContacts.whatsappCommunity.includes( + 'chat.whatsapp.com' + ), + 'WhatsApp link should be correct' +); +console.log('✅ Knowledge base properties verified.'); // 2. Verify constraints -console.log("2. Verifying chatbot constraints..."); -assert(CONSTRAINTS.length >= 5, "Should have at least 5 constraints"); -assert(CONSTRAINTS.some(c => c.toLowerCase().includes("restrict")), "Constraints should restrict topic scope"); -assert(CONSTRAINTS.some(c => c.toLowerCase().includes("hallucinate") || c.toLowerCase().includes("make up")), "Constraints should prevent hallucinations"); -console.log("✅ Constraints verified."); +console.log('2. Verifying chatbot constraints...'); +assert(CONSTRAINTS.length >= 5, 'Should have at least 5 constraints'); +assert( + CONSTRAINTS.some((c) => c.toLowerCase().includes('restrict')), + 'Constraints should restrict topic scope' +); +assert( + CONSTRAINTS.some( + (c) => + c.toLowerCase().includes('hallucinate') || + c.toLowerCase().includes('make up') + ), + 'Constraints should prevent hallucinations' +); +console.log('✅ Constraints verified.'); // 3. Verify tone guidelines -console.log("3. Verifying tone guidelines..."); -assert(TONE_AND_GUIDELINES.length >= 3, "Should have at least 3 tone guidelines"); -assert(TONE_AND_GUIDELINES.some(g => g.toLowerCase().includes("polite") || g.toLowerCase().includes("concise")), "Tone guidelines should enforce standard behavior"); -console.log("✅ Tone guidelines verified."); +console.log('3. Verifying tone guidelines...'); +assert( + TONE_AND_GUIDELINES.length >= 3, + 'Should have at least 3 tone guidelines' +); +assert( + TONE_AND_GUIDELINES.some( + (g) => + g.toLowerCase().includes('polite') || g.toLowerCase().includes('concise') + ), + 'Tone guidelines should enforce standard behavior' +); +console.log('✅ Tone guidelines verified.'); // 4. Verify fallback responses -console.log("4. Verifying fallback responses..."); -assert(typeof FALLBACK_RESPONSES.outOfScope === "string", "Out of scope fallback must be defined"); -assert(typeof FALLBACK_RESPONSES.unknownFeature === "string", "Unknown feature fallback must be defined"); -console.log("✅ Fallback responses verified."); +console.log('4. Verifying fallback responses...'); +assert( + typeof FALLBACK_RESPONSES.outOfScope === 'string', + 'Out of scope fallback must be defined' +); +assert( + typeof FALLBACK_RESPONSES.unknownFeature === 'string', + 'Unknown feature fallback must be defined' +); +console.log('✅ Fallback responses verified.'); // 5. Verify buildMessages constructs system prompt correctly -console.log("5. Verifying buildMessages integration..."); +console.log('5. Verifying buildMessages integration...'); // Use createStreamingChatCompletionConfig to construct stream config and inspect messages -const dummyMessage = "What is DevPath?"; +const dummyMessage = 'What is DevPath?'; const dummyHistory = [ - { role: "user", content: "Hi" }, - { role: "assistant", content: "Hello! I am DevPath Assistant." } + { role: 'user', content: 'Hi' }, + { role: 'assistant', content: 'Hello! I am DevPath Assistant.' }, ]; const config = openRouterService.createStreamingChatCompletionConfig({ message: dummyMessage, - history: dummyHistory + history: dummyHistory, }); const messages = config.body.messages; -assert(Array.isArray(messages), "Messages should be an array"); -assert(messages.length === 4, `Messages should have length 4 (system, user, assistant, user). Got: ${messages.length}`); -assert(messages[0].role === "system", "First message must be system message"); -assert(messages[0].content.includes("DevPath Assistant"), "System prompt should identify assistant"); -assert(messages[0].content.includes("STRUCTURED KNOWLEDGE BASE"), "System prompt should include structured knowledge base section"); -assert(messages[0].content.includes("CONSTRAINTS"), "System prompt should include constraints section"); -assert(messages[0].content.includes("TONE & GUIDELINES"), "System prompt should include tone/guidelines section"); -assert(messages[0].content.includes("devpathind.community@gmail.com"), "System prompt should contain email from knowledge base"); -assert(messages[0].content.includes("HackFiesta"), "System prompt should contain event HackFiesta info"); +assert(Array.isArray(messages), 'Messages should be an array'); +assert( + messages.length === 4, + `Messages should have length 4 (system, user, assistant, user). Got: ${messages.length}` +); +assert(messages[0].role === 'system', 'First message must be system message'); +assert( + messages[0].content.includes('DevPath Assistant'), + 'System prompt should identify assistant' +); +assert( + messages[0].content.includes('STRUCTURED KNOWLEDGE BASE'), + 'System prompt should include structured knowledge base section' +); +assert( + messages[0].content.includes('CONSTRAINTS'), + 'System prompt should include constraints section' +); +assert( + messages[0].content.includes('TONE & GUIDELINES'), + 'System prompt should include tone/guidelines section' +); +assert( + messages[0].content.includes('devpathind.community@gmail.com'), + 'System prompt should contain email from knowledge base' +); +assert( + messages[0].content.includes('HackFiesta'), + 'System prompt should contain event HackFiesta info' +); -assert(messages[1].role === "user" && messages[1].content === "Hi", "History messages preserved correctly"); -assert(messages[2].role === "assistant" && messages[2].content === "Hello! I am DevPath Assistant.", "History messages preserved correctly"); -assert(messages[3].role === "user" && messages[3].content === dummyMessage, "Latest user message appended correctly"); +assert( + messages[1].role === 'user' && messages[1].content === 'Hi', + 'History messages preserved correctly' +); +assert( + messages[2].role === 'assistant' && + messages[2].content === 'Hello! I am DevPath Assistant.', + 'History messages preserved correctly' +); +assert( + messages[3].role === 'user' && messages[3].content === dummyMessage, + 'Latest user message appended correctly' +); -console.log("✅ buildMessages integration verified."); +console.log('✅ buildMessages integration verified.'); -console.log("\n--------------------------------------------------"); -console.log("🎉 All chatbot configuration & prompt tests passed successfully!"); -console.log("--------------------------------------------------"); +console.log('\n--------------------------------------------------'); +console.log('🎉 All chatbot configuration & prompt tests passed successfully!'); +console.log('--------------------------------------------------'); diff --git a/backend/src/services/openRouterService.js b/backend/src/services/openRouterService.js index 3adac194..f5aca47d 100644 --- a/backend/src/services/openRouterService.js +++ b/backend/src/services/openRouterService.js @@ -1,10 +1,10 @@ -const AppError = require("../utils/AppError"); +const AppError = require('../utils/AppError'); const { KNOWLEDGE_BASE, CONSTRAINTS, TONE_AND_GUIDELINES, FALLBACK_RESPONSES, -} = require("../config/chatbotConfig"); +} = require('../config/chatbotConfig'); const OPENROUTER_URL = 'https://openrouter.ai/api/v1/chat/completions'; const DEFAULT_PRIMARY_MODEL = 'openai/gpt-oss-120b:free'; @@ -31,10 +31,10 @@ const getSystemPrompt = () => { ${JSON.stringify(KNOWLEDGE_BASE, null, 2)} # CONSTRAINTS: -${CONSTRAINTS.map((c, idx) => `${idx + 1}. ${c}`).join("\n")} +${CONSTRAINTS.map((c, idx) => `${idx + 1}. ${c}`).join('\n')} # TONE & GUIDELINES: -${TONE_AND_GUIDELINES.map((g, idx) => `${idx + 1}. ${g}`).join("\n")} +${TONE_AND_GUIDELINES.map((g, idx) => `${idx + 1}. ${g}`).join('\n')} # FALLBACK RESPONSES (USE EXACTLY OR ADAPT GRACEFULLY WHEN A QUERY IS OUT-OF-SCOPE OR UNKNOWN): - Out of scope fallback: "${FALLBACK_RESPONSES.outOfScope}" @@ -45,7 +45,7 @@ Important: If the user query is not related to the DevPath platform, its feature const buildMessages = (history, message) => { const systemMessage = { - role: "system", + role: 'system', content: getSystemPrompt(), }; diff --git a/src/app/profile/[username]/page.tsx b/src/app/profile/[username]/page.tsx index 7d6714d0..daf56fea 100644 --- a/src/app/profile/[username]/page.tsx +++ b/src/app/profile/[username]/page.tsx @@ -15,10 +15,7 @@ interface Props { } export async function generateStaticParams() { - return [ - { username: 'dummy' }, - { username: 'kew7p1pbj7WoX66uGH2ZMcg79RB3' } - ]; + return [{ username: 'dummy' }, { username: 'kew7p1pbj7WoX66uGH2ZMcg79RB3' }]; } export const dynamicParams = false; diff --git a/src/app/roadmaps/[id]/page.tsx b/src/app/roadmaps/[id]/page.tsx index 0eff0611..3ae97d46 100644 --- a/src/app/roadmaps/[id]/page.tsx +++ b/src/app/roadmaps/[id]/page.tsx @@ -23,39 +23,45 @@ interface RoadmapConfig { const ROADMAPS_CONFIG: Record = { frontend: { title: 'Frontend Developer Roadmap', - description: 'Master modern frontend development with our curated step-by-step Frontend developer roadmap. Learn HTML/CSS, JavaScript, React, and Next.js.', + description: + 'Master modern frontend development with our curated step-by-step Frontend developer roadmap. Learn HTML/CSS, JavaScript, React, and Next.js.', techDetails: 'HTML/CSS, JavaScript, React, Next.js', isAvailable: true, visualizerPath: 'Frontend', }, backend: { title: 'Backend Developer Roadmap', - description: 'Learn backend engineering with our curated backend roadmap. Master databases, Node.js, and API development.', + description: + 'Learn backend engineering with our curated backend roadmap. Master databases, Node.js, and API development.', techDetails: 'Databases, Node.js, API design', isAvailable: true, visualizerPath: 'Backend', }, devops: { title: 'DevOps Mastery Roadmap', - description: 'DevOps learning path: Docker, Kubernetes, CI/CD, and AWS infrastructure.', + description: + 'DevOps learning path: Docker, Kubernetes, CI/CD, and AWS infrastructure.', techDetails: 'Docker & Kubernetes, CI/CD Pipelines, AWS Infrastructure', isAvailable: false, }, 'python-ai': { title: 'Python for AI Roadmap', - description: 'Learn AI and machine learning: PyTorch, Neural Networks, and LLM Integration.', + description: + 'Learn AI and machine learning: PyTorch, Neural Networks, and LLM Integration.', techDetails: 'PyTorch Fundamentals, Neural Networks, LLM Integration', isAvailable: false, }, 'full-stack-react': { title: 'Full Stack React Roadmap', - description: 'Master Next.js App Router, Server Actions, PostgreSQL, and Prisma.', + description: + 'Master Next.js App Router, Server Actions, PostgreSQL, and Prisma.', techDetails: 'Next.js App Router, Server Actions, PostgreSQL & Prisma', isAvailable: false, }, 'web3-development': { title: 'Web3 Development Roadmap', - description: 'Step into Web3: Solidity Smart Contracts, Ethers.js, and DApp Architecture.', + description: + 'Step into Web3: Solidity Smart Contracts, Ethers.js, and DApp Architecture.', techDetails: 'Solidity Smart Contracts, Ethers.js, DApp Architecture', isAvailable: false, }, @@ -114,8 +120,12 @@ export default async function RoadmapPage({ params }: Props) { if (!config) { return (
-

Roadmap Not Found

-

The requested roadmap does not exist.

+

+ Roadmap Not Found +

+

+ The requested roadmap does not exist. +

Return to Learning Paths @@ -124,7 +134,12 @@ export default async function RoadmapPage({ params }: Props) { } if (!config.isAvailable) { - return ; + return ( + + ); } return ( @@ -135,11 +150,18 @@ export default async function RoadmapPage({ params }: Props) { href="/paths" className="inline-flex items-center gap-2 text-sm text-slate-400 hover:text-white transition-colors group w-fit" > - + Back to Paths -

{config.title}

-

{config.description}

+

+ {config.title} +

+

+ {config.description} +

diff --git a/src/app/signup/page.tsx b/src/app/signup/page.tsx index 1deadd69..79d0eeca 100644 --- a/src/app/signup/page.tsx +++ b/src/app/signup/page.tsx @@ -1,9 +1,9 @@ -"use client"; +'use client'; -import { useState, useEffect } from "react"; -import { useRouter } from "next/navigation"; -import { useAuth } from "@/context/AuthContext"; -import { motion, AnimatePresence } from "framer-motion"; +import { useState, useEffect } from 'react'; +import { useRouter } from 'next/navigation'; +import { useAuth } from '@/context/AuthContext'; +import { motion, AnimatePresence } from 'framer-motion'; import { User, Mail, @@ -19,33 +19,33 @@ import { Sparkles, ShieldCheck, CheckCircle, -} from "lucide-react"; -import Link from "next/link"; -import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth"; -import { doc, setDoc, getDoc, serverTimestamp } from "firebase/firestore"; -import { auth, db } from "@/lib/firebase"; -import { sanitizeSocialLinks } from "@/lib/safe-social-url"; +} from 'lucide-react'; +import Link from 'next/link'; +import { createUserWithEmailAndPassword, updateProfile } from 'firebase/auth'; +import { doc, setDoc, getDoc, serverTimestamp } from 'firebase/firestore'; +import { auth, db } from '@/lib/firebase'; +import { sanitizeSocialLinks } from '@/lib/safe-social-url'; export default function SignupPage() { const [currentStep, setCurrentStep] = useState(1); const totalSteps = 5; // Form States - const [name, setName] = useState(""); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const [mobile, setMobile] = useState(""); - const [countryCode, setCountryCode] = useState("+91"); - const [state, setState] = useState(""); - const [city, setCity] = useState(""); - const [district, setDistrict] = useState(""); - const [linkedin, setLinkedin] = useState(""); - const [github, setGithub] = useState(""); - const [instagram, setInstagram] = useState(""); - const [adminKey, setAdminKey] = useState(""); + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [mobile, setMobile] = useState(''); + const [countryCode, setCountryCode] = useState('+91'); + const [state, setState] = useState(''); + const [city, setCity] = useState(''); + const [district, setDistrict] = useState(''); + const [linkedin, setLinkedin] = useState(''); + const [github, setGithub] = useState(''); + const [instagram, setInstagram] = useState(''); + const [adminKey, setAdminKey] = useState(''); const [isAdminSignup, setIsAdminSignup] = useState(false); - const [error, setError] = useState(""); + const [error, setError] = useState(''); const [loading, setLoading] = useState(false); const router = useRouter(); const { user, isLoading: authLoading } = useAuth(); @@ -60,7 +60,7 @@ export default function SignupPage() { useEffect(() => { if (user) { - router.push("/profile"); + router.push('/profile'); } }, [user, router]); @@ -68,26 +68,26 @@ export default function SignupPage() { // Step Validation const validateStep = (step: number): boolean => { - setError(""); + setError(''); switch (step) { case 1: if (!name.trim()) { - setError("Full name is required."); + setError('Full name is required.'); return false; } if (!email.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { - setError("Please enter a valid email address."); + setError('Please enter a valid email address.'); return false; } if (!/^\d{10}$/.test(mobile)) { - setError("Please enter a valid 10-digit mobile number."); + setError('Please enter a valid 10-digit mobile number.'); return false; } return true; case 2: if (!state.trim() || !city.trim() || !district.trim()) { - setError("Please fill in all location fields."); + setError('Please fill in all location fields.'); return false; } return true; @@ -95,11 +95,11 @@ export default function SignupPage() { return true; // Social links optional case 4: if (!password || password.length < 6) { - setError("Password must be at least 6 characters long."); + setError('Password must be at least 6 characters long.'); return false; } if (isAdminSignup && !adminKey.trim()) { - setError("Admin key is required for admin registration."); + setError('Admin key is required for admin registration.'); return false; } return true; @@ -117,31 +117,31 @@ export default function SignupPage() { }; const goToPrevious = () => { - setError(""); + setError(''); setCurrentStep((prev) => Math.max(prev - 1, 1)); }; const handleSignup = async () => { - setError(""); + setError(''); setLoading(true); try { if (isAdminSignup) { - const keyDoc = await getDoc(doc(db, "admin_keys", "config")); + const keyDoc = await getDoc(doc(db, 'admin_keys', 'config')); if (!keyDoc.exists()) { - throw new Error("System Configuration Error: Admin Key not found."); + throw new Error('System Configuration Error: Admin Key not found.'); } const currentAdminKey = keyDoc.data().value; if (adminKey !== currentAdminKey) { - throw new Error("Invalid Admin Key. Please contact the Super Admin."); + throw new Error('Invalid Admin Key. Please contact the Super Admin.'); } } const userCredential = await createUserWithEmailAndPassword( auth, email, - password, + password ); const firebaseUser = userCredential.user; @@ -154,7 +154,7 @@ export default function SignupPage() { if (isAdminSignup) { await setDoc( - doc(db, "admins", email), + doc(db, 'admins', email), { uid: firebaseUser.uid, name, @@ -164,10 +164,10 @@ export default function SignupPage() { district, ...safeSocialLinks, }, - { merge: true }, + { merge: true } ); } else { - await setDoc(doc(db, "members", firebaseUser.uid), { + await setDoc(doc(db, 'members', firebaseUser.uid), { uid: firebaseUser.uid, name, email, @@ -176,7 +176,7 @@ export default function SignupPage() { city, district, ...safeSocialLinks, - role: "member", + role: 'member', createdAt: serverTimestamp(), points: 0, rank: 0, @@ -188,7 +188,7 @@ export default function SignupPage() { setCurrentStep(6); // Success screen } catch (err: any) { console.error(err); - setError(err.message || "Failed to create account."); + setError(err.message || 'Failed to create account.'); } finally { setLoading(false); } @@ -202,10 +202,10 @@ export default function SignupPage() { key={index} className={`h-2.5 w-2.5 rounded-full transition-all duration-300 ${ index + 1 === currentStep - ? "bg-cyan-400 scale-125" + ? 'bg-cyan-400 scale-125' : index + 1 < currentStep - ? "bg-cyan-400/70" - : "bg-white/20" + ? 'bg-cyan-400/70' + : 'bg-white/20' }`} /> ))} @@ -291,7 +291,7 @@ export default function SignupPage() { type="tel" value={mobile} onChange={(e) => - setMobile(e.target.value.replace(/\D/g, "")) + setMobile(e.target.value.replace(/\D/g, '')) } className="w-full rounded-2xl border border-white/10 bg-black/20 py-3 pl-10 pr-4 text-sm text-foreground outline-none transition-all duration-200 placeholder:text-muted-foreground/70 focus:border-cyan-300/60 focus:bg-black/30 focus:ring-4 focus:ring-cyan-400/10" placeholder="98765 43210" @@ -461,7 +461,7 @@ export default function SignupPage() { {isAdminSignup && (