From deb6ed7ec8fb24140c7a4502449adf7a4a364113 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Tue, 28 May 2024 15:55:19 -0400 Subject: [PATCH] code refactoring + add locale field to user table --- lib/client/getServerSideProps.ts | 64 +++++++++++++++++++ pages/admin.tsx | 56 +--------------- .../migration.sql | 2 + prisma/schema.prisma | 5 +- 4 files changed, 71 insertions(+), 56 deletions(-) create mode 100644 lib/client/getServerSideProps.ts create mode 100644 prisma/migrations/20240528194553_added_locale_field_for_users/migration.sql diff --git a/lib/client/getServerSideProps.ts b/lib/client/getServerSideProps.ts new file mode 100644 index 0000000..5f4027c --- /dev/null +++ b/lib/client/getServerSideProps.ts @@ -0,0 +1,64 @@ +import { GetServerSideProps } from "next"; +import { serverSideTranslations } from "next-i18next/serverSideTranslations"; +import { i18n } from "next-i18next.config"; +import { getToken } from "next-auth/jwt"; +import { prisma } from "../api/db"; + +// Keep this in a separate file, it's for logged out users +// For logged in users, we'll use their preferred language from the database (default: en) +const getServerSideProps: GetServerSideProps = async (ctx) => { + const acceptLanguageHeader = ctx.req.headers["accept-language"]; + const availableLanguages = i18n.locales; + + // Check if it's a logged in user + // If it is, get the user's preferred language from the database + const token = await getToken({ req: ctx.req }); + + if (token) { + const user = await prisma.user.findUnique({ + where: { + id: token.id, + }, + }); + + if (user) { + return { + props: { + ...(await serverSideTranslations(user.locale, ["common"])), + }, + }; + } + } + + // Parse the accept-language header to get an array of languages + const acceptedLanguages = acceptLanguageHeader + ?.split(",") + .map((lang) => lang.split(";")[0]); + + // Find the best match between the accepted languages and available languages + let bestMatch = acceptedLanguages?.find((lang) => + availableLanguages.includes(lang) + ); + + // If no direct match, find the best partial match + if (!bestMatch) { + acceptedLanguages?.some((acceptedLang) => { + const partialMatch = availableLanguages.find((lang) => + lang.startsWith(acceptedLang) + ); + if (partialMatch) { + bestMatch = partialMatch; + return true; + } + return false; + }); + } + + return { + props: { + ...(await serverSideTranslations(bestMatch ?? "en", ["common"])), + }, + }; +}; + +export default getServerSideProps; diff --git a/pages/admin.tsx b/pages/admin.tsx index 35e14ed..3341fb8 100644 --- a/pages/admin.tsx +++ b/pages/admin.tsx @@ -5,10 +5,7 @@ import { User as U } from "@prisma/client"; import Link from "next/link"; import { useEffect, useState } from "react"; import { useTranslation } from "next-i18next"; -import { GetServerSideProps } from "next"; -import { serverSideTranslations } from "next-i18next/serverSideTranslations"; -import { useRouter } from "next/router"; -import { i18n } from "next-i18next.config"; +import getServerSideProps from "@/lib/client/getServerSideProps"; interface User extends U { subscriptions: { @@ -24,8 +21,6 @@ type UserModal = { export default function Admin() { const { t } = useTranslation(); - const router = useRouter(); - const { users, setUsers } = useUserStore(); const [searchQuery, setSearchQuery] = useState(""); @@ -39,7 +34,6 @@ export default function Admin() { const [newUserModal, setNewUserModal] = useState(false); useEffect(() => { - console.log(router); setUsers(); }, []); @@ -183,50 +177,4 @@ const UserListing = ( ); }; -// Take this into a separate file, it's for logged out users -// For logged in users, we'll use their preferred language from the database (default: en) -export const getServerSideProps: GetServerSideProps = async (ctx) => { - console.log("CONTEXT", ctx); - - const acceptLanguageHeader = ctx.req.headers["accept-language"]; - const availableLanguages = i18n.locales; - - console.log("ACCEPT LANGUAGE", acceptLanguageHeader); - console.log("AVAILABLE LANGUAGES", availableLanguages); - - // Parse the accept-language header to get an array of languages - const acceptedLanguages = acceptLanguageHeader - ?.split(",") - .map((lang) => lang.split(";")[0]); - - console.log(acceptedLanguages); - - // Find the best match between the accepted languages and available languages - let bestMatch = acceptedLanguages?.find((lang) => - availableLanguages.includes(lang) - ); - - console.log(bestMatch); - - // If no direct match, find the best partial match - if (!bestMatch) { - acceptedLanguages?.some((acceptedLang) => { - const partialMatch = availableLanguages.find((lang) => - lang.startsWith(acceptedLang) - ); - if (partialMatch) { - bestMatch = partialMatch; - return true; - } - return false; - }); - } - - console.log("BEST MATCH", bestMatch); - - return { - props: { - ...(await serverSideTranslations(bestMatch ?? "en", ["common"])), - }, - }; -}; +export { getServerSideProps }; diff --git a/prisma/migrations/20240528194553_added_locale_field_for_users/migration.sql b/prisma/migrations/20240528194553_added_locale_field_for_users/migration.sql new file mode 100644 index 0000000..6523faa --- /dev/null +++ b/prisma/migrations/20240528194553_added_locale_field_for_users/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "locale" TEXT NOT NULL DEFAULT 'en'; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6bc3200..b1af717 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -33,13 +33,14 @@ model User { emailVerified DateTime? unverifiedNewEmail String? image String? - accounts Account[] password String? + locale String @default("en") + accounts Account[] collections Collection[] tags Tag[] pinnedLinks Link[] collectionsJoined UsersAndCollections[] - collectionOrder Int[] @default([]) + collectionOrder Int[] @default([]) whitelistedUsers WhitelistedUser[] accessTokens AccessToken[] subscriptions Subscription?