Skip to content

Commit

Permalink
B dev (#79)
Browse files Browse the repository at this point in the history
* Test for talent controllers

* Talent controllers

* Talent route

* Added talentRoute endpoint

* Package json update

* Fixed linting issues

* Revert changes

* Accept integration: getTalentById

* Fixed no-unsed-var error

* test: add test for getall offers endpoint

* feat: add talent and auth route to client app

* feat: implement initial auth page

* feat: implement user toggle auth type

User can toggle between user signin type, Employer or talent singin

* chore: bypass eslint error

* chore: fix eslint unused vars

* chore: add package-lock.json to gitignore

* chore: remove package-lock.json from git track

* B dev (#27)

* Test for talent controllers

* Talent controllers

* Talent route

* Added talentRoute endpoint

* Package json update

* Fixed linting issues

* Revert changes

* Accept integration: getTalentById

* Fixed no-unsed-var error

* test: fix failed test for talentcontrollers

* chore: fix eslint hasOwnProperty

* Employer Signup and Login (#34)

* employerSignup

* employer signup and login

* added a test

* fixed

* Feat: About us section implemented (#36)

* feat: made about section

* feat: done with about us page

* fix: linting errors

* readme update&auth page minimal implementation (#39)

* docs: update readme with more project information

* feat: integrate auth pg with auth api for talents

* feat: talent signin and signup v1 implementation

* feat: update landing page with logo

* docs: update readme

Changed logo size in readme

* feat: implement talent and employer routing

Implement authentication for talent and employer to redirect to the various pages

* fix: fix eslint error&update project favicon

* bug: change talent onClick toggle to true or false

Changed the employer and talent toggle from the auth form to take in true or false as the onClick setIsTalent param instead of bool negation

* test: fix test assertions in talentController test

* docs: update readme with more project information

* feat: talent signin and signup v1 implementation

* docs: update readme

Changed logo size in readme

* feat: add seperate models for the following

certification
experience,
skills,
education and
project

* Rebasing staging:Mergeconflict resolved

* Added talentPagination endpoint

* Talent pagination file

* Talent pagination route

* Feat: Error handler

* Feat: Talent pagination

* Feat: Talent pagination route

* Feat:Landing-page

* fix: linting errors

* feat: made about section

* chore: made minor changes

* fix: made minor changes

* chore: general fixes

* chore: clean staging branch

* bug: add location to talent test mock data

* test: remove redundant test file

* feat: implemented datepicker component

* feat: creaed Talent Card component and implemented dummy content for employer page

* chore: fix tsc bundle error

fix tsc bundle error for talent undefined props

* feat: add skills resource endpoints

* feat: add endpoints for talent experience

* Incoming changes

* Conflict merge: Resolved

* refactor: initial code refactor to use redux

* Conflict merge: Resolved

* feat: implement user logout when token expire

* chore: fix client lint error

* feat: implement talent data fetching from the api

* feat: add route button to talent card

Added show talent details route button using react-router-dom Link functionality

* fix: fix eslint error

* feat: add user talent details and offers pages

Add client pages for talent offers and talent details

* Employer user read/write 40% progress (#64)

* feat: add x and linkedn socials to talent table

* feat: add more page routes&adjust navbar

Add talenthire, getranked, and employeroffer route pages
Adjust navbar to detect user logged in

* bug: fix assets images not loading in details page

Changed img src to absolute path and move all asset files to public directory

* feat: implement Show talent initial page

Implemented minimal talent details page from the employers account consuming api to get one talent by id

* fix: fix eslint useEffect dependencies

* Conflict merge: Resolved

* Conflict merge: Resolved

* Conflict merge: Resolved

* feat: add more talents props tables api endpoints

Added Certification, Education adn Projects resource endpoint

* feat: add patch http method for talent routes

* feat: add more offer routes

Add route to get offer by employer or talent id

* feat: implement minimal talent offer card

* feat: implement minimal talent offer page

* feat: add offer create redux action type

* bug: add offerData to createOffer post endpoint

* feat: add employer offer page initial design

* feat: add hire dev offer form for testing

* feat: add getbytalent id route for talent bio data

* feat: add talents subdata reducer actions && types

* fix: fix eslint error

* Conflict merge: Resolved

* Conflict merge: Resolved

* Merge conflict: resolving

* Conflict merge: Resolved

* Merge conflict: package-lock.json

* Conflict merge: Resolved

* Conflict merge: Resolved

* Merge conflict: Interfaces

* Conflict merge: Resolved

* Conflict merge: Resolved

* Merge conflict: Resolving

* Merge conflict: Accepted incoming changes

* Merge conflict: Accepted incoming changes

* Merge conflict: Accepted incoming changes

* Merge conflict: Resolving

* Merge conflict: Resolving

* Merge conflict: Resolving

* Feat: ProfileDropDownMenu

* Package-lock.json

* Feat: ProfileDropDownMenu component

* Fixed lint issues

* Fixed lint issues

* Repetition: removed duplicate code

* Test: features

---------

Co-authored-by: Ayobami <[email protected]>
Co-authored-by: Jojo Thomas <[email protected]>
Co-authored-by: Lawal Abubakar Babatunde <[email protected]>
  • Loading branch information
4 people authored Oct 20, 2023
1 parent 7717eb4 commit 5a553ea
Show file tree
Hide file tree
Showing 16 changed files with 256 additions and 105 deletions.
5 changes: 5 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"semi": true,
"jsxSingleQuote": true,
"singleQuote": true
}
15 changes: 7 additions & 8 deletions client/package-lock.json

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

1 change: 1 addition & 0 deletions client/src/actions/education.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const getEducationsTalent =
try {
setLoading(true);
const { data } = await getTalentEducations(talentId);

dispatch({ type: 'FETCH_TALENT_EDUCATION', payload: data });
setLoading(false);
} catch (error: any) {
Expand Down
36 changes: 36 additions & 0 deletions client/src/components/DropDown/DropDown.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.dropDownProfile{
position: absolute;
top: 5rem;
right: 2rem;
width: 120px;
padding: 15px;
border-radius: 15px;
background-color: rgb(62, 143, 62);
border: 1px solid gray;
color: black;
}

.dropDownProfile::before{
content: '';
position: absolute;
top: -0.7rem;
left: 65px;
/* right: 1.1px; */
width: 24px;
height: 24px;
transform: rotate(37deg);
background-color: white;
border-left: 1px solid gray;
border-top: 1px solid gray;
background-color: rgb(62, 143, 62);

}

.logout{
cursor: pointer;
font-weight: 600;
box-sizing: content-box;
border-radius: 8px;
padding-left: 16px;
background-color: rgb(189, 45, 45);
}
16 changes: 16 additions & 0 deletions client/src/components/DropDown/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import './DropDown.css'

function ProfileDropDownMenu({ logout }: { logout: () => void }): JSX.Element {

return (
<div className='flex flex-col dropDownProfile'>
<ul className='flex flex-col gap-3'>
<li>Edit Profile</li>
<li>Settings</li>
<li onClick={logout} className='logout'>Logout</li> {/* Use onClick to trigger the logout function */}
</ul>
</div>
)
}

export default ProfileDropDownMenu
9 changes: 0 additions & 9 deletions client/src/components/Loading/Submit.tsx

This file was deleted.

133 changes: 66 additions & 67 deletions client/src/components/Navbar/TalentNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,79 +4,78 @@ import { Link, useNavigate, useLocation } from 'react-router-dom';
import { useEffect, useState } from 'react';
import jwtDecode from 'jwt-decode';
import './TalentNav.css';
import ProfileDropDownMenu from '../DropDown/DropDown';

function TalentNav(): JSX.Element {
const navigate = useNavigate();
const location = useLocation();
const path = location.pathname;
let profile;
if (!path.includes('talent')) {
profile = JSON.parse(localStorage.getItem('employerProfile'));
} else {
profile = JSON.parse(localStorage.getItem('talentProfile'));
}
const [openProfile, setOpenProfile] = useState(false);
const navigate = useNavigate();
const location = useLocation();
const path = location.pathname;
let profile;
if (!path.includes('talent')) {
profile = JSON.parse(localStorage.getItem('employerProfile'));
} else {
profile = JSON.parse(localStorage.getItem('talentProfile'));
}

const [user, setUser] = useState(profile);
const [user, setUser] = useState(profile);

const logout = () => {
localStorage.clear();
navigate('/auth');
};
const logout = () => {
localStorage.clear();
navigate('/auth');
};

// side effect on refresh when token expire
useEffect(() => {
const token = user?.token;
if (token) {
const decodedToken = jwtDecode(token);
if (decodedToken.exp * 1000 < new Date().getTime()) logout();
}
}, [location]);
return (
<div className='talent-nav'>
<div className='nav-con'>
<img
className={'rounded-full'}
src={'/assets/logo.png'}
alt=''
/>
<nav className='nav-items-con'>
{user.data ? (
''
) : (
<Link to={`/talent/getranked/${user.talent._id}`}>
Get Ranked
</Link>
)}
<Link to={'#'}>Messages</Link>
{/* we'll have a condition for this, if user is talent use talent else employer id */}
<Link
to={
user.talent
? `/offers/talent/${user.talent._id}`
: `/offers/employer/${user.data._id}`
}
>
Offers
</Link>
</nav>
</div>
// side effect on refresh when token expires
useEffect(() => {
const token = user?.token;
if (token) {
const decodedToken = jwtDecode(token);
if (decodedToken.exp * 1000 < new Date().getTime()) logout();
}
}, [location]);

<Link to={'#'}>
<img
src='/assets/talents/no_image.png'
alt='fine girl'
className='w-20 rounded-full'
/>
<p>{user.data ? user.data.name : user.talent.name}</p>
</Link>
<button
className='border-white-300 bg-green-600 hover:bg-green-300 rounded-lg border-2 w-36 h-10'
onClick={logout}
>
Log out
</button>
</div>
);
return (
<div className='talent-nav'>
<div className='nav-con'>
<img
className={'rounded-full'}
src={'/assets/logo.png'}
alt=''
/>
<nav className='nav-items-con' onClick={() => setOpenProfile(true)}>
{user.data ? (
''
) : (
<Link to={`/talent/getranked/${user.talent._id}`}>
Get Ranked
</Link>
)}
<Link to={'#'}>Messages</Link>
<Link
to={
user.talent
? `/offers/talent/${user.talent._id}`
: `/offers/employer/${user.data._id}`
}
>
Offers
</Link>
</nav>
</div>

<Link to={'#'} >
<img
src='/assets/talents/no_image.png'
alt='fine girl'
className='w-20 rounded-full'
onClick={() => setOpenProfile((prev) => !prev)}
/>
<p>{user.data ? user.data.name : user.talent.name}</p>

</Link>
{openProfile && <ProfileDropDownMenu logout={logout} />}
</div>
);
}

export default TalentNav;
3 changes: 2 additions & 1 deletion client/src/pages/Landing-Page/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

import Home from "./Home";
import Faq from "./FAQ";
import AboutUs from "./About_us";
Expand All @@ -11,6 +12,6 @@ const LandingPage = () => {
<Faq />
</>
);
};
}

export default LandingPage;
4 changes: 2 additions & 2 deletions server/controllers/employerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const JWT_SECRET = process.env.JWT_SECRET ?? 'your-secret-key';
export const employerSignup = async (
req: Request,
res: Response,
next: NextFunction
next: NextFunction,
): Promise<Response | undefined> => {
const { name, email, password } = req.body;

Expand Down Expand Up @@ -48,7 +48,7 @@ export const employerSignup = async (
export const employerLogin = async (
req: Request,
res: Response,
next: NextFunction
next: NextFunction,
): Promise<Response | undefined> => {
const { email, password } = req.body;

Expand Down
5 changes: 3 additions & 2 deletions server/controllers/offerController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const getOffer = async <T>(
// get offer by talentId
export const getOfferByTalent = async <T>(
req: GenericRequest<T>,
res: GenericResponse<ResponseDocument, string>
res: GenericResponse<ResponseDocument, string>,
) => {
try {
const { talentId } = req.params;
Expand All @@ -106,10 +106,11 @@ export const getOfferByTalent = async <T>(
}
};


// get offer by employerId
export const getOfferByEmployer = async <T>(
req: GenericRequest<T>,
res: GenericResponse<ResponseDocument, string>
res: GenericResponse<ResponseDocument, string>,
) => {
try {
const { employerId } = req.params;
Expand Down
2 changes: 1 addition & 1 deletion server/controllers/talentController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,4 @@ export const deleteTalent = async (
} catch (err) {
next(err);
}
};
};
1 change: 0 additions & 1 deletion server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ const PORT: number = 3000;
app.use(cors({ origin: true, credentials: true }));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(cors());

app.use('/employers', employerRoutes);
app.use('/offers', offerRoutes);
Expand Down
2 changes: 1 addition & 1 deletion server/interfaces/education.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ export interface Education {
export interface EducationResponse extends Education {
links?: Array<object>;
message?: string;
}
}
8 changes: 4 additions & 4 deletions server/test/routes/offers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ describe('test offer endpoints', () => {

const offer = new OfferModel(offerData);
await offer.save();
});
}, 10000);
beforeEach(async () => {
app = express();
await app.use(express.json());
await app.use('/offers', offerRoutes);
});
}, 10000);
afterAll(async () => {
await dropDB();
await disconnectDB();
});
}, 10000);

it('test get all offers /offers', async () => {
const res: GenericResponse<ResponseDocument, string> =
Expand All @@ -40,5 +40,5 @@ describe('test offer endpoints', () => {
expect(JSON.parse(res.text)).toHaveProperty('links');
expect(JSON.parse(res.text)['offers']).toBeInstanceOf(Array);
expect(JSON.parse(res.text)['offers'][0]).toHaveProperty('_id');
});
}, 10000);
});
Loading

0 comments on commit 5a553ea

Please sign in to comment.