diff --git a/.env b/.env new file mode 100644 index 00000000..603b7c84 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +REACT_APP_GEMINI_API_KEY=your_actual_api_key_here + diff --git a/backend/package-lock.json b/backend/package-lock.json index 862aa3aa..43e88a6d 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -19,6 +19,9 @@ }, "devDependencies": { "nodemon": "^3.1.9" + }, + "engines": { + "node": "22.x" } }, "node_modules/@mongodb-js/saslprep": { diff --git a/package-lock.json b/package-lock.json index 1402c4fe..f8b3171f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3920,6 +3920,26 @@ "url": "https://github.com/sponsors/tannerlinsley" } }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@testing-library/jest-dom": { "version": "6.6.4", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.4.tgz", @@ -4000,6 +4020,13 @@ "node": ">=10.13.0" } }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "license": "MIT", + "peer": true + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -4219,7 +4246,7 @@ "version": "15.7.14", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", - "dev": true + "devOptional": true }, "node_modules/@types/q": { "version": "1.5.8", @@ -4246,7 +4273,7 @@ "version": "18.3.21", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.21.tgz", "integrity": "sha512-gXLBtmlcRJeT09/sI4PxVwyrku6SaNUj/6cMubjE6T6XdY1fDmBL7r0nX0jbSZPU/Xr0KuwLLZh6aOYY5d91Xw==", - "dev": true, + "devOptional": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -7050,6 +7077,13 @@ "node": ">=6.0.0" } }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "license": "MIT", + "peer": true + }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -12214,6 +12248,16 @@ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, "node_modules/magic-string": { "version": "0.25.9", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", @@ -17285,6 +17329,20 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", diff --git a/public/data/RayyanStudiosTM.json b/public/data/RayyanStudiosTM.json new file mode 100644 index 00000000..455267d7 --- /dev/null +++ b/public/data/RayyanStudiosTM.json @@ -0,0 +1,22 @@ +{ + "name": "Shaikh Rayyan Ahmed", + "location": "Aurangabad, Maharashtra, India", + "bio": "Software developer and AI enthusiast building SaaS platforms, apps, and AI-powered tools to make learning and productivity smarter.", + "avatar": "https://github.com/RayyanStudiosTM.png", + "portfolio": "https://github.com/RayyanStudiosTM", + "skills": [ + "Full Stack Development", + "AI & Machine Learning", + "App Development", + "SaaS Development", + "Data Science", + "Cloud Computing" + ], + "social": { + "GitHub": "https://github.com/RayyanStudiosTM", + "LinkedIn": "https://www.linkedin.com/in/bytexpert/", + "Instagram": "https://www.instagram.com/mr._.rayy", + "Email": "shaikhrayyanofficial@gmail.com", + "Discord": "https://discord.com/users/shaikhrayyanahmed" + } +} diff --git a/src/Page/AiCareer.jsx b/src/Page/AiCareer.jsx index 3923f077..f2aa982e 100644 --- a/src/Page/AiCareer.jsx +++ b/src/Page/AiCareer.jsx @@ -1,335 +1,2014 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import { Brain, Target, - Briefcase, Code, ChevronRight, - Percent, AlertCircle, CheckCircle2, TrendingUp, - LineChart, - Rocket, - Users, + Clock, + BookOpen, Building2, - Award, + Rocket, ArrowRight, Loader2, - Clock, - BookOpen, - Link, + Sparkles, + Star, + Users, + Award, + Github, + Linkedin, + X, + User, + GraduationCap, + Heart, + ArrowLeft, + Compass, + Trophy, + Lightbulb, + MessageCircle, + Send, + Minimize2, + Maximize2, + Bot, + Copy, + DollarSign, } from 'lucide-react'; -import { analyzeCareerPath } from '../api/skillAnalyzer.js'; - -const Testimonial = ({ name, role, company, text, imageUrl }) => ( -
- {role} at {company} -
+ +// Enhanced Chatbot Component with Gemini Integration +const Chatbot = ({ assessmentData, userProfile }) => { + const [isOpen, setIsOpen] = useState(false); + const [isMinimized, setIsMinimized] = useState(false); + const [messages, setMessages] = useState([ + { + id: 1, + type: 'bot', + content: + "Hi! I'm your AI Career Assistant powered by Gemini. I can help you with career guidance, job search tips, skill recommendations, and answer questions about your career path. How can I assist you today?", + timestamp: new Date(), + }, + ]); + const [inputMessage, setInputMessage] = useState(''); + const [isTyping, setIsTyping] = useState(false); + const [isUserTyping, setIsUserTyping] = useState(false); + const [error, setError] = useState(null); + const [apiKey, setApiKey] = useState(process.env.REACT_APP_GEMINI_API_KEY || ''); + const messagesEndRef = useRef(null); + const inputRef = useRef(null); + const typingTimeoutRef = useRef(null); + + const scrollToBottom = () => { + messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + }; + + useEffect(() => { + scrollToBottom(); + }, [messages]); + + // Handle user typing indicator + const handleInputChange = (e) => { + setInputMessage(e.target.value); + setIsUserTyping(true); + + // Clear existing timeout + if (typingTimeoutRef.current) { + clearTimeout(typingTimeoutRef.current); + } + + // Set timeout to hide typing indicator + typingTimeoutRef.current = setTimeout(() => { + setIsUserTyping(false); + }, 1000); + }; + + // Enhanced Gemini API integration + const callGeminiAPI = async (message, context = '') => { + if (!apiKey) { + throw new Error('Gemini API key is not configured. Please add your API key to environment variables.'); + } + + const careerContext = assessmentData + ? ` +User Profile Context: +- Education: ${assessmentData.education?.currentStatus} +- Field of Study: ${assessmentData.education?.fieldOfStudy} +- Technical Skills: ${assessmentData.skills?.technicalSkills?.join(', ')} +- Soft Skills: ${assessmentData.skills?.softSkills?.join(', ')} +- Career Goal: ${assessmentData.career?.primaryGoal} +- Work Preference: ${assessmentData.personal?.workPreference} +- Interests: ${assessmentData.interests?.industries?.join(', ')} +` + : ''; + + const systemPrompt = `You are an expert AI Career Advisor assistant. Your role is to provide personalized, actionable career guidance. + +${careerContext} + +Guidelines: +1. Provide specific, actionable advice +2. Reference current industry trends and market demands +3. Suggest concrete next steps and resources +4. Be encouraging and supportive +5. Use the user's profile context when available +6. Keep responses concise but comprehensive (2-4 paragraphs max) +7. Include relevant examples when helpful +8. Focus on career development, job searching, skills, interviews, salary negotiation, and professional growth + +User Question: ${message} + +Provide a helpful, personalized response:`; + + try { + const response = await fetch( + `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${apiKey}`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + contents: [ + { + parts: [ + { + text: systemPrompt, + }, + ], + }, + ], + generationConfig: { + temperature: 0.7, + topK: 40, + topP: 0.95, + maxOutputTokens: 1024, + }, + safetySettings: [ + { + category: 'HARM_CATEGORY_HARASSMENT', + threshold: 'BLOCK_MEDIUM_AND_ABOVE', + }, + { + category: 'HARM_CATEGORY_HATE_SPEECH', + threshold: 'BLOCK_MEDIUM_AND_ABOVE', + }, + { + category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', + threshold: 'BLOCK_MEDIUM_AND_ABOVE', + }, + { + category: 'HARM_CATEGORY_DANGEROUS_CONTENT', + threshold: 'BLOCK_MEDIUM_AND_ABOVE', + }, + ], + }), + }, + ); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error(errorData.error?.message || 'Failed to get response from Gemini API'); + } + + const data = await response.json(); + + if (data.candidates && data.candidates[0] && data.candidates[0].content) { + return data.candidates[0].content.parts[0].text; + } else { + throw new Error('Invalid response format from Gemini API'); + } + } catch (error) { + console.error('Gemini API Error:', error); + throw error; + } + }; + + // Enhanced fallback responses + const getFallbackResponse = (message) => { + const lowerMessage = message.toLowerCase(); + + if (lowerMessage.includes('salary') || lowerMessage.includes('pay') || lowerMessage.includes('compensation')) { + return `💰 **Salary Guidance**\n\nSalary ranges vary by role, location, and experience. Here's what I suggest:\n\n• **Research**: Use Glassdoor, PayScale, and LinkedIn Salary Insights\n• **Entry-level tech**: $60-80k typically\n• **Mid-level**: $80-120k range\n• **Senior roles**: $120k+ depending on specialization\n\n**Pro tip**: Factor in total compensation including benefits, equity, and work-life balance. Would you like specific advice for your target role?`; + } + + if (lowerMessage.includes('skill') || lowerMessage.includes('learn') || lowerMessage.includes('technology')) { + return `🚀 **Skill Development Strategy**\n\nBased on current market trends, focus on:\n\n**High-demand technical skills:**\n• JavaScript/TypeScript, Python, React\n• Cloud platforms (AWS, Azure, GCP)\n• AI/ML fundamentals\n• DevOps and containerization\n\n**Essential soft skills:**\n• Communication and leadership\n• Problem-solving and critical thinking\n• Adaptability and continuous learning\n\nWhat specific area interests you most? I can create a detailed learning roadmap!`; + } + + if (lowerMessage.includes('interview') || lowerMessage.includes('preparation')) { + return `🎯 **Interview Success Strategy**\n\n**Technical Preparation:**\n• Practice coding challenges (LeetCode, HackerRank)\n• Review system design basics\n• Prepare for role-specific questions\n\n**Behavioral Questions:**\n• Use the STAR method (Situation, Task, Action, Result)\n• Prepare 5-7 strong examples\n• Practice out loud\n\n**Day of Interview:**\n• Ask thoughtful questions about the role/company\n• Show enthusiasm and cultural fit\n• Follow up within 24 hours\n\nNeed help with specific interview types or questions?`; + } + + if (lowerMessage.includes('career change') || lowerMessage.includes('transition')) { + return `🔄 **Career Transition Roadmap**\n\n**Phase 1: Foundation**\n• Identify transferable skills\n• Research target industry thoroughly\n• Start building relevant skills\n\n**Phase 2: Build Credibility**\n• Create portfolio projects\n• Get relevant certifications\n• Network with industry professionals\n\n**Phase 3: Make the Move**\n• Apply strategically\n• Consider contract/freelance work initially\n• Leverage your unique background\n\nTransitions take 6-18 months typically. What field are you considering?`; + } + + return `I'm here to help with your career journey! While I'm currently offline, I can still assist with:\n\n• **Career planning** and goal setting\n• **Skill development** recommendations\n• **Job search** strategies\n• **Interview preparation** tips\n• **Salary negotiation** guidance\n• **Network building** advice\n\nFor the most personalized guidance, try taking our comprehensive career assessment. What specific area would you like to explore?`; + }; + + // Enhanced message handling with Gemini API + const handleSendMessage = async () => { + if (!inputMessage.trim()) return; + + const userMessage = { + id: messages.length + 1, + type: 'user', + content: inputMessage.trim(), + timestamp: new Date(), + }; + + setMessages((prev) => [...prev, userMessage]); + setInputMessage(''); + setIsUserTyping(false); + setIsTyping(true); + setError(null); + + try { + // Call Gemini API + const aiResponse = await callGeminiAPI(userMessage.content); + + const botResponse = { + id: messages.length + 2, + type: 'bot', + content: aiResponse, + timestamp: new Date(), + }; + + setMessages((prev) => [...prev, botResponse]); + } catch (error) { + console.error('Error getting AI response:', error); + + // Fallback to predefined responses if API fails + const fallbackResponse = getFallbackResponse(userMessage.content); + + const botResponse = { + id: messages.length + 2, + type: 'bot', + content: fallbackResponse, + timestamp: new Date(), + isError: true, + }; + + setMessages((prev) => [...prev, botResponse]); + setError('Using offline responses. For best experience, please check your internet connection.'); + } finally { + setIsTyping(false); + } + }; + + // Enhanced quick actions based on user context + const getContextualQuickActions = () => { + const baseActions = [ + 'What skills should I learn next?', + 'Help me prepare for interviews', + 'Career change advice needed', + 'Salary negotiation tips', + 'How to build a strong portfolio?', + ]; + + if (assessmentData) { + const personalizedActions = [ + `Roadmap for ${assessmentData.career?.primaryGoal || 'my career goal'}`, + `Best practices for ${assessmentData.interests?.industries?.[0] || 'my industry'}`, + 'Next steps based on my assessment', + ]; + return personalizedActions.concat(baseActions.slice(0, 3)); + } + + return baseActions; + }; + + const quickActions = getContextualQuickActions(); + + const handleQuickAction = (action) => { + setInputMessage(action); + if (inputRef.current) { + inputRef.current.focus(); + } + }; + + const copyMessage = (content) => { + navigator.clipboard.writeText(content); + }; + + if (!isOpen) { + return ( +{error ? 'Offline Mode' : 'Powered by Gemini • Online'}
+✨ Try asking about:
+“{text}”
-{description}
-Analyzing your responses to create personalized recommendations...
++ Help us understand your background, skills, and goals to create a personalized career roadmap. +
++ {currentSection.id === 'education' && 'Tell us about your educational background and academic interests.'} + {currentSection.id === 'skills' && + 'Share your technical abilities and soft skills to help us understand your strengths.'} + {currentSection.id === 'interests' && + "Your interests and motivations help us identify career paths you'll be passionate about."} + {currentSection.id === 'personal' && + 'Understanding your working style and preferences helps us recommend the right environment.'} + {currentSection.id === 'career' && + 'Your career goals and priorities help us create a personalized roadmap for success.'} +
+- Navigate your career journey with precision using AI-powered insights. Get personalized recommendations - and close your skill gaps effectively. -
- - Get Started -