diff --git a/apps/landing/src/components/home/bonus.tsx b/apps/landing/src/components/home/bonus.tsx
index d439cdc03..1e7712ccc 100644
--- a/apps/landing/src/components/home/bonus.tsx
+++ b/apps/landing/src/components/home/bonus.tsx
@@ -10,7 +10,7 @@ import { Trans } from "react-i18next/TransWithoutContext";
import { BonusItem } from "@/components/home/bonus-item";
-export async function Bonus({ t }: { t: TFunction }) {
+export async function Bonus({ t }: { t: TFunction<"home" | "common"> }) {
const userCount = await prisma.user.count();
return (
diff --git a/apps/landing/src/i18n/server.ts b/apps/landing/src/i18n/server.ts
index 2f48c385f..5e7cd2977 100644
--- a/apps/landing/src/i18n/server.ts
+++ b/apps/landing/src/i18n/server.ts
@@ -21,13 +21,14 @@ const initI18next = async (lng: string, ns: Namespace) => {
return i18nInstance;
};
-export async function getTranslation(
+export async function getTranslation(
locale: string,
- ns: Namespace = defaultNS,
+ ns?: Ns,
) {
- const i18nextInstance = await initI18next(locale, ns);
+ const fixedNs = ns ?? defaultNS;
+ const i18nextInstance = await initI18next(locale, fixedNs);
return {
- t: i18nextInstance.getFixedT(locale, Array.isArray(ns) ? ns[0] : ns),
+ t: i18nextInstance.getFixedT(locale),
i18n: i18nextInstance,
};
}
diff --git a/apps/landing/src/i18n/settings.ts b/apps/landing/src/i18n/settings.ts
index 9b6213a62..b265a0372 100644
--- a/apps/landing/src/i18n/settings.ts
+++ b/apps/landing/src/i18n/settings.ts
@@ -1,5 +1,5 @@
import allLanguages from "@rallly/languages";
-import type { InitOptions } from "i18next";
+import type { InitOptions, Namespace } from "i18next";
export const fallbackLng = "en";
export const languages = Object.keys(allLanguages);
@@ -7,7 +7,7 @@ export const defaultNS = "common";
export function getOptions(
lng = fallbackLng,
- ns: string | string[] = defaultNS,
+ ns: Namespace = defaultNS,
): InitOptions {
return {
// debug: true,
diff --git a/apps/web/package.json b/apps/web/package.json
index b943668c1..46e0e458c 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -54,7 +54,7 @@
"cookie": "^0.7.0",
"crypto": "^1.0.1",
"dayjs": "^1.11.10",
- "i18next": "^22.4.9",
+ "i18next": "^24.2.2",
"i18next-icu": "^2.3.0",
"i18next-resources-to-backend": "^1.1.4",
"ics": "^3.1.0",
@@ -75,7 +75,7 @@
"react-big-calendar": "^1.8.1",
"react-hook-form": "^7.42.1",
"react-hook-form-persist": "^3.0.0",
- "react-i18next": "^12.1.4",
+ "react-i18next": "^15.4.1",
"react-remove-scroll": "^2.5.6",
"react-use": "^17.4.0",
"smoothscroll-polyfill": "^0.4.4",
diff --git a/apps/web/src/app/api/house-keeping/remove-deleted-polls/route.ts b/apps/web/src/app/api/house-keeping/remove-deleted-polls/route.ts
index c420883e6..26d44626a 100644
--- a/apps/web/src/app/api/house-keeping/remove-deleted-polls/route.ts
+++ b/apps/web/src/app/api/house-keeping/remove-deleted-polls/route.ts
@@ -6,41 +6,25 @@ import { checkApiAuthorization } from "@/utils/api-auth";
/**
* Remove polls and corresponding data that have been marked deleted for more than 7 days.
*/
-export async function POST(req: Request) {
+export async function POST() {
const unauthorized = checkApiAuthorization();
if (unauthorized) return unauthorized;
- const options = (await req.json()) as { take?: number } | undefined;
-
// First get the ids of all the polls that have been marked as deleted for at least 7 days
- const deletedPolls = await prisma.poll.findMany({
- select: {
- id: true,
- },
+ const deletedPolls = await prisma.poll.deleteMany({
where: {
deleted: true,
deletedAt: {
lt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
},
},
- take: options?.take ?? 1000,
- });
-
- const deletedPollIds = deletedPolls.map((poll) => poll.id);
-
- const { count: deletedPollCount } = await prisma.poll.deleteMany({
- where: {
- id: {
- in: deletedPollIds,
- },
- },
});
return NextResponse.json({
success: true,
summary: {
deleted: {
- polls: deletedPollCount,
+ polls: deletedPolls.count,
},
},
});
diff --git a/apps/web/src/i18n/settings.ts b/apps/web/src/i18n/settings.ts
index 66d91dbab..f18fe5164 100644
--- a/apps/web/src/i18n/settings.ts
+++ b/apps/web/src/i18n/settings.ts
@@ -1,5 +1,5 @@
import allLanguages from "@rallly/languages";
-import type { InitOptions } from "i18next";
+import type { InitOptions, Namespace } from "i18next";
export const fallbackLng = "en";
export const languages = Object.keys(allLanguages);
@@ -7,7 +7,7 @@ export const defaultNS = "app";
export function getOptions(
lng = fallbackLng,
- ns: string | string[] = defaultNS,
+ ns: Namespace = defaultNS,
): InitOptions {
return {
supportedLngs: languages,
diff --git a/packages/emails/src/i18n.ts b/packages/emails/src/i18n.ts
index 9b7512eb6..59135b0db 100644
--- a/packages/emails/src/i18n.ts
+++ b/packages/emails/src/i18n.ts
@@ -20,9 +20,6 @@ const i18nDefaultConfig: InitOptions = {
ns: ["emails"],
fallbackNS: "emails",
defaultNS: "emails",
- interpolation: {
- escapeValue: false,
- },
} as const;
export type I18nInstance = typeof i18nInstance;
diff --git a/packages/emails/src/types.ts b/packages/emails/src/types.ts
index f32429bb6..855b9470c 100644
--- a/packages/emails/src/types.ts
+++ b/packages/emails/src/types.ts
@@ -9,7 +9,7 @@ export type EmailContext = {
domain: string;
supportEmail: string;
i18n: I18nInstance;
- t: TFunction<"emails", undefined, "emails">;
+ t: TFunction;
};
export type TemplateName = keyof EmailTemplates;
diff --git a/yarn.lock b/yarn.lock
index ea819cef7..0826b11ae 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2271,6 +2271,13 @@
dependencies:
regenerator-runtime "^0.14.0"
+"@babel/runtime@^7.23.2", "@babel/runtime@^7.25.0":
+ version "7.26.9"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.9.tgz#aa4c6facc65b9cb3f87d75125ffd47781b475433"
+ integrity sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
"@babel/runtime@^7.23.5":
version "7.23.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7"
@@ -10011,12 +10018,12 @@ i18next@*:
dependencies:
"@babel/runtime" "^7.20.6"
-i18next@^22.4.9:
- version "22.4.10"
- resolved "https://registry.npmjs.org/i18next/-/i18next-22.4.10.tgz"
- integrity sha512-3EqgGK6fAJRjnGgfkNSStl4mYLCjUoJID338yVyLMj5APT67HUtWoqSayZewiiC5elzMUB1VEUwcmSCoeQcNEA==
+i18next@^24.2.2:
+ version "24.2.2"
+ resolved "https://registry.yarnpkg.com/i18next/-/i18next-24.2.2.tgz#3ba3d213302068d569142737f03f30929de696de"
+ integrity sha512-NE6i86lBCKRYZa5TaUDkU5S4HFgLIEJRLr3Whf2psgaxBleQ2LC1YW1Vc+SCgkAW7VEzndT6al6+CzegSUHcTQ==
dependencies:
- "@babel/runtime" "^7.20.6"
+ "@babel/runtime" "^7.23.2"
iconv-lite@0.4.24:
version "0.4.24"
@@ -12578,12 +12585,12 @@ react-hook-form@^7.42.1:
resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.43.2.tgz"
integrity sha512-NvD3Oe2Y9hhqo2R4I4iJigDzSLpdMnzUpNMxlnzTbdiT7NT3BW0GxWCzEtwPudZMUPbZhNcSy1EcGAygyhDORg==
-react-i18next@^12.1.4:
- version "12.2.0"
- resolved "https://registry.npmjs.org/react-i18next/-/react-i18next-12.2.0.tgz"
- integrity sha512-5XeVgSygaGfyFmDd2WcXvINRw2WEC1XviW1LXY/xLOEMzsCFRwKqfnHN+hUjla8ZipbVJR27GCMSuTr0BhBBBQ==
+react-i18next@^15.4.1:
+ version "15.4.1"
+ resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-15.4.1.tgz#33f3e89c2f6c68e2bfcbf9aa59986ad42fe78758"
+ integrity sha512-ahGab+IaSgZmNPYXdV1n+OYky95TGpFwnKRflX/16dY04DsYYKHtVLjeny7sBSCREEcoMbAgSkFiGLF5g5Oofw==
dependencies:
- "@babel/runtime" "^7.20.6"
+ "@babel/runtime" "^7.25.0"
html-parse-stringify "^3.0.1"
react-is@^16.13.1, react-is@^16.7.0: