DEV Community

Cover image for Hire+Plus! For Employees Here's how I built it (UI - Company)
AjeaS
AjeaS

Posted on

2 1

Hire+Plus! For Employees Here's how I built it (UI - Company)

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.

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;

Enter fullscreen mode Exit fullscreen mode

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 ...

import { useAppSelector } from '../../app/hooks';
import { truncateString } from '../../utils/truncateString';
Enter fullscreen mode Exit fullscreen mode

Functionality

get company state from companyReducer

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

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

export default ViewCompany;

Enter fullscreen mode Exit fullscreen mode

UI

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

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;

Enter fullscreen mode Exit fullscreen mode

Screenshots

about company

company jobs

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

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post →

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay