REFACTORED - Flatten portfolio category routes to /portfolio/[slug]
Merge the category and project routes under a single /portfolio/[slug] segment via resolvePortfolioSlug (category wins over project on a slug clash). Removes the /portfolio/category/... prefix from links, redirect, and sitemap. Adds resolver integration tests.
This commit is contained in:
@@ -285,6 +285,30 @@ export const getPublishedPortfolioProjectBySlug = cache(async function (slug: st
|
||||
return mapProject(project);
|
||||
});
|
||||
|
||||
export type ResolvedPortfolioSlug =
|
||||
| { kind: "category"; category: PortfolioCategoryView }
|
||||
| { kind: "project"; project: PortfolioProjectView }
|
||||
| null;
|
||||
|
||||
/**
|
||||
* Resolves a `/portfolio/[slug]` segment to either a category or a project.
|
||||
* Categories take precedence so `/portfolio/web` shows the category listing;
|
||||
* a project slug only wins when no active category shares that slug.
|
||||
*/
|
||||
export async function resolvePortfolioSlug(slug: string): Promise<ResolvedPortfolioSlug> {
|
||||
const category = await getActivePortfolioCategoryBySlug(slug);
|
||||
if (category) {
|
||||
return { kind: "category", category };
|
||||
}
|
||||
|
||||
const project = await getPublishedPortfolioProjectBySlug(slug);
|
||||
if (project) {
|
||||
return { kind: "project", project };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function getAdminPortfolioProjectById(id: string) {
|
||||
const project = await db.query.portfolioProject.findFirst({
|
||||
where: eq(portfolioProject.id, id),
|
||||
|
||||
Reference in New Issue
Block a user