To start this app run
npm install
And then run
npm run dev
# or
yarn dev
Open http://localhost:3000
to display it in the browser
axios
for api calls.
dotenv
for environment variables.
moment
for working on time/date.
react-icons
for different icons.
react-linkify
this is used to wrap a text/paragraph to detect links and automatically adding anchor tags to those links. It is used in job description.
sass
this dependency allows using sass directly to react without compiling sass to css.
-
index.js
Landing page, consists of the following components/components/home/hero/Hero.js
displays the introductory header and paragraph along with the search bars that redirects to jobs page./components/jobs_template/Jobs.js
showcases the jobs for landing page and jobs page. (more explanations on components details)/components/home/companies/Companies.js
contains a list of some available companies and the number of jobs the company have posted.
-
jobs.js
Displays list of all jobs available. consists of the following components./components/filter_hero/Hero.js
this is used for both jobs and companies pages to display different filters for searching either jobs or companies./components/jobs_template/Jobs
showcases jobs and it is used also in landing page expept here it also shows different filter criterias as entered by user in/components/filter_hero/Hero.js
component.
-
companies.js
Displays the list of all verified companies available. consists of/components/filter_hero/Hero.js
more descriptions in components part/components/template/Template.js
this returns a general layout for landing, jobs, companies, about, pages and other pages, takes in a heading(primary heading) and childrens(whatever components can be added as a child in its parent component)./components/company/Company.js
the company card for mapped inside the main companies page./components/loaders/ButtonLoader.js
for displaying spinner while fetching more companies/components/newsletter/NewsLetter.js
for displaying subscribe form
-
company.js
displays profile of authenticated company i.e. the company that is current logged in and returns 404 not found component when no company is logged in. It consists of/components/profile_template/Profile_Template.js
this components uses props to display different profile informations of various users. (more explainations on the component part)./components/error/Error.js
this return 404 page error when no company is authenticated.
-
profile.js
displays profile of authenticated user i.e. the user that is current logged in and returns 404 not found component when no user is logged in. It consists of/components.profile_template/Profile_Template.js
this components uses props to display different profile informations of various users. (more explainations on the component part)./components/error/Error.js
this return 404 page error when no user is authenticated.
-
404.js
displays page not found error when user visits a route that is not in the pages list i.ehttp://localhost:3000/page-not-listed
will return this page. it consists of/components/error/Error.js
-
register.js
page for registering users. it consists of/components/register/JobSeeker.js
for registering job seekers/components/register/Company.js
for registering companies
-
login.js
for authenticating users -
forgot_password
for when users forgets their password -
about.js
for displaying about jobportal info. contains/components/page_template/Page_Template.js
this contains a hero and a/components/template/Template.js
for normal pages i.e about, contact, help, terms and conditions etc and childrens for any content in the pages
-
contact.js
...refer to about page -
companies/'id].js
displays company with id [id] profile details. it employs the same waycompany.js
page works but for any company and doesnt require authentication -
profile/[id].js
displays user with id [id] profile details, this will only be accessible to an admin of job portal unless when the id is same to authenticated user id then it will display details as inprofile.js
page
auth.js
deals with all the global state management for authenticated user, when the login, update profile, logout etc.alerts.js
deals with global state managements for alerts when user successfully signed in, logged in, uploaded profile, etc
These are hardcoded data that were userd accross the app as a placeholders to the data coming from the api
-
alerts/GlobalAlert.js
this is an alerts getting its data from alert context and will be displayed at the bottom center (fixed) of the page when a message to the alert is added/dispatched. it was imported inpages/_app.js
-
buttons/FormButton.js
this is a button that can be used in forms and it accepts several props ie
{
loading, //checks if its loading to display a spinner
text, //button text
btnClass, //either btn-primary or btn-secondary NB: any class passed as props need to be styles in global sass file
btnGroupClass
}
inputs/Input.js
this is an input that can be used in forms as input and accepts several props i.e
{
inputClass, // classname incase different stylings are required NB: any class passed as props need to be styles in global sass file
name, // name of the form. it is Required
id, // id for the htmlFor in the label
type, // type of the input ie can be text, email etc
placeholder, // input placeholder
value, // value of the input
handleChange, // handling onchange event of an input. it is Required
title, // title to display in the label of an input
error, // for displaying errors underneath an input (it changes the border color and add an error message at the bottom of the input if there is an error)
success, // does the same as an error just it is for success so the success colors all the way
textarea, // if true means the input is textarea and returns a textarea
}
-
rippleEffect.js
well a ripple effect for buttons (wave like effect when a button is clicked) -
UseClickOutside.js
custom hook for detecting if user has clicked outside an elements, it is used mostly for dropdowns -
Logo.js
custom logo image and accepts height of an image props. can be used whenever logo is needed -
error/Error.js
as explained in some pages it returns a page not found error with some good UI and call of actions when user wants to go back or go home -
loaders
different loaders to display when something's loading, ie some pre-rendered cards loader when jobs/ companies is are being fetched/AuthLoader.js
displays some pre-rendered components ie header, hero and template when user data are being fetched when user visits the page... this is to avoid sudden change of some components when user is loaded and authenticated/ButtonLoader.js
displays spinner in the button when user is has clicked some buttons that requires fetching to alert user that its fetching. it is alse used for loading more jobs and companies and/or can be used anywhere where a spinner is required. it accepts props
{ bg, // if bg="light" it means the spinner is in light background and changes the class which eventually changes the color of the spinner. default a spinner works on colored background/it is white }
/CardLoader.js
this prerenders cards when components that requires cards are loading. these components are Job card, company card. it accepts a prop
{ stars, // true or false it means displays stars loading or not the reason is the company card does not have stars and hence stars can be false while the job card has stars and hence will pass stars={true} as a prop }
/CpmpaniesLoader.js
in the landing page at the companies section this loader is user to prerender when fetching companies/Details.js
renders when job details are loading and is used in/pages/jobs/[id].js
/HeroLoader.js
prerenders hero component for profile(both companies and user profiles) pages and job details page when details are fetching/ProfileLoader.js
renders when user details are fetching and is used in main profile part of the profile(more explanations in/components/profile_template
part)
-
newsletter/NewsLetter.js
displays subscription form for unauthenticated users -
template/Template.js
is used for many pages to display main section of the page and also contains primary header and is responsible for the layout (ie in the page where jobs part and newsletter/related jobs part is displayed ) -
page_template/PageTemplate.js
is the component that uses/components/template/Template.js
component but also has its own hero fro the pages where hero doesn't have any content i.e about, contact etc -
register
contains two components to separate registering user/jobseeker and registering a company/JobSeeker.js
responsible for registering normal user/Job seeker/Company.js
responsible for registering a company
-
profile_template
is used to showcase user/companies profiles/ jobs/ applied jobs/ saved jobs/ edit profile items. The profile page has three main sections ->hero
,navigation
andmain-content
and uses tabs to switch between different contents/pages. these tabs looks like thishttp://localhost:3000/page_name?tab=tab_name
the value of tab ie tab_name is what returns the required contents.... more explanations below./Perofile_Template.js
is the entry component in the whole profile ecosystem. it takes in/components/profile_template/hero/Hero
to display a hero for some details and/components/profile_template/template/Template
to display the main profile details and takes two props ie
{ details, // profile details of either user or company/ both share some similar components page // page name ie page can be user (do indicate the profile is of user), auth-user (to indicate the profile is of authenticated user/ user who is currently logged in) or company (to indicate that the profile is of a company) }
/hero/Hero.js
displays some user/company details on the hero, takes indetails
andpage
as props/template/Template.js
takes indetails
andpage
as props and also its where we check if the profile is of authenticated user or company(in order to allow them to edit profile if its theirs as well as view their own private items likeapplied jobs
ofsaved jobs
). Two components are imported in this component which isAside
(navigation section of the profile) andDetails
(main content of the website), both takingdetails
andpage
,isUser
(true if profile is of the current logged in user) andisCompany
(true if the profile is of the current logged in company) as props/aside/Aside.js
as explained above this shows profile navigation and consist of route liketab=profile
- for profile details page,tab=edit-profile
available ifisUser
orisCompany
is true to allow users to edit their profiles,tab=jobs
available for companies only and works only whenpage="company"
,/dashboard
this ia available ifisCompany
is true or ifisUser
is true and user is anadmin
to take them to their dashboards which is another apps,tab=saved-jobs
andtab=applied-jobs
whenisUser
is true and works only whenpage="user/auth-user"
. the aside does not display at all whenisUser
andisCompany
are false and it is a user profile and only an admin can view user profile/Details.js
this works similar to aside where displays different contents deoending on the route clicked in the aside, the authentication status and the page ie, ifisUser
and page isuser
/auth-user
and the tab=edit-profile
it will display edit profile contents while ifisUser
is false it will just display the profile details of the user. so it takes in several components ie/components/profile_template/edit-profile/EditProfile.js
,/components/profile_template/edit-profile/Profile.js
,/components/profile_template/edit-profile/Jobs.js
,/components/profile_template/edit-profile/AppliedJobs.js
and/components/profile_template/edit-profile/SavedJobs.js
components./Section.js
this is the main template used by details components, takes in heading and children/profile/Profile.js
this displays profile information for any user/company, it takes indetails
props./jobs/Jobs.js
displays jobs added by a company. only works whentab=jobs
andpage=company
/jobs/AppliedJobs.js
displays jobs that user has applied and their status and only work whentab=applied-jobs
andisUser
is true otherwise returns/components/profile_template/profile/Profile.js
component/jobs/SavedJobs.js
displays jobs user has saved and works similar to the component above/edit-profile/EditProfile.js
this works ontab=edit-profile
and eitherisUser
orisCompany
is true otherwise returns/components/profile_template/profile/Profile.js
component. also it takes indetails
,isUser
andisCompany
props. it has two components,/components/profile_template/edit-profile/user/EditUser.js
and/components/profile_template/edit-profile/company/EditCompany.js
. the reason to separate these stuffs is user and company updates their profile to different destinations/ api routes just like we did in register. so ifisUser
is true then displaysEditUser
component and the other way around.NB
: bothisUser
andisCompany
can never be true at the same time, its either one of them true or both false./user/EditUser.js
edits user and takes in/edit-profile/Upload.js
to allow user to upload dp/profile photos,/edit-profile/CV.js
to allow user to upload their CVs,/settings/Settings.js
to allow users to update their core info like email, username and password while allowing users to update their basic infos inside the same component./company/EditCompany.js
workis exactly like/user/EditUser
except doesnt have upload CV section and in the settings doesnt have username settings ie companies dont have usernamesUpload.js
allows uploading dp/logos/user/CV.js
allows uploading CVs/settings/Settings.js
allow user to update their core info likeusername
,emails
andpassword
. updating each of these info reguires user to add his/her current login info to ensure its the user who is doing them changes even if user may be authenticated. this is because we may use unexpiring sessions/tokens and anyone can use users computer so just to make sure. it takes inUsername
,Email
andPassword
components./Username.js
,Email.js
,Password.js
as explained above these contains forms to update the infos and the UI part is the are arranged as accordions where user have to click the title to actually see the form so they require/Accordion.js
just to do that./Accordion.js
is used to toggle on and off the settings forms this is good to reduce the number of components visible at the same time in the settings part as having three forms at the same time actually can distract user so they must choose what they want to change, click them and boom the form appears before them
-
job
random jobs components used accross the app-
/Job.js
a job card to display some job details and is used in/components/jobs_template/Jobs.js
which is used in both/pages/index.js
and/pages/jobs.js
. It accepts props ie{ job: { id, title, company, created_at, close_date, close_time, job_type, location, reviews, } }
/JobDetails.js
display job details in the/pages/jobs/[id].js
page. it accepts props ie
{ job: { id, job_type, location, company, email, attachment, descriptions } }
/RelatedJobs.js
in/pages/jobs/[id].js
it displays three jobs which relates to the job with id [id]
-
-
company/Company
is a company card mapped in/pages/companies.js
and accepts props ie
{
id, logo, name, jobs // number of jobs added by the individual company
}
-
layout/Layout.js
it is the main layout for all pages expect/pages/login.js
,/pages/register.js
and/pages/forgot_password.js
. it is used to display/components/header/Header.js
at the top,/components/footer/Footer.js
at the bottom and whatever component props is passed in as children. it is imported in/pages/_app.js
and its where user data will be fetched hence/components/loaders/AuthLoader.js
will pre-render while fetchimg user data. This is to avoid fetching user data to the pages where this layout isn't users ielogin.js
-
header
/Header.js
is the main header of the app and is imported in/components/layout/Layout.js
. it displays the main navigation as well as some user data when user is authenticated/Profile.js
displays saome basic user data and some navigation to authenticated pages, shows when user is authenticated/Notifications.js
display user notifications and only showa when user is authenticated
-
home
contains components that are used in landing page only/hero/Hero.js
contains introductory heading and paragraph together with search bars which redirects to jobs page./companies/Companies.js
dispays a shortlist of companies in the landing page
-
filter_hero/Hero.js
this is used for both/pages/companies.js
and/pages/jobs
to display different search criteria. it has search inputs as well as mapping category filters/components/categories/Category.js
. it accepts accept props which issearch
andsetSearch
. search is a state declared in the individual page such as jobs page and setSearch is also a method declared in usestate to update search state. When user type in search bars it updates the state in this same component.
The reason to opt usestate instead of using global state is because these same components are used to update different states ie search state in jobs is different from that in companies page and they are used to call different data in the api although they share the same types of data ie search passed as props is declared as
{
keyword: "",
location: "",
categories: [],
}
-
categories
used to display different filters in/components/filter_hero/Hero.js
component/Category.js
this component is mapped in/components/filter_hero/Hero.js
and takes in the props ie search, setSearch (...refer to/components/filter_hero/Hero.js
component), category which has the following data
{ name, //category name sub_categories: [], // array of subcategories id, //category id }
these data are extracted from
/components/filter_hero/Hero.js
component where in that component categories are fetched from the api, the sub_category array is mapped in this component/SubCategory.js
is mapped from/components/categories/Category
and is used to display subcategories of the main category. it receives props such as
{ sub: { id, //sub_category id name, //sub_category name }, setSearch, // prop drilled from the main page search, // prop drilled from main page category: { id, //parent category id } }
In this component user is allowed to select/unselect any subcategory and the clicked subcategory is then added/removed in the search state, the main reason we have setSearch. search prop is used to update UI when user selects and unselect a sub_category by using custom checkbox(svg)
-
jobs_template/Jobs.js
this is used inindex.js
andjobs.js
to display jobs and other items. it accepts props which are
{
search,
setSearch, // refer to `/components/filter_hero/Hero.js`
heading, //to render different headings as per page
page // to render different items for different pages ie from jobs page the value passed is page="jobs"
}
it uses /components/template.Template.js
as the main template and pass childrens and heading as props. refer to /components/template.Template.js
it maps /components/job/Job.js
when jobs are available from the main page
it also uses /components/filter_criteria
to display different criterias in the /pages/jobs.js
page
-
filter_criteria
used to display different filter criterias in/pages/jobs.js
and/pages/companies.js
pages/FilterCriteria.js
this accepts search and setSearch props. setsearch is used to remove item/criteria from the state and search to display criteria in the browser. it displayskeyword
andlocation
criteria while maps categories to display category names. in each category it maps the/components/filter_criteria/FilterItem.js
to displays subcategories of each category. if none exists or have no value in search state it doesnt display nothing/FilterItem.js
it is mapped in the above component to display subcategories of each category with a function to remove the subcategory. if removed it update search state using setsearch and if all the subcategories are removed from a category it removes the category completely from the search state
-
footer
Most of the components are wrapped in the folders and contains their own css files. These files have .module.sass
extension. the global css files are placed in /styles
folder and are
1. `/global.sass`, this is the global css file and is imported in `/pages/_app.js`. contains all the global styles together with some components which starts with `_filename.sass`
2. `_filename.sass` these are components in sass ecosystem and can be imported in any sass file in order to use their styles/ varialbles or functions