diff --git a/pages/_app.tsx b/pages/_app.tsx
index 084c2db..afb21f2 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -33,10 +33,18 @@ export default function App({ Component, pageProps: { session, ...pageProps }, }
useEffect(() => {
console.log("Current locale:", router.locale);
async function loadLocaleData() {
- const localeMessages = await import(`../content/i18n/${router.locale}.json`);
+ // Replace the static import with a fetch request
+ const res = await fetch(`/api/translations/${router.locale}`);
+ if (res.ok) {
+ const localeMessages = await res.json();
+ console.log("Loaded messages for locale:", router.locale, localeMessages);
+ setMessages(localeMessages);
+ } else {
+ const localeMessages = await import(`../content/i18n/${router.locale}.json`); setMessages(localeMessages.default);
+ }
console.log("Loaded locale '", router.locale, "' ",);
//console.log("Loaded messages for locale:", router.locale, localeMessages.default);
- setMessages(localeMessages.default);
+
}
loadLocaleData();
}, [router.locale]);
diff --git a/pages/api/translations/[...locale].ts b/pages/api/translations/[...locale].ts
index 84cb6c7..4deebec 100644
--- a/pages/api/translations/[...locale].ts
+++ b/pages/api/translations/[...locale].ts
@@ -1,37 +1,82 @@
+import { NextApiRequest, NextApiResponse } from 'next';
import fs from 'fs';
import path from 'path';
-import { NextApiRequest, NextApiResponse } from 'next';
+import common from "../../../src/helpers/common";
+
+function flattenTranslations(data) {
+ const result = {};
+
+ function recurse(cur, prop) {
+ if (Object(cur) !== cur) {
+ result[prop] = cur;
+ } else if (Array.isArray(cur)) {
+ for (let i = 0, l = cur.length; i < l; i++)
+ recurse(cur[i], prop ? prop + "." + i : "" + i);
+ if (l == 0)
+ result[prop] = [];
+ } else {
+ let isEmpty = true;
+ for (let p in cur) {
+ isEmpty = false;
+ recurse(cur[p], prop ? prop + "." + p : p);
+ }
+ if (isEmpty)
+ result[prop] = {};
+ }
+ }
+ recurse(data, "");
+ return result;
+}
+
+function unflattenTranslations(data) {
+ const result = {};
+
+ for (let i in data) {
+ const keys = i.split('.');
+ keys.reduce((r, e, j) => {
+ return r[e] || (r[e] = isNaN(Number(keys[j + 1])) ? (keys.length - 1 === j ? data[i] : {}) : []);
+ }, result);
+ }
+ return result;
+}
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
- const { locale, type } = req.query;
- const baseFilePath = path.join(process.cwd(), `content/i18n/${locale}.json`);
+ const { locale } = req.query;
+ const filePath = path.join(process.cwd(), `content/i18n/${locale.join(".")}.json`);
const modifiedFilePath = path.join(process.cwd(), `content/i18n/${locale}.modified.json`);
- let translations = {};
-
- try {
- translations = JSON.parse(fs.readFileSync(baseFilePath, 'utf8'));
- if (fs.existsSync(modifiedFilePath)) {
- const modifiedTranslations = JSON.parse(fs.readFileSync(modifiedFilePath, 'utf8'));
- translations = { ...translations, ...modifiedTranslations };
- }
- } catch (error) {
- console.error('Error loading translation files:', error);
- }
-
switch (req.method) {
case 'GET':
- res.status(200).json(translations);
+ let flat = common.parseBool(req.query.flat);
+ try {
+ const fileContents = fs.readFileSync(filePath, 'utf8');
+ let translations = JSON.parse(fileContents);
+ if (fs.existsSync(modifiedFilePath)) {
+ const modifiedTranslations = JSON.parse(fs.readFileSync(modifiedFilePath, 'utf8'));
+ translations = { ...translations, ...modifiedTranslations };
+ }
+ if (flat) {
+ translations = flattenTranslations(translations);
+ }
+ res.status(200).json(translations);
+ } catch (error) {
+ console.error('Error reading translation file:', error);
+ res.status(500).json({ error: 'Failed to read translation file' });
+ }
break;
+
case 'POST':
try {
- fs.writeFileSync(modifiedFilePath, JSON.stringify(req.body, null, 2), 'utf8');
+ const newTranslations = req.body;
+ const reconstructedTranslations = unflattenTranslations(newTranslations);
+ fs.writeFileSync(filePath, JSON.stringify(reconstructedTranslations, null, 2), 'utf8');
res.status(200).json({ status: 'Updated' });
} catch (error) {
- console.error('Error writing modified translation file:', error);
+ console.error('Error writing translation file:', error);
res.status(500).json({ error: 'Failed to update translation file' });
}
break;
+
default:
res.setHeader('Allow', ['GET', 'POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
diff --git a/pages/cart/translations/index.tsx b/pages/cart/translations/index.tsx
index e272f7f..782c4f7 100644
--- a/pages/cart/translations/index.tsx
+++ b/pages/cart/translations/index.tsx
@@ -2,16 +2,22 @@ import axiosInstance from '../../../src/axiosSecure';
import { useState, useEffect } from 'react';
import ProtectedRoute from "../../../components/protectedRoute";
import { UserRole } from "@prisma/client";
+import Layout from 'components/layout';
+import { useRouter } from "next/router";
-// Simulate importing locales from a config or define directly here
-const locales = ['en', 'bg', 'ru'];
+const locales = ['bg', 'en', 'ru'];
const AdminTranslations = () => {
const [translations, setTranslations] = useState({});
- const [locale, setLocale] = useState('en');
+ // set locale to the current locale by default. get it from the useRouter
+ let router = useRouter();
+
+ const [locale, setLocale] = useState(router.locale);
+ const [baseTranslations, setBaseTranslations] = useState(locales[0]);
useEffect(() => {
- axiosInstance.get(`/api/translations/${locale}`).then(res => setTranslations(res.data));
+ axiosInstance.get(`/api/translations/${locale}?flat=true`).then(res => setTranslations(res.data));
+ axiosInstance.get(`/api/translations/${locales[0]}?flat=true`).then(res => setBaseTranslations(res.data));
}, [locale]);
const handleSave = () => {
@@ -28,34 +34,38 @@ const AdminTranslations = () => {
};
return (
-
-
-
Edit Translations
-
-
-
-
-
+
+
+
+
+
+
);
};