All files / app/jobs page.tsx

100% Statements 28/28
74.19% Branches 23/31
100% Functions 3/3
100% Lines 25/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107              1x     3x 3x           3x 1x               2x 3x   3x 3x 3x     3x         3x 3x 1x       2x 2x     2x                           3x       3x         2x     2x 1x     1x     1x                   1x                            
import fetchContentType from "@/lib/strapi/fetchContentType";
import JobBoardClient from "./JobBoardClient"; // ✅ Client component
import { generateMetadataObject } from '@/lib/metadata';
import { Metadata } from "next";
import { strapiImage } from "@/lib/strapi/strapiImage";
 
 
let heading: string = '', sub_heading: string = '', description: string = '';
 
export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
  const BASE_URL_NEXT = process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000";
  const pageData = await fetchContentType('jobs-page', {
    populate: ["seo","seo.metaImage"],
  }, true)
  //console.log("Job Page Data:", pageData); // Debugging output
 
  
  if (!pageData) {
    return {
      title: "Page Not Found | Bitmutex Technologies",
      description: "The requested page does not exist.",
      robots: "noindex, nofollow", // Avoid indexing non-existent pages
    };
  }
 
  
  const seo = pageData?.seo;
  const metadata = generateMetadataObject(seo);
 
  heading = pageData.heading;
  sub_heading = pageData.sub_heading;
  description = pageData.description;
 
  // ✅ Ensure title fallback to `pageData.title` if `seo.metaTitle` is missing
  const seotitle = seo?.metaTitle 
  ? `${seo.metaTitle}  | Careers at Bitmutex`
  : `${pageData.subheading || "Openings"} | Careers at Bitmutex`;
 
  // ✅ use pageData description as fallback if metaDescription is not available
  let seodescription = seo?.metaDescription || pageData.description || "";
  if (seodescription.length > 150) {
    seodescription = seodescription.substring(0, seodescription.lastIndexOf(" ", 150)) + "...";
  }
 
  // ✅ Override normal title field
  metadata.title = seotitle;
  metadata.description = seodescription;
 
  // ✅ Override OG fields
  metadata.openGraph = {
    ...(metadata.openGraph as any), // Cast to 'any' to allow unknown properties
    title: seotitle, 
    description: seodescription,
    images: seo?.metaImage
      ? [{ url: strapiImage(seo.metaImage.url) }]
      : { url: `${BASE_URL_NEXT}/bmcs.png` },
    
    url: `${BASE_URL_NEXT}/industries`, // Add custom URL field
    site_name: "Bitmutex",
    locale: "en_US",
    type: "website",
  };
    // ✅ Assign canonical URL to `alternates`
    metadata.alternates = {
      canonical: `${BASE_URL_NEXT}/industries`,
    };
  
  return metadata;
}
 
export default async function JobBoardPage() {
  // Fetch jobs from Strapi (SSR)
  const data = await fetchContentType("jobs", { populate: "*" });
 
  // Handle errors
  if (!data || !data.data) {
    return <p className="text-center text-red-500">Error: Unable to fetch job data.</p>;
  }
 
  console.log("Fetched Jobs Data:", data);
 
  // ✅ Map job data for rendering
  const jobs = data.data.map((job: any) => ({
    documentID: job.documentId,
    title: job.title || "Untitled Job",
    description: job.description || "No description available.",
    location: job.location || "Not specified",
    postedAt: job.createdAt || "Unknown date",
    experience: job.experience || "Not specified",
    deadline: job.deadline || "No deadline specified",
  }));
 
  return(
    
 
  <div className="text-center pt-20 mt-10">
      <span className="font-bold uppercase text-primary tracking-wide">{heading}</span>
      <h2 className="font-heading text-4xl font-bold text-gray-900 dark:text-white mt-2">{sub_heading}</h2>
      <p className="text-lg text-muted-foreground mt-3 max-w-xl mx-auto pb-4">
      {description}
      </p>
      <JobBoardClient initialJobs={jobs} />
  </div>
 
); 
}