Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 0 additions & 9 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,9 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
<<<<<<< HEAD
"firebase": "^11.2.0",

"framer-motion": "^12.5.0",

"jspdf": "^3.0.1",

=======
"firebase": "^11.5.0",
"framer-motion": "^12.5.0",
"jspdf": "^3.0.1",
>>>>>>> upstream/main
"lucide-react": "^0.469.0",
"motion": "^12.5.0",
"react": "^18.3.1",
Expand Down
21 changes: 2 additions & 19 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import { ThemeProvider } from './components/ThemeProvider';
import LandingPage from './pages/LandingPage';
import NotFound from './pages/NotFound';
import SignIn from './pages/AuthPage';
import Login from './pages/AuthPage'
import Dashboard from './pages/Dashboard';
import ProfilePage from './pages/ProfilePage';
import ResumeDev from './pages/ResumeDev';
import ResumeResearch from './pages/ResumeResearch'
import ChooseResume from './pages/ChooseResume';
import ResumeResearch from './pages/ResumeResearch';
import ProtectedRoute from './components/ProtectedRoute';

// Resume type components
Expand All @@ -25,29 +24,13 @@ const App = () => {
{/* Public Routes */}
<Route path="/" element={<LandingPage />} />
<Route path="*" element={<NotFound />} />
<<<<<<< HEAD
<Route path="/auth" element={<Auth />} />
<Route path="/login" element={<Login />} />
<Route path="/resume" element={<ChooseResume />} />
<Route path="/resume/developer" element={<DeveloperResume />} />
<Route path="/resume/researcher" element={<ResearcherResume />} />
<Route path="/resume/balanced" element={<BalancedResume />} />

<Route path="/:id/dashboard/" element={<Dashboard />}>
<Route path="profile" element={<ProfilePage />} />
=======
<Route path="/login" element={<SignIn />} />

{/* Protected Routes */}
<Route
path="/dashboard/*"
element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
}
>

>>>>>>> upstream/main
</Route>
<Route path="profile" element={<ProfilePage />} />
<Route
Expand Down
57 changes: 43 additions & 14 deletions client/src/components/ResumeDev/ChatInterface.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState, useEffect, useRef } from 'react';
import resumeData from './resumeData.json';
import profile from './profile.json'

export default function ChatInterface({ onResumeData }) {
const [messages, setMessages] = useState([
Expand Down Expand Up @@ -47,10 +48,8 @@ export default function ChatInterface({ onResumeData }) {
{ text: `Thanks! Analyzing your profile for a ${jobRole} position...`, sender: 'bot' }
]);

// Mock delay to simulate processing
setTimeout(() => {
processResume(jobRole, input);
}, 2000);
// Make API call to generate the resume
fetchCustomizedResume(jobRole, input);
}
} catch (error) {
console.error('Error processing request:', error);
Expand All @@ -63,33 +62,63 @@ export default function ChatInterface({ onResumeData }) {
}
};

const processResume = async (role, description) => {
const fetchCustomizedResume = async (role, description) => {
try {
// Use the actual resume data from the JSON file instead of mock data
setIsLoading(true);

// Update messages to reflect findings
// Prepare request payload according to the API documentation
const payload = {
user_profile: profile,
resume_template: resumeData,
job_description: description
};

// Make the API call
const response = await fetch('/api/resume/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

if (!response.ok) {
throw new Error(`API call failed with status: ${response.status}`);
}

// Parse the response - according to docs it should have a "resume" property
const responseData = await response.json();

// Log the entire response
console.log("API Response:", responseData);

// Extract the resume data from the response
const customizedResumeData = responseData.resume;
console.log("Customized Resume Data:", customizedResumeData);

// Update messages to reflect success
setMessages(prev => [
...prev,
{ text: `Identifying relevant skills for this position...`, sender: 'bot' },
{ text: `I found ${resumeData.skills.length} relevant skills for this position.`, sender: 'bot' },
{ text: `I found ${customizedResumeData.skills?.length || 0} relevant skills for this position.`, sender: 'bot' },
{ text: `Identifying relevant projects for this position...`, sender: 'bot' },
{ text: `I found ${resumeData.projects.length} relevant projects for this position.`, sender: 'bot' },
{ text: `I found ${customizedResumeData.projects?.length || 0} relevant projects for this position.`, sender: 'bot' },
{ text: `Identifying relevant work experience...`, sender: 'bot' },
{ text: `I found ${resumeData.workEx.length} relevant work experiences for this position.`, sender: 'bot' },
{ text: `I found ${customizedResumeData.workEx?.length || 0} relevant work experiences for this position.`, sender: 'bot' },
{ text: `Generating a tailored summary for your resume...`, sender: 'bot' },
{ text: `Your resume is ready! I've created a tailored resume that highlights your relevant skills and experience for this ${role} position. You can view it in the preview panel and download it as a PDF.`, sender: 'bot' }
]);

// Pass the resume data from the JSON file up to the parent component
onResumeData(resumeData);
// Pass the customized resume data to the parent component
onResumeData(customizedResumeData);

// Mark process as complete
setStage('complete');
} catch (error) {
console.error('Error processing resume:', error);
console.error('Error fetching customized resume:', error);
setMessages(prev => [
...prev,
{ text: 'Sorry, there was an error generating your resume. Please try again.', sender: 'bot' }
{ text: 'Sorry, there was an error generating your customized resume. Please try again.', sender: 'bot' }
]);
} finally {
setIsLoading(false);
Expand Down
84 changes: 84 additions & 0 deletions client/src/components/ResumeDev/profile.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"personal_info": {
"name": "John Doe",
"age": 25,
"address": {
"street": "123 Main Street",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "USA"
},
"phone_number": "+1 234-567-8901",
"email": "johndoe@example.com",
"linkedin": "https://linkedin.com/in/johndoe",
"github": "https://github.com/johndoe",
"website": "https://johndoe.dev"
},
"skills": [
"JavaScript",
"React.js",
"Node.js",
"Python",
"Machine Learning",
"Data Structures & Algorithms",
"Database Management",
"Cybersecurity",
"Cloud Computing"
],
"education": [
{
"degree": "Bachelor of Technology",
"field": "Computer Science and Engineering",
"university": "XYZ University",
"year_of_graduation": 2024,
"cgpa": 8.9
}
],
"certifications": [
{
"title": "Google Data Analytics Certificate",
"issuer": "Google",
"year": 2023
},
{
"title": "AWS Certified Solutions Architect",
"issuer": "Amazon Web Services",
"year": 2022
}
],
"projects": [
{
"title": "AI-Powered Resume Builder",
"description": "Developed an AI-based web application that dynamically generates resumes based on user input.",
"technologies": ["React.js", "Node.js", "GPT API", "MongoDB"],
"github_link": "https://github.com/johndoe/resume-builder"
},
{
"title": "Secure Chat App",
"description": "Built an end-to-end encrypted chat application with AI-assisted message summarization.",
"technologies": ["Next.js", "Socket.io", "WebRTC", "AES Encryption"],
"github_link": "https://github.com/johndoe/secure-chat"
}
],
"experience": [
{
"role": "Software Engineer Intern",
"company": "Tech Corp",
"duration": "June 2023 - Dec 2023",
"responsibilities": [
"Developed APIs for a high-traffic web application.",
"Implemented authentication and role-based access control.",
"Optimized database queries to improve response time by 30%."
]
}
],
"achievements": [
"Finalist in Google Solution Challenge 2023",
"Top 5% in LeetCode Global Coding Contest",
"Published research paper on AI in Education at ICML 2024"
],
"languages": ["English", "Spanish", "French"],
"interests": ["Open Source Contributions", "Cybersecurity Research", "AI Ethics"]
}

7 changes: 0 additions & 7 deletions client/src/pages/ChooseResume.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const ChooseResume = () => {
return (
<>
<Topbar/>
<<<<<<< HEAD

<div className="min-h-screen bg-gray-900 py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-4xl mx-auto">
Expand All @@ -53,12 +52,6 @@ const ChooseResume = () => {
))}
</div>
</div>
=======
<div className='bg-black h-screen'>
<ResumeCards/>
<ResumeCards/>
<ResumeCards/>
>>>>>>> upstream/main
</div>
</>
)
Expand Down
88 changes: 78 additions & 10 deletions client/src/pages/Dashboard.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,92 @@
import React from "react";
import React, { useState } from "react";
import Topbar from "@/components/Topbar";
import { Outlet } from "react-router-dom";
import { TypewriterEffectSmooth } from "@/components/ui/typewriter-effect";
import { FlipWords } from "@/components/ui/flip-words";
import { Button } from "@/components/ui/button";

const words = ["Stronger", "Better", "Higher"];

const Dashboard = () => {
const [showFeedback, setShowFeedback] = useState(false);
const [feedback, setFeedback] = useState("");

const handleSubmit = () => {
// Handle the feedback submission here
console.log("Feedback submitted:", feedback);
setFeedback("");
setShowFeedback(false);
};

return (
<div className="flex flex-col min-h-screen bg-black">
{/* Fixed Topbar */}
<div className="sticky top-0 left-0 w-full z-50 shadow-md ">
<Topbar />
<>
<div className="flex flex-col min-h-screen bg-black">
{/* Fixed Topbar */}
<div className="sticky top-0 left-0 w-full z-50 shadow-md ">
<Topbar />
</div>

{/* Scrollable Content */}
<div className="ml-[40%] mt-[20%]">
<span className="text-5xl text-yellow-500">Build<FlipWords words={words}/> </span>
</div>

{/* Feedback Button */}
<div className="fixed bottom-8 right-8">
<Button
onClick={() => setShowFeedback(true)}
className="bg-yellow-500 hover:bg-yellow-600 text-black font-bold py-2 px-4 rounded-full shadow-lg"
>
Give Feedback
</Button>
</div>
</div>

{/* Scrollable Content */}
<div className=" ml-[40%] mt-[20%]">
<span className="text-5xl text-yellow-500">Build<FlipWords words={words}/> </span>
</div>
</div>
{/* Feedback Modal (custom implementation) */}
{showFeedback && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg p-6 w-full max-w-md mx-4">
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-bold">Share Your Feedback</h2>
<button
onClick={() => setShowFeedback(false)}
className="text-gray-500 hover:text-gray-700"
>
</button>
</div>

<div className="mb-4">
<label htmlFor="feedback" className="block text-sm font-medium mb-2">
Your feedback
</label>
<textarea
id="feedback"
value={feedback}
onChange={(e) => setFeedback(e.target.value)}
placeholder="Tell us what you think..."
className="w-full border border-gray-300 rounded-md p-2 min-h-[120px]"
/>
</div>

<div className="flex justify-end space-x-2">
<button
onClick={() => setShowFeedback(false)}
className="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-100"
>
Cancel
</button>
<button
onClick={handleSubmit}
className="px-4 py-2 bg-yellow-500 text-black rounded-md hover:bg-yellow-600"
>
Submit
</button>
</div>
</div>
</div>
)}
</>
);
};

Expand Down
5 changes: 0 additions & 5 deletions client/src/pages/ResumeDev.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,13 @@ function App({ resumeType = 'developer' }) {
return (
<>
<Topbar/>
<<<<<<< HEAD
<div className="flex flex-col bg-gray-950 min-h-screen">
<div className="px-6 py-4">
<h1 className="text-2xl font-bold text-white">{getResumeTitle()}</h1>
<p className="text-gray-400">Tailored for {resumeType} profiles</p>
</div>

<div className="flex flex-1 gap-6 p-6">
=======
<div className="flex h-screen bg-black p-6">
<div className="flex gap-6 w-full h-full">
>>>>>>> upstream/main
<div className="w-1/3">
<ChatInterface onResumeData={handleResumeData} resumeType={resumeType} />
</div>
Expand Down
Loading