From 3914c3ba57561ec44f23607826776dada68c7143 Mon Sep 17 00:00:00 2001 From: ahmedriad1 Date: Wed, 25 Sep 2024 17:15:01 +0300 Subject: [PATCH] update genre to show localized name --- prisma/schema.prisma | 14 +++++- .../genre/[genreSlug]/opengraph-image.tsx | 9 +++- .../(entityPages)/genre/[genreSlug]/page.tsx | 10 ++++- .../_components/content-tab/index.tsx | 5 ++- src/components/genres-filter/client.tsx | 11 ++++- src/server/services/books.ts | 4 +- src/server/services/genres.ts | 44 ++++++++++++++----- 7 files changed, 76 insertions(+), 21 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index c075c9f7..d74c4fec 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -102,12 +102,24 @@ model BookOtherNames { model Genre { id String @id slug String @unique - name String + + nameTranslations GenreName[] + transliteration String? numberOfBooks Int @default(0) books Book[] } +model GenreName { + locale String + text String + + genreId String + genre Genre @relation(fields: [genreId], references: [id], onDelete: Cascade, onUpdate: Cascade) + + @@id([genreId, locale]) +} + enum LocationType { Died Born diff --git a/src/app/[locale]/(entityPages)/genre/[genreSlug]/opengraph-image.tsx b/src/app/[locale]/(entityPages)/genre/[genreSlug]/opengraph-image.tsx index 5d6c197a..9a47421d 100644 --- a/src/app/[locale]/(entityPages)/genre/[genreSlug]/opengraph-image.tsx +++ b/src/app/[locale]/(entityPages)/genre/[genreSlug]/opengraph-image.tsx @@ -3,6 +3,7 @@ import { loadFileOnEdge } from "@/lib/edge"; import { notFound } from "next/navigation"; import { ImageResponse } from "next/og"; import { findGenreBySlug } from "@/server/services/genres"; +import { getPrimaryLocalizedText } from "@/server/db/localization"; export const runtime = "edge"; @@ -30,10 +31,12 @@ export async function generateImageMetadata({ const genre = await findGenreBySlug(genreSlug); if (!genre) return []; + const primaryText = getPrimaryLocalizedText(genre.nameTranslations, "en"); + return [ { id: "main", - alt: genre.name, + alt: primaryText, contentType: "image/png", size, }, @@ -51,6 +54,8 @@ export default async function Image({ notFound(); } + const primaryText = getPrimaryLocalizedText(genre.nameTranslations, "en"); + // Font const [calSans, family] = await Promise.all([ loadFileOnEdge.asArrayBuffer(fonts.calSans), @@ -71,7 +76,7 @@ export default async function Image({ fontFamily: "Cal Sans", }} > - {genre.name} + {primaryText} {/*

import("@/components/year-filter"), { ssr: false, @@ -28,10 +30,13 @@ export const generateMetadata = async ({ const genre = await findGenreBySlug(genreSlug); if (!genre) return; + const locale = await getPathLocale(); + const primaryText = getPrimaryLocalizedText(genre.nameTranslations, locale); + return getMetadata({ hasImage: true, pagePath: navigation.genres.bySlug(genreSlug), - title: genre.name, + title: primaryText, }); }; @@ -41,6 +46,7 @@ async function GenrePage({ routeParams: { genreSlug }, searchParams, }: GenrePageProps) { + const locale = await getPathLocale(); const genre = await findGenreBySlug(decodeURIComponent(genreSlug)); if (!genre) { @@ -63,7 +69,7 @@ async function GenrePage({ }, }); - const primaryName = genre.name; + const primaryName = getPrimaryLocalizedText(genre.nameTranslations, locale); const secondaryName = null; return ( diff --git a/src/app/[locale]/t/[bookId]/_components/content-tab/index.tsx b/src/app/[locale]/t/[bookId]/_components/content-tab/index.tsx index 7a15f232..d074a2cd 100644 --- a/src/app/[locale]/t/[bookId]/_components/content-tab/index.tsx +++ b/src/app/[locale]/t/[bookId]/_components/content-tab/index.tsx @@ -321,7 +321,10 @@ export default function ContentTab({ bookResponse }: TabProps) { variant="secondary" className="font-normal" > - {genre.name} + {getPrimaryLocalizedText( + genre.nameTranslations, + pathLocale, + )} ))} diff --git a/src/components/genres-filter/client.tsx b/src/components/genres-filter/client.tsx index 37efa44a..03009bb6 100644 --- a/src/components/genres-filter/client.tsx +++ b/src/components/genres-filter/client.tsx @@ -8,6 +8,8 @@ import FilterContainer from "@/components/search-results/filter-container"; import { useSearchParams, type ReadonlyURLSearchParams } from "next/navigation"; import { useFormatter, useTranslations } from "next-intl"; import type { findAllGenresWithBooksCount } from "@/server/services/genres"; +import { getPrimaryLocalizedText } from "@/server/db/localization"; +import { usePathLocale } from "@/lib/locale/utils"; const DEBOUNCE_DELAY = 300; @@ -50,6 +52,7 @@ export default function _GenresFilter({ const { replace } = useRouter(); const searchParams = useSearchParams(); const [size, setSize] = useState(10); + const locale = usePathLocale(); const genreIdToGenreName = useMemo(() => { return Object.fromEntries(genres.map((item) => [item.id, item])); @@ -152,7 +155,11 @@ export default function _GenresFilter({ // const count = genreIdToBooksCount[genre.genreId.toLowerCase()] ?? 0; const booksCount = formatter.number(genre._count.books); - const title = `${genre.name} (${booksCount})`; + const primaryText = getPrimaryLocalizedText( + genre.nameTranslations, + locale, + ); + const title = `${primaryText} (${booksCount})`; return ( handleChange(genre.id)} > - {genre.name} + {primaryText} ); })} diff --git a/src/server/services/books.ts b/src/server/services/books.ts index da365171..faf02120 100644 --- a/src/server/services/books.ts +++ b/src/server/services/books.ts @@ -43,7 +43,9 @@ const getBook = async (id: string, locale: string) => { bioTranslations: localeWhere, }, }, - genres: true, + genres: { + include: { nameTranslations: localeWhere }, + }, primaryNameTranslations: localeWhere, otherNameTranslations: localeWhere, }, diff --git a/src/server/services/genres.ts b/src/server/services/genres.ts index 4d2818cc..9465cd4a 100644 --- a/src/server/services/genres.ts +++ b/src/server/services/genres.ts @@ -3,35 +3,54 @@ import { cache } from "react"; import { db } from "../db"; import { unstable_cache } from "next/cache"; +import { PathLocale } from "@/lib/locale/utils"; +import { getLocaleWhereClause } from "../db/localization"; -export const findAllGenres = cache(async () => { - return await db.genre.findMany(); -}); +export const findAllGenres = cache(async (locale: PathLocale = "en") => { + const localeWhere = getLocaleWhereClause(locale); -export const findGenreBySlug = cache(async (slug: string) => { - const genreRecord = await db.genre.findUnique({ - where: { - slug, + return await db.genre.findMany({ + include: { + nameTranslations: localeWhere, }, }); +}); - if (!genreRecord) { - return; - } +export const findGenreBySlug = cache( + async (slug: string, locale: PathLocale = "en") => { + const localeWhere = getLocaleWhereClause(locale); - return genreRecord; -}); + const genreRecord = await db.genre.findUnique({ + where: { + slug, + }, + include: { + nameTranslations: localeWhere, + }, + }); + + if (!genreRecord) { + return; + } + + return genreRecord; + }, +); export const findAllGenresWithBooksCount = cache( async ({ yearRange, authorId, regionId, + locale = "en", }: { yearRange?: [number, number]; authorId?: string; regionId?: string; + locale?: PathLocale; } = {}) => { + const localeWhere = getLocaleWhereClause(locale); + const base = await db.genre.findMany({ include: { _count: { @@ -64,6 +83,7 @@ export const findAllGenresWithBooksCount = cache( }, }, }, + nameTranslations: localeWhere, }, });