mirror of
https://github.com/lukevella/rallly.git
synced 2025-04-28 17:56:37 +02:00
⬆️ Upgrade i18next (#1592)
This commit is contained in:
parent
8c84a92a58
commit
bff2dd3a20
15 changed files with 56 additions and 65 deletions
16
apps/landing/declarations/i18next.d.ts
vendored
16
apps/landing/declarations/i18next.d.ts
vendored
|
@ -1,21 +1,19 @@
|
|||
import "react-i18next";
|
||||
import "i18next";
|
||||
|
||||
import type blog from "../public/locales/en/blog.json";
|
||||
import type common from "../public/locales/en/common.json";
|
||||
import type home from "../public/locales/en/home.json";
|
||||
import type pricing from "../public/locales/en/pricing.json";
|
||||
|
||||
interface I18nNamespaces {
|
||||
common: typeof common;
|
||||
home: typeof home;
|
||||
pricing: typeof pricing;
|
||||
blog: typeof blog;
|
||||
}
|
||||
|
||||
declare module "i18next" {
|
||||
interface CustomTypeOptions {
|
||||
defaultNS: "common";
|
||||
resources: I18nNamespaces;
|
||||
resources: {
|
||||
common: typeof common;
|
||||
home: typeof home;
|
||||
pricing: typeof pricing;
|
||||
blog: typeof blog;
|
||||
};
|
||||
returnNull: false;
|
||||
}
|
||||
}
|
||||
|
|
1
apps/landing/next-env.d.ts
vendored
1
apps/landing/next-env.d.ts
vendored
|
@ -1,6 +1,5 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference types="next/navigation-types/compat/navigation" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
"accept-language-parser": "^1.5.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"gray-matter": "^4.0.3",
|
||||
"i18next": "^22.4.9",
|
||||
"i18next": "^24.2.2",
|
||||
"i18next-icu": "^2.3.0",
|
||||
"intl-messageformat": "^10.3.4",
|
||||
"lodash": "^4.17.21",
|
||||
|
@ -31,7 +31,7 @@
|
|||
"next-i18next": "^13.0.3",
|
||||
"next-mdx-remote": "^5.0.0",
|
||||
"next-seo": "^6.1.0",
|
||||
"react-i18next": "^12.1.4",
|
||||
"react-i18next": "^15.4.1",
|
||||
"react-use": "^17.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -6,7 +6,7 @@ import { BigTestimonial, Marketing, MentionedBy } from "@/components/marketing";
|
|||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page({ params }: { params: { locale: string } }) {
|
||||
const { t } = await getTranslation(params.locale, ["common", "home"]);
|
||||
const { t } = await getTranslation(params.locale, "home");
|
||||
return (
|
||||
<Marketing>
|
||||
<MarketingHero
|
||||
|
|
|
@ -4,17 +4,21 @@ import { BigTestimonial, Marketing, MentionedBy } from "@/components/marketing";
|
|||
import { getTranslation } from "@/i18n/server";
|
||||
|
||||
export default async function Page({ params }: { params: { locale: string } }) {
|
||||
const { t } = await getTranslation(params.locale, ["common", "home"]);
|
||||
const { t } = await getTranslation(params.locale, ["home", "common"]);
|
||||
return (
|
||||
<Marketing>
|
||||
<MarketingHero
|
||||
title={t("home:headline", {
|
||||
title={t("headline", {
|
||||
defaultValue: "Ditch the back-and-forth emails",
|
||||
ns: "home",
|
||||
})}
|
||||
description={t("home:subheading", {
|
||||
description={t("subheading", {
|
||||
defaultValue: "Streamline your scheduling process and save time",
|
||||
ns: "home",
|
||||
})}
|
||||
callToAction={t("getStarted", {
|
||||
ns: "common",
|
||||
})}
|
||||
callToAction={t("getStarted")}
|
||||
/>
|
||||
<Bonus t={t} />
|
||||
<BigTestimonial />
|
||||
|
@ -30,10 +34,11 @@ export async function generateMetadata({
|
|||
}) {
|
||||
const { t } = await getTranslation(params.locale, "home");
|
||||
return {
|
||||
title: t("home:metaTitle", {
|
||||
title: t("metaTitle", {
|
||||
defaultValue: "Rallly: Group Scheduling Tool",
|
||||
ns: "home",
|
||||
}),
|
||||
description: t("home:metaDescription", {
|
||||
description: t("metaDescription", {
|
||||
defaultValue:
|
||||
"Create polls and vote to find the best day or time. A free alternative to Doodle.",
|
||||
}),
|
||||
|
|
|
@ -8,7 +8,7 @@ import { linkToApp } from "@/lib/linkToApp";
|
|||
|
||||
import { PriceTables } from "./pricing-table";
|
||||
|
||||
const FAQ = async ({ t }: { t: TFunction }) => {
|
||||
const FAQ = async ({ t }: { t: TFunction<"pricing"> }) => {
|
||||
return (
|
||||
<section>
|
||||
<h2 className="text-2xl font-bold">
|
||||
|
@ -123,7 +123,7 @@ const FAQ = async ({ t }: { t: TFunction }) => {
|
|||
};
|
||||
|
||||
export default async function Page({ params }: { params: { locale: string } }) {
|
||||
const { t } = await getTranslation(params.locale, ["common", "pricing"]);
|
||||
const { t } = await getTranslation(params.locale, "pricing");
|
||||
return (
|
||||
<article className="mx-auto max-w-3xl space-y-6">
|
||||
<header className="space-y-2 sm:p-6 sm:text-center">
|
||||
|
|
|
@ -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 (
|
||||
<div className="mx-auto flex flex-wrap justify-center gap-2 whitespace-nowrap text-center sm:grid-cols-4 sm:gap-4 sm:gap-x-8">
|
||||
|
|
|
@ -21,13 +21,14 @@ const initI18next = async (lng: string, ns: Namespace) => {
|
|||
return i18nInstance;
|
||||
};
|
||||
|
||||
export async function getTranslation(
|
||||
export async function getTranslation<Ns extends Namespace>(
|
||||
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<Ns>(locale),
|
||||
i18n: i18nextInstance,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -20,9 +20,6 @@ const i18nDefaultConfig: InitOptions = {
|
|||
ns: ["emails"],
|
||||
fallbackNS: "emails",
|
||||
defaultNS: "emails",
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type I18nInstance = typeof i18nInstance;
|
||||
|
|
|
@ -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;
|
||||
|
|
27
yarn.lock
27
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:
|
||||
|
|
Loading…
Add table
Reference in a new issue