initial commit for i18n

This commit is contained in:
daniel31x13 2024-05-27 17:42:29 -04:00
parent b0ea14737f
commit 17cdb7efa4
8 changed files with 140 additions and 5 deletions

7
next-i18next.config.js Normal file
View File

@ -0,0 +1,7 @@
/** @type {import('next-i18next').UserConfig} */
module.exports = {
i18n: {
defaultLocale: "en",
locales: ["en", "de"],
},
};

View File

@ -1,7 +1,9 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const { version } = require("./package.json"); const { version } = require("./package.json");
const { i18n } = require("./next-i18next.config");
const nextConfig = { const nextConfig = {
i18n,
reactStrictMode: true, reactStrictMode: true,
images: { images: {
// For fetching the favicons // For fetching the favicons

View File

@ -50,12 +50,14 @@
"framer-motion": "^10.16.4", "framer-motion": "^10.16.4",
"handlebars": "^4.7.8", "handlebars": "^4.7.8",
"himalaya": "^1.1.0", "himalaya": "^1.1.0",
"i18next": "^23.11.5",
"jimp": "^0.22.10", "jimp": "^0.22.10",
"jsdom": "^22.1.0", "jsdom": "^22.1.0",
"lottie-web": "^5.12.2", "lottie-web": "^5.12.2",
"micro": "^10.0.1", "micro": "^10.0.1",
"next": "13.4.12", "next": "13.4.12",
"next-auth": "^4.22.1", "next-auth": "^4.22.1",
"next-i18next": "^15.3.0",
"node-fetch": "^2.7.0", "node-fetch": "^2.7.0",
"nodemailer": "^6.9.3", "nodemailer": "^6.9.3",
"playwright": "^1.43.1", "playwright": "^1.43.1",
@ -63,6 +65,7 @@
"react-colorful": "^5.6.1", "react-colorful": "^5.6.1",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"react-hot-toast": "^2.4.1", "react-hot-toast": "^2.4.1",
"react-i18next": "^14.1.2",
"react-image-file-resizer": "^0.4.8", "react-image-file-resizer": "^0.4.8",
"react-masonry-css": "^1.0.16", "react-masonry-css": "^1.0.16",
"react-select": "^5.7.4", "react-select": "^5.7.4",

View File

@ -9,9 +9,11 @@ import toast from "react-hot-toast";
import { Toaster, ToastBar } from "react-hot-toast"; import { Toaster, ToastBar } from "react-hot-toast";
import { Session } from "next-auth"; import { Session } from "next-auth";
import { isPWA } from "@/lib/client/utils"; import { isPWA } from "@/lib/client/utils";
import useInitialData from "@/hooks/useInitialData"; // import useInitialData from "@/hooks/useInitialData";
import { appWithTranslation } from "next-i18next";
import nextI18nextConfig from "../next-i18next.config";
export default function App({ function App({
Component, Component,
pageProps, pageProps,
}: AppProps<{ }: AppProps<{
@ -96,6 +98,8 @@ export default function App({
); );
} }
export default appWithTranslation(App);
// function GetData({ children }: { children: React.ReactNode }) { // function GetData({ children }: { children: React.ReactNode }) {
// const status = useInitialData(); // const status = useInitialData();
// return typeof window !== "undefined" && status !== "loading" ? ( // return typeof window !== "undefined" && status !== "loading" ? (

View File

@ -3,7 +3,12 @@ import NewUserModal from "@/components/ModalContent/NewUserModal";
import useUserStore from "@/store/admin/users"; import useUserStore from "@/store/admin/users";
import { User as U } from "@prisma/client"; import { User as U } from "@prisma/client";
import Link from "next/link"; import Link from "next/link";
import { Fragment, useEffect, useState } from "react"; 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";
interface User extends U { interface User extends U {
subscriptions: { subscriptions: {
@ -17,6 +22,10 @@ type UserModal = {
}; };
export default function Admin() { export default function Admin() {
const { t } = useTranslation();
const router = useRouter();
const { users, setUsers } = useUserStore(); const { users, setUsers } = useUserStore();
const [searchQuery, setSearchQuery] = useState(""); const [searchQuery, setSearchQuery] = useState("");
@ -30,6 +39,7 @@ export default function Admin() {
const [newUserModal, setNewUserModal] = useState(false); const [newUserModal, setNewUserModal] = useState(false);
useEffect(() => { useEffect(() => {
console.log(router);
setUsers(); setUsers();
}, []); }, []);
@ -44,7 +54,7 @@ export default function Admin() {
<i className="bi-chevron-left text-xl"></i> <i className="bi-chevron-left text-xl"></i>
</Link> </Link>
<p className="capitalize text-3xl font-thin inline"> <p className="capitalize text-3xl font-thin inline">
User Administration {t("user_administration")}
</p> </p>
</div> </div>
@ -172,3 +182,51 @@ const UserListing = (
</div> </div>
); );
}; };
// 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"])),
},
};
};

View File

@ -0,0 +1,3 @@
{
"user_administration": "TEST, TEST, TEST"
}

View File

@ -0,0 +1,3 @@
{
"user_administration": "User Administration"
}

View File

@ -666,6 +666,13 @@
dependencies: dependencies:
regenerator-runtime "^0.14.0" regenerator-runtime "^0.14.0"
"@babel/runtime@^7.23.2", "@babel/runtime@^7.23.9":
version "7.24.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.6.tgz#5b76eb89ad45e2e4a0a8db54c456251469a3358e"
integrity sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==
dependencies:
regenerator-runtime "^0.14.0"
"@babel/runtime@^7.24.1": "@babel/runtime@^7.24.1":
version "7.24.5" version "7.24.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.5.tgz#230946857c053a36ccc66e1dd03b17dd0c4ed02c" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.5.tgz#230946857c053a36ccc66e1dd03b17dd0c4ed02c"
@ -1960,7 +1967,7 @@
"@types/minimatch" "*" "@types/minimatch" "*"
"@types/node" "*" "@types/node" "*"
"@types/hoist-non-react-statics@^3.3.0": "@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.4":
version "3.3.5" version "3.3.5"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494"
integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg== integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
@ -2683,6 +2690,11 @@ core-js@^2.6.12:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
core-js@^3:
version "3.37.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.1.tgz#d21751ddb756518ac5a00e4d66499df981a62db9"
integrity sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==
core-util-is@1.0.2: core-util-is@1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@ -3833,6 +3845,13 @@ html-encoding-sniffer@^3.0.0:
dependencies: dependencies:
whatwg-encoding "^2.0.0" whatwg-encoding "^2.0.0"
html-parse-stringify@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2"
integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==
dependencies:
void-elements "3.1.0"
http-errors@1.7.3: http-errors@1.7.3:
version "1.7.3" version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
@ -3870,6 +3889,18 @@ https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1:
agent-base "6" agent-base "6"
debug "4" debug "4"
i18next-fs-backend@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/i18next-fs-backend/-/i18next-fs-backend-2.3.1.tgz#0c7d2459ff4a039e2b3228131809fbc0e74ff1a8"
integrity sha512-tvfXskmG/9o+TJ5Fxu54sSO5OkY6d+uMn+K6JiUGLJrwxAVfer+8V3nU8jq3ts9Pe5lXJv4b1N7foIjJ8Iy2Gg==
i18next@^23.11.5:
version "23.11.5"
resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.11.5.tgz#d71eb717a7e65498d87d0594f2664237f9e361ef"
integrity sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==
dependencies:
"@babel/runtime" "^7.23.2"
iconv-lite@0.4.24: iconv-lite@0.4.24:
version "0.4.24" version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@ -4569,6 +4600,17 @@ next-auth@^4.22.1:
preact-render-to-string "^5.1.19" preact-render-to-string "^5.1.19"
uuid "^8.3.2" uuid "^8.3.2"
next-i18next@^15.3.0:
version "15.3.0"
resolved "https://registry.yarnpkg.com/next-i18next/-/next-i18next-15.3.0.tgz#b4530c80573854d00f95229af405e1e5beedbf18"
integrity sha512-bq7Cc9XJFcmGOCLnyEtHaeJ3+JJNsI/8Pkj9BaHAnhm4sZ9vNNC4ZsaqYnlRZ7VH5ypSo73fEqLK935jLsmCvQ==
dependencies:
"@babel/runtime" "^7.23.2"
"@types/hoist-non-react-statics" "^3.3.4"
core-js "^3"
hoist-non-react-statics "^3.3.2"
i18next-fs-backend "^2.3.1"
next@13.4.12: next@13.4.12:
version "13.4.12" version "13.4.12"
resolved "https://registry.yarnpkg.com/next/-/next-13.4.12.tgz#809b21ea0aabbe88ced53252c88c4a5bd5af95df" resolved "https://registry.yarnpkg.com/next/-/next-13.4.12.tgz#809b21ea0aabbe88ced53252c88c4a5bd5af95df"
@ -5195,6 +5237,14 @@ react-hot-toast@^2.4.1:
dependencies: dependencies:
goober "^2.1.10" goober "^2.1.10"
react-i18next@^14.1.2:
version "14.1.2"
resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-14.1.2.tgz#cd57a755f25a32a5fcc3dbe546cf3cc62b4f3ebd"
integrity sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==
dependencies:
"@babel/runtime" "^7.23.9"
html-parse-stringify "^3.0.1"
react-image-file-resizer@^0.4.8: react-image-file-resizer@^0.4.8:
version "0.4.8" version "0.4.8"
resolved "https://registry.yarnpkg.com/react-image-file-resizer/-/react-image-file-resizer-0.4.8.tgz#85f4ae4469fd2867d961568af660ef403d7a79af" resolved "https://registry.yarnpkg.com/react-image-file-resizer/-/react-image-file-resizer-0.4.8.tgz#85f4ae4469fd2867d961568af660ef403d7a79af"
@ -6176,6 +6226,11 @@ verror@1.10.0:
core-util-is "1.0.2" core-util-is "1.0.2"
extsprintf "^1.2.0" extsprintf "^1.2.0"
void-elements@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==
w3c-xmlserializer@^4.0.0: w3c-xmlserializer@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073" resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073"