111 lines
3.5 KiB
TypeScript
111 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import { useParams } from "next/navigation";
|
|
import { useEffect } from "react";
|
|
import Link from "next/link";
|
|
import Header from "@/components/shared/layout/header/Header";
|
|
import JobSingle from "@/components/pages/career/JobSingle";
|
|
import Footer from "@/components/shared/layout/footer/Footer";
|
|
import CareerScrollProgressButton from "@/components/pages/career/CareerScrollProgressButton";
|
|
import CareerInitAnimations from "@/components/pages/career/CareerInitAnimations";
|
|
import { useJob } from "@/lib/hooks/useCareer";
|
|
import { generateCareerMetadata } from "@/lib/seo/metadata";
|
|
|
|
const JobPage = () => {
|
|
const params = useParams();
|
|
const slug = params?.slug as string;
|
|
const { job, loading, error } = useJob(slug);
|
|
|
|
// Update metadata dynamically for client component
|
|
useEffect(() => {
|
|
if (job) {
|
|
const metadata = generateCareerMetadata(job);
|
|
const title = typeof metadata.title === 'string' ? metadata.title : `Career - ${job.title} | GNX Soft`;
|
|
document.title = title;
|
|
|
|
// Update meta description
|
|
let metaDescription = document.querySelector('meta[name="description"]');
|
|
if (!metaDescription) {
|
|
metaDescription = document.createElement('meta');
|
|
metaDescription.setAttribute('name', 'description');
|
|
document.head.appendChild(metaDescription);
|
|
}
|
|
const description = typeof metadata.description === 'string' ? metadata.description : `Apply for ${job.title} at GNX Soft. ${job.location || 'Remote'} position.`;
|
|
metaDescription.setAttribute('content', description);
|
|
|
|
// Update canonical URL
|
|
let canonical = document.querySelector('link[rel="canonical"]');
|
|
if (!canonical) {
|
|
canonical = document.createElement('link');
|
|
canonical.setAttribute('rel', 'canonical');
|
|
document.head.appendChild(canonical);
|
|
}
|
|
canonical.setAttribute('href', `${window.location.origin}/career/${job.slug}`);
|
|
}
|
|
}, [job]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="tp-app">
|
|
<Header />
|
|
<main>
|
|
<section className="pt-120 pb-120">
|
|
<div className="container">
|
|
<div className="row">
|
|
<div className="col-12 text-center">
|
|
<h2>Loading job details...</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
<Footer />
|
|
<CareerScrollProgressButton />
|
|
<CareerInitAnimations />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (error || !job) {
|
|
return (
|
|
<div className="tp-app">
|
|
<Header />
|
|
<main>
|
|
<section className="pt-120 pb-120">
|
|
<div className="container">
|
|
<div className="row">
|
|
<div className="col-12 text-center">
|
|
<h2 className="text-danger">Job Not Found</h2>
|
|
<p className="mt-24">
|
|
The job position you are looking for does not exist or is no longer available.
|
|
</p>
|
|
<Link href="/career" className="btn mt-40">
|
|
View All Positions
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
<Footer />
|
|
<CareerScrollProgressButton />
|
|
<CareerInitAnimations />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="tp-app">
|
|
<Header />
|
|
<main>
|
|
<JobSingle job={job} />
|
|
</main>
|
|
<Footer />
|
|
<CareerScrollProgressButton />
|
|
<CareerInitAnimations />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default JobPage;
|