Adding Job Type Filtering

ExamPro Markdown Lab Part 3
This is part of the ExamPro Next.js course. Additional content will be added to this lab, such as pagination and job type filtering.
In this lab, we will be adding the job type filtering feature to the existing application
Filter by Job Type: All, Full-Time, Part-Time Feature
localhost:3000/jobs/type/full-time
  • Create pages/jobs/type/[type_name].js

  • Import the following

  • import { promises as fs } from 'fs';
    import path from 'path';
    import matter from 'gray-matter';
    
    import Job from '@/components/jobs/Job';
    import JobsHeader from '@/components/jobs/JobsHeader';
    import Layout from '@/components/Layout';
  • Create the getStaticPaths() function
  • export async function getStaticPaths() {
      // Read from the /jobs directory
      const files = await fs.readdir(path.join('jobs'));
    
      const types = await Promise.all(
        files.map(async (filename) => {
          const markdown = await fs.readFile(path.join('jobs', filename), 'utf-8');
    
          const { data } = matter(markdown);
    
          // Return the job types in lowercase. Eg. 'full-time' instead of 'Full-Time'
          return data.type.toLowerCase();
        })
      );
    
      const paths = types.map((type) => ({
        params: { type_name: type },
      }));
    
      return {
        paths,
        fallback: false,
      };
    }
  • Create the getStaticProps() function
  • // This function takes the type_name from getStaticPaths()
    export async function getStaticProps({ params: { type_name } }) {
      // Read from /jobs directory
      const files = await fs.readdir(path.join('jobs'));
    
      // Map through jobs directory
      const jobs = await Promise.all(
        files.map(async (filename) => {
          // Set 'slug' to name of md file
          const slug = filename.replace('.md', '');
          // Read all markdown from file
          const markdown = await fs.readFile(path.join('jobs', filename), 'utf-8');
          // Extract data from markdown
          const { data } = matter(markdown);
    
          // return slug and data in an array
          return {
            slug,
            data,
          };
        })
      );
    
      // Maps through all the job types
      const types = jobs.map((job) => job.data.type);
      // Only take the unique job types
      const uniqueTypes = [...new Set(types)];
    
      const jobTypes = jobs.filter((job) => job.data.type.toLowerCase() === type_name);
    
      // return jobs, typeName, types
      return {
        props: {
          jobs: jobTypes,
          typeName: type_name,
          types: uniqueTypes,
        },
      };
    }
  • Create JobTypePostings() function
  • export default function JobTypePostings({ jobs, typeName }) {
      const jobType = typeName.replace(/(^|[\s-])\S/g, function (match) {
        return match.toUpperCase();
      });
    
      return (
        <Layout title="Jobs | ExamPro">
          <JobsHeader jobType={jobType} />
          <div className="bg-white my-4 shadow overflow-hidden divide-y divide-gray-200 sm:rounded-md">
            <ul role="list" className="divide-y divide-gray-200">
              {/* Maps through each job */}
              {jobs.map((job, index) => (
                <Job key={index} job={job} />
              ))}
            </ul>
          </div>
        </Layout>
      );
    }
    Update the [page_index].js file
  • Import the JobsHeader component
  • import JobsHeader from '@/components/jobs/JobsHeader';
  • Replace the following lines
  • <div className="px-4 py-4 sm:px-6 md:flex md:items-center md:justify-between">
      <div className="flex-1 min-w-0">
        <h2 className="text-2xl font-bold leading-7 text-gray-900 sm:text-3xl sm:truncate">
          Job Postings
        </h2>
      </div>
    </div>
    with
    <JobsHeader />

    40

    This website collects cookies to deliver better user experience

    Adding Job Type Filtering