Skip to content

Commit 1cb7462

Browse files
authored
Merge pull request #161 from Code-Hammers/CHE-113/story/Profiles-Improvements
[CHE 113] Profiles Improvements
2 parents 4224d74 + f19b3f7 commit 1cb7462

File tree

20 files changed

+795
-79
lines changed

20 files changed

+795
-79
lines changed

.DS_Store

8 KB
Binary file not shown.

__tests__/profileController.test.ts

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,30 @@ xdescribe('Profile Controller Tests', () => {
9999
mockRequest = {
100100
params: { userID: '65117c94f000c9930ef5c0ee' },
101101
body: {
102-
firstName: 'Bobby',
103-
lastName: 'Orr',
102+
availabilityForNetworking: true,
103+
careerInformation: {
104+
currentPosition: {
105+
company: 'CodeHammers',
106+
title: 'Developer',
107+
},
108+
pastPositions: [
109+
{
110+
company: 'CodeHammers',
111+
title: 'Junior Developer',
112+
startDate: '2020-01-01',
113+
endDate: '2021-01-01',
114+
},
115+
],
116+
},
117+
cohort: 'ECRI-TEST',
104118
119+
gitHubProfile: 'Ghub',
120+
linkedInProfile: 'Lin',
121+
nickName: 'Johnny',
122+
personalBio: 'I love dogs!',
123+
skills: ['Javascript', 'Typescript', 'React', 'Nodejs'],
124+
socialMediaLinks: 'SMlinks',
125+
specializations: ['Javascript', 'React'],
105126
},
106127
};
107128
mockResponse = {
@@ -114,9 +135,30 @@ xdescribe('Profile Controller Tests', () => {
114135
it('should handle profile update', async () => {
115136
(Profile.findOneAndUpdate as jest.Mock).mockResolvedValue({
116137
_id: '65117c94f000c9930ef5c0ee',
117-
firstName: 'Bobby',
118-
lastName: 'Orr',
138+
availabilityForNetworking: true,
139+
careerInformation: {
140+
currentPosition: {
141+
company: 'CodeHammers',
142+
title: 'Developer',
143+
},
144+
pastPositions: [
145+
{
146+
company: 'CodeHammers',
147+
title: 'Junior Developer',
148+
startDate: '2020-01-01',
149+
endDate: '2021-01-01',
150+
},
151+
],
152+
},
153+
cohort: 'ECRI-TEST',
119154
155+
gitHubProfile: 'Ghub',
156+
linkedInProfile: 'Lin',
157+
nickName: 'Johnny',
158+
personalBio: 'I love dogs!',
159+
skills: ['Javascript', 'Typescript', 'React', 'Nodejs'],
160+
socialMediaLinks: 'SMlinks',
161+
specializations: ['Javascript', 'React'],
120162
});
121163

122164
await updateProfile(mockRequest as Request, mockResponse as Response, mockNext);

client/src/assets/blogLogo.png

1.65 KB
Loading

client/src/assets/github_icon.png

1.33 KB
Loading

client/src/assets/linkedInLogo.png

740 Bytes
Loading

client/src/assets/twitterLogo.png

816 Bytes
Loading

client/src/components/Header/Header.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ const Header = () => {
3232

3333
return (
3434
<div
35-
className="fixed top-0 left-0 right-0 bg-gray-600 text-white p-4 md:p-6 flex items-center justify-between"
35+
className="bg-gray-600 fixed flex items-center justify-between left-0 md:p-6 p-4 right-0 text-white top-0"
3636
style={{ margin: '10px 20px 0 20px', zIndex: 1000 }}
3737
>
3838
<Link to="/app/main" className="flex items-center">
3939
<img src={logo} alt="Code Hammers Logo" className="h-12 md:h-16" />
40-
<h1 className="ml-3 text-xl md:text-2xl font-bold">Code Hammers</h1>
40+
<h1 className="font-bold md:text-2xl ml-3 text-xl">Code Hammers</h1>
4141
</Link>
4242

4343
<div className="flex-grow mx-10">
44-
<div className="flex justify-evenly space-x-4 md:space-x-6 lg:space-x-10">
44+
<div className="flex justify-evenly lg:space-x-10 md:space-x-6 space-x-4">
4545
<Link
4646
to="/app/directory"
4747
className={`text-lg md:text-xl ${
@@ -60,15 +60,15 @@ const Header = () => {
6060
</Link>
6161
<Link
6262
to="/app/profiles"
63-
className={`text-lg md:text-xl ${
63+
className={`md:text-xl text-lg ${
6464
currentPath === 'profiles' ? 'text-gray-300' : 'hover:text-gray-300'
6565
} transition transform hover:scale-105`}
6666
>
6767
Profiles
6868
</Link>
6969
<Link
7070
to="/app/forums"
71-
className={`text-lg md:text-xl ${
71+
className={`md:text-xl text-lg ${
7272
currentPath === 'forums' ? 'text-gray-300' : 'hover:text-gray-300'
7373
} transition transform hover:scale-105`}
7474
>
@@ -79,18 +79,18 @@ const Header = () => {
7979
<div className="relative">
8080
<button
8181
onClick={() => setShowDropdown(!showDropdown)}
82-
className="bg-gray-700 hover:bg-gray-800 font-bold py-2 px-4 rounded"
82+
className="bg-blue-500 font-bold hover:bg-blue-700 px-4 py-2 rounded text-white"
8383
>
8484
Account
8585
</button>
8686
{showDropdown && (
8787
<div
8888
ref={dropdownRef}
89-
className="absolute right-0 mt-2 py-2 w-48 bg-gray-700 rounded-md shadow-xl z-20"
89+
className="absolute bg-gray-700 mt-2 py-2 right-0 rounded-md shadow-xl w-48 z-20"
9090
>
9191
<a
9292
href="#!"
93-
className="block px-4 py-2 text-sm text-white hover:bg-gray-800"
93+
className="block hover:bg-gray-800 px-4 py-2 text-sm text-white"
9494
onClick={() => {
9595
navigate('/app/editProfile');
9696
setShowDropdown(false);
@@ -100,7 +100,7 @@ const Header = () => {
100100
</a>
101101
<a
102102
href="#!"
103-
className="block px-4 py-2 text-sm text-white hover:bg-gray-800"
103+
className="block hover:bg-gray-800 px-4 py-2 text-sm text-white"
104104
onClick={handleLogout}
105105
>
106106
Logout
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React from 'react';
2+
3+
interface EditProfileInputProps {
4+
label: string;
5+
type: string;
6+
value: string;
7+
name: string;
8+
onChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
9+
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void; // Add onKeyDown as optional
10+
placeholder?: string;
11+
}
12+
13+
const EditProfileInput = ({
14+
label,
15+
type,
16+
value,
17+
name,
18+
onChange,
19+
onKeyDown,
20+
placeholder,
21+
}: EditProfileInputProps) => {
22+
return (
23+
<div className="mb-4">
24+
<label className="block font-bold mb-2 text-sm" htmlFor={name}>
25+
{label}
26+
</label>
27+
{type === 'textarea' ? (
28+
<textarea
29+
className="bg-gray-800 p-2 rounded text-white w-full"
30+
id={name}
31+
name={name}
32+
value={value}
33+
onChange={onChange}
34+
style={{ maxHeight: '200px' }}
35+
maxLength={1000}
36+
/>
37+
) : (
38+
<input
39+
className="bg-gray-800 p-2 rounded text-white w-full"
40+
id={name}
41+
name={name}
42+
type={type}
43+
value={value}
44+
onChange={onChange}
45+
onKeyDown={onKeyDown}
46+
placeholder={placeholder}
47+
/>
48+
)}
49+
</div>
50+
);
51+
};
52+
53+
export default EditProfileInput;

client/src/components/ProfileThumb/ProfileThumb.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,27 @@ interface ProfileThumbProps {
77
const ProfileThumb = ({ profile }: ProfileThumbProps) => {
88
const defaultImage = 'https://picsum.photos/200';
99

10+
const shortenBio = (bio: string | undefined, wordLimit: number) => {
11+
if (!bio) return;
12+
const words: string[] = bio.split(' ');
13+
if (words.length > wordLimit) {
14+
return words.slice(0, wordLimit).join(' ') + '...';
15+
}
16+
return bio;
17+
};
18+
1019
return (
11-
<div className="bg-gradient-to-r from-gray-700 via-gray-800 to-gray-900 text-white p-4 rounded-lg flex flex-col items-center justify-center h-64 w-64">
20+
<div className="bg-gradient-to-r flex flex-col from-gray-700 h-64 items-center justify-center p-4 rounded-lg text-white to-gray-900 via-gray-800 w-64">
1221
<img
1322
src={profile.profilePhoto || defaultImage}
1423
alt={profile.firstName || 'Default Profile'}
15-
className="rounded-full h-24 w-24 object-cover mb-4"
24+
className="h-24 mb-4 object-cover rounded-full w-24"
1625
/>
1726

18-
<h1 className="text-xl font-bold mb-2">
27+
<h1 className="font-bold mb-2 text-xl">
1928
{profile.firstName} {profile.lastName}
2029
</h1>
21-
<h2 className="text-md mb-2">{profile.personalBio}</h2>
30+
<h2 className="max-h-10 mb-2 text-xs">{shortenBio(profile.personalBio, 8)}</h2>
2231
</div>
2332
);
2433
};

client/src/features/userProfile/userProfileSlice.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
22
import axios from 'axios';
33
import { IProfile } from '../../../types/profile';
4+
import { NavigateFunction } from 'react-router-dom';
45

56
export interface ProfileState {
67
profile: IProfile | null;
@@ -31,11 +32,18 @@ export const fetchUserProfile = createAsyncThunk(
3132
},
3233
);
3334

35+
interface UpdateUserProfileArgs extends Partial<IProfile> {
36+
userID: string;
37+
navigate: NavigateFunction;
38+
}
39+
3440
export const updateUserProfile = createAsyncThunk(
3541
'profile/updateUserProfile',
36-
async ({ userID, ...updateData }: Partial<IProfile> & { userID: string }, thunkAPI) => {
42+
async ({ userID, navigate, ...updateData }: UpdateUserProfileArgs, thunkAPI) => {
3743
try {
44+
console.log('userId before axios call: ', userID);
3845
const response = await axios.put(`/api/profiles/${userID}`, updateData);
46+
navigate(`/app/profile/${userID}`);
3947
return response.data;
4048
} catch (error) {
4149
let errorMessage = 'An error occurred during profile update';

0 commit comments

Comments
 (0)