Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/iDevRanjan/lws-ra-b4-assignment-five/llms.txt

Use this file to discover all available pages before exploring further.

LWS Job Portal gives job seekers a powerful, fast discovery experience from the moment they land on the home page. A full-width search bar sits above a rich filter panel, and as you type or adjust any filter, results refresh automatically — no page reloads required. Matching jobs stream in as cards, and scrolling toward the bottom of the list loads the next batch seamlessly, letting you browse hundreds of opportunities without ever leaving the page.

Home Page Job Discovery

The home page (/) is the central hub for browsing open positions. It combines a hero banner, a search-and-filter toolbar, a live results count header, and an infinite-scroll grid of job cards. The page is powered by React Query’s useInfiniteQuery, which fetches one page of results at a time and appends more pages to the list as you request them.

Search & Filter Jobs

Use keywords and filters to narrow down the jobs that matter to you.

View Your Applications

Track every application you have submitted and monitor status updates.

Search Bar with Debounced Input

The search input accepts any keyword — job title, company name, skill, or location. Rather than firing an API call on every keystroke, the useDebounce hook delays the network request by 300 ms after you stop typing. This prevents excessive requests and makes the experience feel smooth even on slow connections.
// src/hooks/useDebounce.js
import { useRef } from "react";

export function useDebounce(func, delay = 300) {
    const timeoutId = useRef(null);

    return function (...args) {
        if (timeoutId.current) {
            clearTimeout(timeoutId.current);
        }

        timeoutId.current = setTimeout(() => {
            func.apply(this, args);
            timeoutId.current = null;
        }, delay);
    };
}
The debounced function is consumed directly inside JobSearchAndFilter:
// Trigger query param regeneration only after typing stops
useDebounce(generateQueryPath, 300)();
The 300 ms default delay strikes a good balance between responsiveness and API efficiency. If you are self-hosting the portal and want snappier results on a fast local network, you can lower the delay value in useDebounce.

Filter Options

Below the search bar, the filter panel exposes five independent dropdowns. Each filter updates the query-string parameters, which are picked up by useInfiniteQuery and used to fetch a fresh, filtered page of results.

Category

Narrow results to a specific department or functional area.
LabelValue
EngineeringEngineering
DesignDesign
ProductProduct
MarketingMarketing
SalesSales
HRHR
FinanceFinance
OtherOther

Job Type (Employment Type)

Filter by how the position is structured.
LabelValue
Full timeFull-time
Part timePart-time
ContractContract
FreelanceFreelance
InternshipInternship
TemporaryTemporary

Work Mode

Filter by where the work takes place.
LabelValue
RemoteRemote
On-siteOn-site
HybridHybrid

Salary Range

Filter by expected annual compensation.
LabelValue
00 - 50k0 - 50000
50k50k - 100k50000 - 100000
100k100k - 150k100000 - 150000
$150k+150000

Skills

Filter jobs that require a specific skill. The predefined skill options available in the portal are:
Skill
React
Node.js
Python
TypeScript
The skills filter matches against the skills array stored on each job listing. A job is returned if any of the listed skills match your selected filter value.

Infinite Scroll

The home page fetches jobs one page at a time using useInfiniteQuery. When you reach the bottom of the current results, a Load More button appears (or the next page loads automatically) — the new batch is appended without clearing the existing cards.
const {
    data: allJobsData,
    isFetching,
    fetchNextPage,
    hasNextPage,
} = useInfiniteQuery(getAllJobsQueryOption(params));
  • fetchNextPage is called when you click Load More or reach the scroll threshold.
  • hasNextPage is false when the last page returned an empty data array, hiding the Load More control automatically.
  • When you change any filter or search term, the query key changes and the list resets to page 1, showing only relevant results from the start.

Job Cards

Every job in the grid is rendered as a card that surfaces the most important details at a glance:

Job Title & Company

The role name and the hiring company are shown prominently at the top of each card.

Location & Work Mode

Where the job is based and whether it is Remote, On-site, or Hybrid.

Employment Type & Salary

Full-time, Part-time, Contract, Freelance, Internship, or Temporary — plus the salary range.

Required Skills

A tag list of the skills the employer is looking for, so you can judge fit at a glance.
Clicking any job card navigates to /jobs/:jobSlug for the full job details.

Job Details Page

The job details page (/jobs/:jobSlug) is fetched via GET /api/jobs/:jobSlug and is laid out in a two-column grid — the main content on the left and an action sidebar on the right.

Main Content Sections

Displays the job title, hiring company name, office location, and employment type badge. The company logo is shown alongside the header information.
A quick-reference panel showing:
  • Number of vacancies available
  • Experience level required (e.g., Entry, Mid, Senior)
  • Application deadline — the date after which applications are no longer accepted
The full, formatted description written by the employer. This section covers the day-to-day responsibilities, team context, and any additional information about the role.
A tag cloud of skills the employer expects. Skills are stored as a string array on the job object and rendered as individual badges.
A list of jobs with related attributes, fetched from GET /api/jobs/:id/similar. This section appears below the main job content and helps you discover comparable opportunities without returning to the home page.
The right-hand sidebar contains:
  • Apply Now button (or Applied / Withdraw if you have already applied)
  • Company Info — a brief overview of the hiring company
  • Share Job — links to share the listing
  • Report this job — a flag button for inappropriate listings

Applying for a Job

1

Open the Job Details Page

From the home page, click on any job card. You will be taken to /jobs/:jobSlug where you can read the full description, requirements, and company information before deciding to apply.
2

Click Apply Now

In the right-hand sidebar, click the Apply Now button. If you are not logged in as a job seeker (role: USER), the portal will display a toast notification and redirect you to /login before proceeding.
3

Write Your Cover Letter

The Apply for Position dialog opens. Review your resume details displayed at the top — the portal uses the resume already uploaded to your profile. Then write a cover message (up to 500 characters) explaining why you are a great fit for the role. The character counter turns orange below 50 characters remaining and red below 10.
Field: coverLetter (required, max 500 characters)
The Submit Application button is disabled if you have not yet uploaded a resume to your profile. You must upload a resume at /edit-jobseeker-profile before you can apply to any job.
4

Submit the Application

Click Submit Application. The form data is sent to the API:
POST /api/applications/jobs/:jobId/apply
Body: { coverLetter: "..." }
On success, a toast notification confirms the submission and React Query invalidates the applications cache so status updates appear immediately.
5

Confirm the Applied State

After a successful submission, the Apply Now button in the sidebar changes state. You will see either an Applied indicator or a Withdraw button, confirming your application is on record. You cannot submit a duplicate application for the same job.
Only authenticated users with the USER role (job seekers) can apply for jobs. Company accounts (COMPANY role) do not see the Apply Now button.

When you are logged in as a job seeker, the dashboard (/jobseeker-dashboard) surfaces a Recommended for You section. Recommendations are personalised based on your profile skills and experience level and are fetched from:
GET /api/jobs/recommendations
The same recommendations widget also appears on the dashboard sidebar. Clicking any recommended job card takes you to the full job details page.

Similar Jobs

On any job details page, a Similar Jobs panel appears below the main content area. These are fetched lazily using a dependent query:
GET /api/jobs/:id/similar
Similar jobs share attributes such as category, work mode, or required skills with the job you are currently viewing.

Build docs developers (and LLMs) love