Skip to content

Commit

Permalink
Merge pull request #122 from spryker-community/jobs-slug
Browse files Browse the repository at this point in the history
Updated job urls to show names instead of id #
  • Loading branch information
gxjansen authored Oct 24, 2024
2 parents 7683b5a + b186cd1 commit 9c87205
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 11 deletions.
11 changes: 7 additions & 4 deletions src/components/FreelancerCard.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
import { Image } from 'astro:assets';
import type { ImageMetadata } from 'astro';
import { getFlagEmoji, hasSprykerCertifications } from '../utils/utils.js';
import { getFlagEmoji, hasSprykerCertifications, generateNameSlug } from '../utils/utils.js';
const { freelancer } = Astro.props;
import { Icon } from 'astro-icon/components'; // social icons
import CQIcon from '@components/ui/icons/CQIcon.astro';
Expand Down Expand Up @@ -35,6 +35,9 @@ async function getFreelancerImage(photoPath: string) {
}
}
// Generate the URL-friendly slug for the freelancer
const freelancerSlug = generateNameSlug(freelancer.firstName, freelancer.lastName);
// Construct the correct image path
const imagePath = `/src/images/freelancers/${freelancer.photo}`;
Expand All @@ -54,7 +57,7 @@ const freelancerImage: ImageMetadata | undefined = imageFiles[imagePath];
</style>

<div class="bg-neutral-100 dark:bg-white/[.075] rounded-xl shadow-md overflow-hidden mb-10">
<a href={`/jobs/${freelancer.id}`}>
<a href={`/jobs/${freelancerSlug}`}>
{freelancerImage ? (
<Image
src={freelancerImage}
Expand All @@ -70,7 +73,7 @@ const freelancerImage: ImageMetadata | undefined = imageFiles[imagePath];
)}
</a>
<div class="p-6">
<a href={`/jobs/${freelancer.id}`} class="group"> <!-- Added group for hover effect -->
<a href={`/jobs/${freelancerSlug}`} class="group"> <!-- Added group for hover effect -->
<h2 class="text-2xl font-semibold mb-2 text-blue-500 dark:text-blue-400 group-hover:text-blue-600 dark:group-hover:text-blue-300 transition-colors">
{`${freelancer.firstName} ${freelancer.lastName}`}
</h2>
Expand Down Expand Up @@ -116,7 +119,7 @@ const freelancerImage: ImageMetadata | undefined = imageFiles[imagePath];
</div>
)}
<div class="mt-0 grid w-full gap-3 sm:inline-flex">
<SecondaryCTA title={`View ${freelancer.firstName}'s job profile`} url={`/jobs/${freelancer.id}`} />
<SecondaryCTA title={`View ${freelancer.firstName}'s job profile`} url={`/jobs/${freelancerSlug}`} />
</div>
</div>
</div>
1 change: 1 addition & 0 deletions src/pages/jobs.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import FreelancerCard from '../components/FreelancerCard.astro';
import freelancers from '../data_files/freelancers.json';
import PrimaryCTA from "@components/ui/buttons/PrimaryCTA.astro";
import type { Freelancer } from '../types.ts';
import { generateNameSlug } from '../utils/utils.js';
const pageTitle = "Available Spryker Developers";
Expand Down
23 changes: 17 additions & 6 deletions src/pages/jobs/[id].astro → src/pages/jobs/[slug].astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import MainLayout from '../../layouts/MainLayout.astro';
import MainSection from "../../components/ui/blocks/MainSection.astro";
import freelancers from '../../data_files/freelancers.json';
import { generateNameSlug } from '../../utils/utils.js';
import { Image } from 'astro:assets';
import type { ImageMetadata } from 'astro';
import { getFlagEmoji, hasSprykerCertifications } from '../../utils/utils.js';
Expand All @@ -16,10 +17,16 @@ const imageFiles: Record<string, ImageMetadata> = import.meta.glob('/src/images/
});
export function getStaticPaths() {
return freelancers.filter(freelancer => freelancer.isVisible).map((freelancer) => ({
params: { id: freelancer.id.toString() },
props: { freelancer }
}));
return freelancers
.filter(freelancer => freelancer.isVisible)
.map((freelancer) => {
// Generate slug from name
const slug = generateNameSlug(freelancer.firstName, freelancer.lastName);
return {
params: { slug }, // Use slug instead of id
props: { freelancer }
};
});
}
const { freelancer } = Astro.props;
Expand All @@ -34,15 +41,19 @@ const imagePath = `/src/images/freelancers/${freelancer.photo}`;
// Get the image from our glob
const freelancerImage: ImageMetadata | undefined = imageFiles[imagePath];
//Get slug
const freelancerSlug = generateNameSlug(freelancer.firstName, freelancer.lastName);
---

<MainLayout
title={pageTitle}
structuredData={{
"@context": "https://schema.org",
"@type": "ProfilePage",
"@id": `https://commercequest.space/jobs/${freelancer.id}/`,
"url": `https://commercequest.space/jobs/${freelancer.id}/`,
"@id": `https://commercequest.space/jobs/${freelancerSlug}/`,
"url": `https://commercequest.space/jobs/${freelancerSlug}/`,
"name": `${`${freelancer.firstName} ${freelancer.lastName}`} - Spryker Developer Profile | CommerceQuest`,
"description": `${freelancer.shortPitch}`,
"isPartOf": {
Expand Down
19 changes: 18 additions & 1 deletion src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,26 @@ function hasSprykerCertifications(certifications: SprykerCertifications): boolea
return certifications.backEndDeveloper || certifications.solutionArchitect;
}

// Generate URL-friendly slug from first and last name
function generateNameSlug(firstName: string, lastName: string): string {
// Combine first and last name, convert to lowercase, replace spaces with hyphens
// Remove special characters and normalize to basic Latin characters
const normalizedName = `${firstName} ${lastName}`
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '') // Remove diacritics
.replace(/[^a-z0-9\s-]/g, '') // Remove special characters
.trim()
.replace(/\s+/g, '-'); // Replace spaces with hyphens

return normalizedName;
}

// Export the new function along with existing ones
export {
formatDate,
capitalize,
getFlagEmoji,
hasSprykerCertifications
hasSprykerCertifications,
generateNameSlug
};

0 comments on commit 9c87205

Please sign in to comment.