feat(i18n): add localized navigation and news translations
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
updatePostInputSchema,
|
||||
} from "@cms/content"
|
||||
import { type CrudAuditHook, type CrudMutationContext, createCrudService } from "@cms/crud"
|
||||
import { z } from "zod"
|
||||
import type { Post } from "../prisma/generated/client/client"
|
||||
|
||||
import { db } from "./client"
|
||||
@@ -35,6 +36,15 @@ const postRepository = {
|
||||
}),
|
||||
}
|
||||
|
||||
const supportedLocaleSchema = z.enum(["de", "en", "es", "fr"])
|
||||
const upsertPostTranslationInputSchema = z.object({
|
||||
postId: z.string().uuid(),
|
||||
locale: supportedLocaleSchema,
|
||||
title: z.string().min(3).max(180),
|
||||
excerpt: z.string().max(320).nullable().optional(),
|
||||
body: z.string().min(1),
|
||||
})
|
||||
|
||||
const postAuditHooks: Array<CrudAuditHook<Post>> = []
|
||||
|
||||
const postCrudService = createCrudService({
|
||||
@@ -73,6 +83,100 @@ export async function getPostBySlug(slug: string) {
|
||||
})
|
||||
}
|
||||
|
||||
export async function getPostBySlugForLocale(slug: string, locale: string) {
|
||||
const normalizedLocale = supportedLocaleSchema.safeParse(locale).data
|
||||
const post = await db.post.findUnique({
|
||||
where: { slug },
|
||||
include: {
|
||||
translations: normalizedLocale
|
||||
? {
|
||||
where: {
|
||||
locale: normalizedLocale,
|
||||
},
|
||||
take: 1,
|
||||
}
|
||||
: false,
|
||||
},
|
||||
})
|
||||
|
||||
if (!post) {
|
||||
return null
|
||||
}
|
||||
|
||||
const translation = post.translations?.[0]
|
||||
|
||||
return {
|
||||
...post,
|
||||
title: translation?.title ?? post.title,
|
||||
excerpt: translation?.excerpt ?? post.excerpt,
|
||||
body: translation?.body ?? post.body,
|
||||
}
|
||||
}
|
||||
|
||||
export async function listPostsForLocale(locale: string) {
|
||||
const normalizedLocale = supportedLocaleSchema.safeParse(locale).data
|
||||
const posts = await db.post.findMany({
|
||||
where: {
|
||||
status: "published",
|
||||
},
|
||||
orderBy: {
|
||||
updatedAt: "desc",
|
||||
},
|
||||
include: {
|
||||
translations: normalizedLocale
|
||||
? {
|
||||
where: { locale: normalizedLocale },
|
||||
take: 1,
|
||||
}
|
||||
: false,
|
||||
},
|
||||
})
|
||||
|
||||
return posts.map((post) => {
|
||||
const translation = post.translations?.[0]
|
||||
|
||||
return {
|
||||
...post,
|
||||
title: translation?.title ?? post.title,
|
||||
excerpt: translation?.excerpt ?? post.excerpt,
|
||||
body: translation?.body ?? post.body,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function listPostsWithTranslations() {
|
||||
return db.post.findMany({
|
||||
orderBy: {
|
||||
updatedAt: "desc",
|
||||
},
|
||||
include: {
|
||||
translations: {
|
||||
orderBy: [{ locale: "asc" }],
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export async function upsertPostTranslation(input: unknown) {
|
||||
const payload = upsertPostTranslationInputSchema.parse(input)
|
||||
const { postId, locale, ...data } = payload
|
||||
|
||||
return db.postTranslation.upsert({
|
||||
where: {
|
||||
postId_locale: {
|
||||
postId,
|
||||
locale,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
postId,
|
||||
locale,
|
||||
...data,
|
||||
},
|
||||
update: data,
|
||||
})
|
||||
}
|
||||
|
||||
export async function createPost(input: unknown, context?: CrudMutationContext) {
|
||||
return postCrudService.create(input, context)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user