Skip to content

Commit

Permalink
Merge pull request #8 from Ndevu12/ft-user-profile
Browse files Browse the repository at this point in the history
ft profile
  • Loading branch information
Ndevu12 authored Oct 14, 2024
2 parents 978ea97 + a6e828d commit cb8ff38
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 27 deletions.
49 changes: 33 additions & 16 deletions DummyData/users/dummyUserData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { userIconUrl } from "../../src/assets/images/images";

export const dummyUserData = {
account: {
id: "12345",
_id: { "$oid": "670d619cba23872288152b62" },
profileImage: userIconUrl,
name: "John Doe",
email: "john.doe@example.com",
occupation: "Software Engineer",
phone: "+1-555-555-5555",
address: {
street: "123 Main St",
Expand All @@ -14,25 +15,41 @@ export const dummyUserData = {
zip: "12345",
country: "USA",
},
company: {
name: "Tech Solutions Inc.",
website: "www.techsolutions.com",
logo: "https://via.placeholder.com/150",
logoBackground: "#f0f0f0",
},
AppliedJobs: [
company: [
{ "$oid": "670c194c0f09b3416d5a6d72" }
],
password: "$2a$10$AebymRSaQpVvt6Absyi3C.qbWo5hpk3KTmfSrssQGj74JcDwm6mfu",
role: "user",
appliedJobs: [
{ "$oid": "670c170ca6260f596823a232" },
{ "$oid": "670c1755cce0e10ec98a2edb" }
],
education: [
{
_id: { "$oid": "670c19b4f4758894c56166aa" },
institution: "University of Example",
degree: "Bachelor of Science in Computer Science",
year: "2020"
}
],
experience: [
{
jobId: "job123",
position: "Software Engineer",
_id: { "$oid": "670c1af2b93fef838ae8d679" },
company: "Tech Solutions Inc.",
appliedAt: "2023-01-01T12:00:00Z",
},
role: "Software Engineer",
duration: "2 years"
}
],
skills: [
{
jobId: "job456",
position: "Frontend Developer",
company: "Web Innovations LLC",
appliedAt: "2023-02-15T08:30:00Z",
_id: { "$oid": "670c10659d22c26d32cc3f45" },
name: "JavaScript"
},
{
_id: { "$oid": "670c10659d22c26d32cc3f46" },
name: "React"
}
],
__v: { "$numberInt": "0" }
},
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@testing-library/user-event": "^14.5.2",
"@types/crypto-js": "^4.2.2",
"@types/jsonwebtoken": "^9.0.7",
"@types/jwt-decode": "^3.1.0",
"@types/node": "^20.14.7",
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
Expand Down Expand Up @@ -96,4 +97,4 @@
},
"main": "index.js",
"license": "MIT"
}
}
9 changes: 7 additions & 2 deletions src/pages/Jobs/SingleJobPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { PropagateLoader } from "react-spinners";
import { dummyJobData } from "../../../DummyData/detailedJob";
import Modal from 'react-modal';
import { FiX } from 'react-icons/fi';
import { jwtDecode } from 'jwt-decode';

const API_BASE_URL = (import.meta as any).env.VITE_REACT_APP_API_BASE_URL;

Expand Down Expand Up @@ -54,7 +55,11 @@ const SingleJobPage: React.FC = () => {
const token = localStorage.getItem("token");
if (token) {
try {
const response = await fetch(`${API_BASE_URL}/account`, {
// Decode the token to get the userId
const decodedToken: any = jwtDecode(token);
const userId = decodedToken.userId;

const response = await fetch(`${API_BASE_URL}/account/${userId}`, {
headers: {
Authorization: `Bearer ${token}`,
},
Expand Down Expand Up @@ -166,7 +171,7 @@ const SingleJobPage: React.FC = () => {
// Fallback to localStorage
toast.info("Application failed");
const appliedJobs = JSON.parse(localStorage.getItem("appliedJobs") || "[]");
appliedJobs.push({ jobId: jobData._id, method: "uploadedCV", fileName: selectedFile.name });
appliedJobs.push({ jobId: jobData._id || jobData.id, method: "uploadedCV", fileName: selectedFile.name });
localStorage.setItem("appliedJobs", JSON.stringify(appliedJobs));
toast.success("Successfully applied for the job (stored locally)");
setApplyText("Applied");
Expand Down
76 changes: 68 additions & 8 deletions src/pages/profile/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { toast, ToastContainer } from 'react-toastify';
import { useNavigate } from 'react-router-dom';
import { dummyUserData } from '../../../DummyData/users/dummyUserData';
import Button from '../../components/Buttons/Button';
import {jwtDecode} from 'jwt-decode';

const API_BASE_URL = (import.meta as any).env.VITE_REACT_APP_API_BASE_URL;

const defaultJobKey = () => {
return `${Math.random().toString(36).substr(2, 9)}`;
};

const ProfilePage: React.FC = () => {
const { isLoggedIn } = useAuth();
const [userData, setUserData] = useState<any>(null);
Expand All @@ -27,7 +32,10 @@ const ProfilePage: React.FC = () => {
const token = localStorage.getItem('token');
if (token) {
try {
const response = await fetch(`${API_BASE_URL}/account`, {
// Decode the token to get the userId
const decodedToken: any = jwtDecode(token);
const userId = decodedToken.userId;
const response = await fetch(`${API_BASE_URL}/account/${userId}`, {
headers: {
Authorization: `Bearer ${token}`,
},
Expand Down Expand Up @@ -65,7 +73,8 @@ const ProfilePage: React.FC = () => {
});
}
}
} catch (error) {
} catch (error: any) {
console.log(error.message);
toast.error('Something went wrong, Try again!');
const localData = localStorage.getItem('userData');
if (localData) {
Expand Down Expand Up @@ -134,6 +143,7 @@ const ProfilePage: React.FC = () => {
toast.error('Failed to update profile');
}
} catch (error) {
console.log(error);
toast.error('Something went wrong, Try again!');
}
}
Expand All @@ -160,6 +170,7 @@ const ProfilePage: React.FC = () => {
toast.error('Failed to change password');
}
} catch (error) {
console.log(error);
toast.error('Something went wrong, Try again!');
}
}
Expand All @@ -173,8 +184,8 @@ const ProfilePage: React.FC = () => {
const token = localStorage.getItem('token');
if (token) {
try {
const response = await fetch(`${API_BASE_URL}/account/upload-profile-image`, {
method: 'POST',
const response = await fetch(`${API_BASE_URL}/account`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${token}`,
},
Expand All @@ -190,6 +201,7 @@ const ProfilePage: React.FC = () => {
toast.error('Failed to upload profile image');
}
} catch (error) {
console.log(error);
toast.error('Something went wrong, Try again!');
}
}
Expand Down Expand Up @@ -221,6 +233,7 @@ const ProfilePage: React.FC = () => {
toast.error('Failed to upload CV');
}
} catch (error) {
console.log(error);
toast.error('Something went wrong, Try again!');
}
}
Expand All @@ -233,7 +246,7 @@ const ProfilePage: React.FC = () => {

return (
<div className='bg-white mt-5 mb-7 p-6 rounded-lg mx-auto max-w-4xl'>
<ToastContainer />
<ToastContainer />
<div className="container mt-7 mx-auto p-4">
<h1 className="text-2xl font-bold mb-4">Profile</h1>
{userData ? (
Expand Down Expand Up @@ -298,6 +311,7 @@ const ProfilePage: React.FC = () => {
<div className="flex flex-col items-left justify-center pl-10 pt-10 pb-5 mb-4 border border-gray-100 pt-3 rounded pb-10">
<p><span className='font-medium text-lg'>Name: </span>{userData.name}</p>
<p><span className='font-medium text-lg'>Email: </span>{userData.email}</p>
<p><span className='font-medium text-lg'>Occupation: </span>{userData.occupation}</p>
<p><span className='font-medium text-lg'>Phone: </span>{userData.phone}</p>
<p><span className='font-medium text-lg'>Address: </span>{`${userData.address.street}, ${userData.address.city}, ${userData.address.state}, ${userData.address.zip}, ${userData.address.country}`}</p>
<button onClick={() => setEditMode(true)} className="w-[30%] bg-blue-400 text-white px-4 py-2 rounded mt-4">Edit Profile</button>
Expand All @@ -306,10 +320,10 @@ const ProfilePage: React.FC = () => {
)}
<div className="mt-8 flex flex-col items-left justify-center pl-10 pt-10 pb-5 mb-4 border border-gray-100 rounded">
<h2 className="text-xl font-bold mb-4">Applied Jobs</h2>
{userData.AppliedJobs.length > 0 ? (
{userData.appliedJobs.length > 0 ? (
<ul>
{userData.AppliedJobs.map((job: any) => (
<li key={job.jobId} className="mb-4">
{userData.appliedJobs.map((job: any) => (
<li key={defaultJobKey()} className="mb-4">
<p><span className='font-medium text-lg'>Position: </span>{job.position}</p>
<p><span className='font-medium text-lg'>Company: </span>{job.company}</p>
<p><span className='font-medium text-lg'>Applied At: </span>{new Date(job.appliedAt).toLocaleDateString()}</p>
Expand All @@ -325,6 +339,52 @@ const ProfilePage: React.FC = () => {
<input type="file" name="cv" onChange={handleFileChange} className="mt-2" />
<button onClick={handleUploadCv} className="bg-blue-400 text-white px-4 py-2 rounded mt-2">Upload CV</button>
</div>
<div className="mt-8 pl-10">
<h2 className="text-xl font-bold mb-4">Education</h2>
{userData.education.length > 0 ? (
<ul>
{userData.education.map((edu: any) => (
<li key={defaultJobKey()} className="mb-4">
<p><span className='font-medium text-lg'>Institution: </span>{edu.institution}</p>
<p><span className='font-medium text-lg'>Degree: </span>{edu.degree}</p>
<p><span className='font-medium text-lg'>Year: </span>{edu.year}</p>
</li>
))}
</ul>
) : (
<p>No education details available.</p>
)}
</div>
<div className="mt-8 pl-10">
<h2 className="text-xl font-bold mb-4">Experience</h2>
{userData.experience.length > 0 ? (
<ul>
{userData.experience.map((exp: any) => (
<li key={defaultJobKey()} className="mb-4">
<p><span className='font-medium text-lg'>Company: </span>{exp.company}</p>
<p><span className='font-medium text-lg'>Role: </span>{exp.role}</p>
<p><span className='font-medium text-lg'>Duration: </span>{exp.duration}</p>
</li>
))}
</ul>
) : (
<p>No experience details available.</p>
)}
</div>
<div className="mt-8 pl-10">
<h2 className="text-xl font-bold mb-4">Skills</h2>
{userData.skills.length > 0 ? (
<ul>
{userData.skills.map((skill: any) => (
<li key={defaultJobKey()} className="mb-4">
<p><span className='font-medium text-lg'>Skill: </span>{skill.name}</p>
</li>
))}
</ul>
) : (
<p>No skills available.</p>
)}
</div>
</div>
) : (
<div>No user data available</div>
Expand Down

0 comments on commit cb8ff38

Please sign in to comment.