Hire+Plus! For Employees Here's how I built it (UI - Company)
Tags: react, webdev, programming, tutorial
Published: 2022-08-05 18:52:00

## Overview: All views and functionality related to the Company, all funcs called are coming from the `authSlice` reducer.

---

## Company Route Page
**inside `routes > company > company-page.tsx`**
imports that assist with components to render, and functions to call from `companyReducer`. `useParams` will be used to get the `id` of the company that's passed in the url. -> `company/:id` route. On mount, I fetch the appropriate company in DB by id. To clarify, when I fetch this data I set it to state.

```javascript
import { useEffect } from 'react';
import { useParams } from 'react-router';
import BeatLoader from 'react-spinners/BeatLoader';
import { getCompany } from '../../app/features/company/companySlice';
import { useAppDispatch, useAppSelector } from '../../app/hooks';
import ViewCompany from '../../components/company/view-company.component';

const CompanyPage = () => {
	const { id } = useParams();
	const dispatch = useAppDispatch();
	const { isLoading } = useAppSelector((state) => state.company);

	useEffect(() => {
		dispatch(getCompany(id));
	}, [id, dispatch]);
	return <>{isLoading ? <BeatLoader /> : <ViewCompany />}</>;
};

export default CompanyPage;

```

---

## View Company Component
**inside `components > company > view-company.component.tsx`**
I created a helper method `truncateString` for text that's too long. If text reaches max length it shows `...`

```javascript
import { useAppSelector } from '../../app/hooks';
import { truncateString } from '../../utils/truncateString';
```

### Functionality
get company state from `companyReducer`

```javascript
const ViewCompany = () => {
	const { company } = useAppSelector((state) => state.company);

	return ({/* removed for simplicity */});
};

export default ViewCompany;

```

### UI
In a nutshell, it renders company details(who they are, location, hiring, etc.), along with the jobs they posted.

```javascript
const ViewCompany = () => {
	const { company } = useAppSelector((state) => state.company);
	return (
		<>
			<section style={{ backgroundColor: '#252731' }} className="mb-3">
				<div className="container mx-auto py-5 px-5 md:px-0 text-right text-white flex justify-between">
					<div className="flex justify-center text-md text-slate-200">
						{company.isHiring ? (
							<p>We are hiring!</p>
						) : (
							<p>Not hiring at the moment</p>
						)}
					</div>
				</div>
				<div className="md:px-12 lg:px-24 max-w-7xl relative items-center w-full px-5 py-5 mx-auto">
					<div className="mx-auto flex flex-col w-full max-w-lg mb-12 text-center">
						<p className="mb-5 font-medium text-2xl text-white">
							{company.companyName}
						</p>
						<img
							alt="testimonial"
							className="inline-block object-cover object-center w-20 h-20 mx-auto mb-8 rounded-full"
							src="https://picsum.photos/200"
						/>
						<div className="flex justify-center">
							{company.companyUrl ? (
								<a
									href={company.companyUrl}
									className="text-base leading-relaxed text-indigo-500 border-r-2 border-gray-500 pr-2"
								>
									Company Website
								</a>
							) : null}
							{company.companySize ? (
								<p className="text-base leading-relaxed font-color pl-2">
									Company size: {company.companySize}
								</p>
							) : null}
						</div>
					</div>
				</div>
			</section>
			<ul
				className="nav nav-tabs flex flex-col md:flex-row flex-wrap list-none border-b-0 pl-0 mb-4 text-white"
				id="tabs-tabFill"
				role="tablist"
			>
				<li className="nav-item flex-auto text-center" role="presentation">
					<a
						href="#tabs-homeFill"
						className="
								nav-link
								w-full
								block
								font-medium
								text-sm
								leading-tight
								uppercase
								border-x-0 border-t-0 border-b-2 border-transparent
								px-6
								py-3
								my-2
								hover:border-transparent hover:bg-transparent
								focus:border-transparent
								active
								"
						id="tabs-home-tabFill"
						data-bs-toggle="pill"
						data-bs-target="#tabs-homeFill"
						role="tab"
						aria-controls="tabs-homeFill"
						aria-selected="true"
					>
						About the company
					</a>
				</li>
				<li className="nav-item flex-auto text-center" role="presentation">
					<a
						href="#tabs-profileFill"
						className="
								nav-link
								w-full
								block
								font-medium
								text-sm
								leading-tight
								uppercase
								border-x-0 border-t-0 border-b-2 border-transparent
								px-6
								py-3
								my-2
								hover:border-transparent hover:bg-transparent
								focus:border-transparent
								"
						id="tabs-profile-tabFill"
						data-bs-toggle="pill"
						data-bs-target="#tabs-profileFill"
						role="tab"
						aria-controls="tabs-profileFill"
						aria-selected="false"
					>
						Jobs Posted
					</a>
				</li>
			</ul>
			<div className="tab-content font-color" id="tabs-tabContentFill">
				<div
					className="tab-pane fade show active w-full max-w-4xl"
					id="tabs-homeFill"
					role="tabpanel"
					aria-labelledby="tabs-home-tabFill"
				>
					<p className="text-md px-10">{company.companyDescription}</p>
				</div>
				<div
					className="tab-pane fade"
					id="tabs-profileFill"
					role="tabpanel"
					aria-labelledby="tabs-profile-tabFill"
				>
					{company.jobs.length ? (
						<section className="text-gray-600 body-font">
							<div className="container py-5 mx-auto">
								<div className="flex flex-wrap -m-4">
									{company.jobs.map((job, index) => {
										return (
											<div className="p-4 md:w-1/2 w-full" key={index}>
												<div className="h-full secondary-bg-color p-8 rounded">
													<h2 className="mb-3 text-indigo-500">
														<a href={job.applyUrl}>APPLY FOR JOB</a>
													</h2>
													<p className="leading-relaxed mb-6 font-color">
														{truncateString(job.description, 250)}
													</p>

													<span className="flex-grow flex flex-col">
														<span className="title-font font-medium text-white">
															{job.position}
														</span>
														<div className="flex font-color">
															<span className="text-sm">
																{job.location.toUpperCase()}
															</span>
															<span className="text-sm mx-2">
																{job.jobType.toUpperCase()}
															</span>
															<span className="text-sm">
																${job.salary.toUpperCase()}
															</span>
														</div>
													</span>
												</div>
											</div>
										);
									})}
								</div>
							</div>
						</section>
					) : (
						<p className="text-md">No Jobs posted </p>
					)}
				</div>
			</div>
		</>
	);
};

export default ViewCompany;

```

### Screenshots

![about company](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/srcmtjhrj4aqubwdi51a.png)

![company jobs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x7x4fa836edh8ack4dnl.png)

That's all for the UI/Company portion of the project, stay tuned!