diff --git a/apps/landing/package.json b/apps/landing/package.json index 1e8a6744a..41c68c4ea 100644 --- a/apps/landing/package.json +++ b/apps/landing/package.json @@ -25,10 +25,10 @@ "gray-matter": "^4.0.3", "i18next": "^24.2.2", "i18next-icu": "^2.3.0", - "intl-messageformat": "^10.3.4", + "i18next-resources-to-backend": "^1.2.1", + "intl-messageformat": "^10.7.15", "lodash": "^4.17.21", "nanoid": "^5.0.9", - "next-i18next": "^13.0.3", "next-mdx-remote": "^5.0.0", "next-seo": "^6.1.0", "react-i18next": "^15.4.1", diff --git a/apps/landing/src/app/[locale]/footer.tsx b/apps/landing/src/app/[locale]/footer.tsx index 29dfc0b22..c1ccb4cd4 100644 --- a/apps/landing/src/app/[locale]/footer.tsx +++ b/apps/landing/src/app/[locale]/footer.tsx @@ -20,9 +20,9 @@ import Image from "next/image"; import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; import * as React from "react"; -import { useTranslation } from "react-i18next"; -import { Trans } from "@/components/trans"; +import { Trans } from "@/i18n/client/trans"; +import { useTranslation } from "@/i18n/client/use-translation"; const LanguageSelect = () => { const router = useRouter(); diff --git a/apps/landing/src/app/[locale]/layout.tsx b/apps/landing/src/app/[locale]/layout.tsx index c493d035e..f123f58ca 100644 --- a/apps/landing/src/app/[locale]/layout.tsx +++ b/apps/landing/src/app/[locale]/layout.tsx @@ -17,7 +17,7 @@ import Link from "next/link"; import { Trans } from "react-i18next/TransWithoutContext"; import { sans } from "@/fonts/sans"; -import { I18nProvider } from "@/i18n/client"; +import { I18nProvider } from "@/i18n/client/i18n-provider"; import { getTranslation } from "@/i18n/server"; import { linkToApp } from "@/lib/linkToApp"; diff --git a/apps/landing/src/app/[locale]/pricing/pricing-table.tsx b/apps/landing/src/app/[locale]/pricing/pricing-table.tsx index 4a77327bc..b151a8a4b 100644 --- a/apps/landing/src/app/[locale]/pricing/pricing-table.tsx +++ b/apps/landing/src/app/[locale]/pricing/pricing-table.tsx @@ -18,7 +18,7 @@ import Link from "next/link"; import React from "react"; import { Trans } from "react-i18next/TransWithoutContext"; -import { useTranslation } from "@/i18n/client"; +import { useTranslation } from "@/i18n/client/use-translation"; import { linkToApp } from "@/lib/linkToApp"; export function PriceTables() { diff --git a/apps/landing/src/components/error-page.tsx b/apps/landing/src/components/error-page.tsx index 2a2255bba..86ad294f2 100644 --- a/apps/landing/src/components/error-page.tsx +++ b/apps/landing/src/components/error-page.tsx @@ -3,9 +3,10 @@ import { Button } from "@rallly/ui/button"; import { FileSearchIcon } from "lucide-react"; import Link from "next/link"; -import { useTranslation } from "next-i18next"; import * as React from "react"; +import { useTranslation } from "@/i18n/client/use-translation"; + export interface ComponentProps { icon?: React.ReactNode; title: string; diff --git a/apps/landing/src/components/home/hero.tsx b/apps/landing/src/components/home/hero.tsx index e80090c65..9e6038bda 100644 --- a/apps/landing/src/components/home/hero.tsx +++ b/apps/landing/src/components/home/hero.tsx @@ -8,8 +8,8 @@ import Image from "next/image"; import Link from "next/link"; import * as React from "react"; -import { Trans } from "@/components/trans"; import { handwritten } from "@/fonts/handwritten"; +import { Trans } from "@/i18n/client/trans"; import { linkToApp } from "@/lib/linkToApp"; const Screenshot = () => { diff --git a/apps/landing/src/components/marketing.tsx b/apps/landing/src/components/marketing.tsx index 263018d39..af6daa2e9 100644 --- a/apps/landing/src/components/marketing.tsx +++ b/apps/landing/src/components/marketing.tsx @@ -5,7 +5,7 @@ import Image from "next/image"; import Link from "next/link"; import React from "react"; -import { Trans } from "@/components/trans"; +import { Trans } from "@/i18n/client/trans"; // export const UsedBy = () => { // return ( diff --git a/apps/landing/src/i18n/client.tsx b/apps/landing/src/i18n/client/i18n-provider.tsx similarity index 69% rename from apps/landing/src/i18n/client.tsx rename to apps/landing/src/i18n/client/i18n-provider.tsx index 37f71c9b6..b60784e30 100644 --- a/apps/landing/src/i18n/client.tsx +++ b/apps/landing/src/i18n/client/i18n-provider.tsx @@ -1,17 +1,12 @@ "use client"; -import type { Namespace } from "i18next"; import i18next from "i18next"; import ICU from "i18next-icu"; import resourcesToBackend from "i18next-resources-to-backend"; import React from "react"; -import { - I18nextProvider, - initReactI18next, - useTranslation as useTranslationOrg, -} from "react-i18next"; +import { I18nextProvider, initReactI18next } from "react-i18next"; import { useAsync } from "react-use"; -import { defaultNS, getOptions } from "./settings"; +import { defaultNS, getOptions } from "../settings"; async function initTranslations(lng: string) { const i18n = i18next @@ -20,7 +15,7 @@ async function initTranslations(lng: string) { .use( resourcesToBackend( (language: string, namespace: string) => - import(`../../public/locales/${language}/${namespace}.json`), + import(`../../../public/locales/${language}/${namespace}.json`), ), ); await i18n.init(getOptions(lng)); @@ -28,10 +23,6 @@ async function initTranslations(lng: string) { return i18n; } -export function useTranslation(ns?: Namespace) { - return useTranslationOrg(ns); -} - export function I18nProvider({ locale, children, diff --git a/apps/landing/src/components/trans.tsx b/apps/landing/src/i18n/client/trans.tsx similarity index 73% rename from apps/landing/src/components/trans.tsx rename to apps/landing/src/i18n/client/trans.tsx index c06b51051..eb5450d5d 100644 --- a/apps/landing/src/components/trans.tsx +++ b/apps/landing/src/i18n/client/trans.tsx @@ -1,4 +1,5 @@ -import { Trans as BaseTrans, useTranslation } from "next-i18next"; +"use client"; +import { Trans as BaseTrans, useTranslation } from "react-i18next"; type TransWithContextProps = Omit, "t">; diff --git a/apps/landing/src/i18n/client/use-translation.ts b/apps/landing/src/i18n/client/use-translation.ts new file mode 100644 index 000000000..2e8e95c08 --- /dev/null +++ b/apps/landing/src/i18n/client/use-translation.ts @@ -0,0 +1,6 @@ +import type { Namespace } from "i18next"; +import { useTranslation as useTranslationOrg } from "react-i18next"; + +export function useTranslation(ns?: Namespace) { + return useTranslationOrg(ns); +} diff --git a/apps/landing/src/utils/page-translations.ts b/apps/landing/src/utils/page-translations.ts deleted file mode 100644 index b3a3a066e..000000000 --- a/apps/landing/src/utils/page-translations.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { GetStaticProps } from "next"; -import { serverSideTranslations } from "next-i18next/serverSideTranslations"; - -export const getStaticTranslations = - (namespacesRequired: string[] = []): GetStaticProps => - async (ctx) => { - const locale = ctx.locale ?? "en"; - return { - props: { - ...(await serverSideTranslations(locale, [ - "common", - ...namespacesRequired, - ])), - }, - }; - }; diff --git a/apps/web/package.json b/apps/web/package.json index dac5f1a20..3a1cbed87 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -58,9 +58,9 @@ "dayjs": "^1.11.10", "i18next": "^24.2.2", "i18next-icu": "^2.3.0", - "i18next-resources-to-backend": "^1.1.4", + "i18next-resources-to-backend": "^1.2.1", "ics": "^3.1.0", - "intl-messageformat": "^10.3.4", + "intl-messageformat": "^10.7.15", "iron-session": "^6.3.1", "jose": "^5.9.6", "js-cookie": "^3.0.1", @@ -71,7 +71,6 @@ "micro": "^10.0.1", "nanoid": "^5.0.9", "next-auth": "^5.0.0-beta.25", - "next-i18next": "^13.0.3", "php-serialize": "^4.1.1", "postcss": "^8.4.31", "react-big-calendar": "^1.8.1", diff --git a/apps/web/src/app/[locale]/(admin)/settings/profile/profile-page.tsx b/apps/web/src/app/[locale]/(admin)/settings/profile/profile-page.tsx index f3040aaba..4996ddef1 100644 --- a/apps/web/src/app/[locale]/(admin)/settings/profile/profile-page.tsx +++ b/apps/web/src/app/[locale]/(admin)/settings/profile/profile-page.tsx @@ -3,7 +3,6 @@ import { Button } from "@rallly/ui/button"; import { DialogTrigger } from "@rallly/ui/dialog"; import { LogOutIcon, TrashIcon } from "lucide-react"; import Head from "next/head"; -import { useTranslation } from "next-i18next"; import { DeleteAccountDialog } from "@/app/[locale]/(admin)/settings/profile/delete-account-dialog"; import { ProfileSettings } from "@/app/[locale]/(admin)/settings/profile/profile-settings"; @@ -15,6 +14,7 @@ import { } from "@/components/settings/settings"; import { Trans } from "@/components/trans"; import { useUser } from "@/components/user-provider"; +import { useTranslation } from "@/i18n/client"; import { ProfileEmailAddress } from "./profile-email-address"; diff --git a/apps/web/src/app/[locale]/poll/[urlId]/edit-options/page.tsx b/apps/web/src/app/[locale]/poll/[urlId]/edit-options/page.tsx index ad9b20964..899c9b2a6 100644 --- a/apps/web/src/app/[locale]/poll/[urlId]/edit-options/page.tsx +++ b/apps/web/src/app/[locale]/poll/[urlId]/edit-options/page.tsx @@ -5,7 +5,6 @@ import { Form } from "@rallly/ui/form"; import dayjs from "dayjs"; import Link from "next/link"; import { useRouter } from "next/navigation"; -import { useTranslation } from "next-i18next"; import { useForm } from "react-hook-form"; import type { PollOptionsData } from "@/components/forms"; @@ -14,6 +13,7 @@ import { useModalContext } from "@/components/modal/modal-provider"; import { useUpdatePollMutation } from "@/components/poll/mutations"; import { usePoll } from "@/components/poll-context"; import { Trans } from "@/components/trans"; +import { useTranslation } from "@/i18n/client"; import { encodeDateOption } from "@/utils/date-time-utils"; const convertOptionToString = ( diff --git a/apps/web/src/app/[locale]/poll/[urlId]/guest-poll-alert.tsx b/apps/web/src/app/[locale]/poll/[urlId]/guest-poll-alert.tsx index 0d6999663..f3693fd27 100644 --- a/apps/web/src/app/[locale]/poll/[urlId]/guest-poll-alert.tsx +++ b/apps/web/src/app/[locale]/poll/[urlId]/guest-poll-alert.tsx @@ -1,10 +1,10 @@ "use client"; import { Alert, AlertDescription, AlertTitle } from "@rallly/ui/alert"; import { InfoIcon } from "lucide-react"; -import { Trans } from "next-i18next"; import { LoginLink } from "@/components/login-link"; import { RegisterLink } from "@/components/register-link"; +import { Trans } from "@/components/trans"; import { useUser } from "@/components/user-provider"; import { usePoll } from "@/contexts/poll"; diff --git a/apps/web/src/components/discussion/discussion.tsx b/apps/web/src/components/discussion/discussion.tsx index 5719f3a89..2e418f3c5 100644 --- a/apps/web/src/components/discussion/discussion.tsx +++ b/apps/web/src/components/discussion/discussion.tsx @@ -27,7 +27,6 @@ import { TrashIcon, } from "lucide-react"; import { signIn, useSession } from "next-auth/react"; -import { useTranslation } from "next-i18next"; import * as React from "react"; import { Controller, useForm } from "react-hook-form"; @@ -37,6 +36,7 @@ import { useParticipants } from "@/components/participants-provider"; import { Trans } from "@/components/trans"; import { usePoll } from "@/contexts/poll"; import { useRole } from "@/contexts/role"; +import { useTranslation } from "@/i18n/client"; import { trpc } from "@/trpc/client"; import { requiredString } from "../../utils/form-validation"; diff --git a/apps/web/src/components/error-page.tsx b/apps/web/src/components/error-page.tsx index 83ad7724c..eba75da91 100644 --- a/apps/web/src/components/error-page.tsx +++ b/apps/web/src/components/error-page.tsx @@ -1,9 +1,10 @@ import { Button } from "@rallly/ui/button"; import { FrownIcon } from "lucide-react"; import Link from "next/link"; -import { useTranslation } from "next-i18next"; import * as React from "react"; +import { useTranslation } from "@/i18n/client"; + export interface ComponentProps { icon?: React.ComponentType<{ className?: string }>; title: string; diff --git a/apps/web/src/components/feedback.tsx b/apps/web/src/components/feedback.tsx index 62749b9d9..04dc8604b 100644 --- a/apps/web/src/components/feedback.tsx +++ b/apps/web/src/components/feedback.tsx @@ -14,7 +14,8 @@ import { SmileIcon, } from "lucide-react"; import Link from "next/link"; -import { Trans } from "next-i18next"; + +import { Trans } from "@/components/trans"; const FeedbackButton = () => { return ( diff --git a/apps/web/src/components/forms/poll-details-form.tsx b/apps/web/src/components/forms/poll-details-form.tsx index 8d634e22c..8301e3ba8 100644 --- a/apps/web/src/components/forms/poll-details-form.tsx +++ b/apps/web/src/components/forms/poll-details-form.tsx @@ -1,10 +1,10 @@ import { FormField, FormItem, FormLabel, FormMessage } from "@rallly/ui/form"; import { Input } from "@rallly/ui/input"; import { Textarea } from "@rallly/ui/textarea"; -import { useTranslation } from "next-i18next"; import { useFormContext } from "react-hook-form"; import { Trans } from "@/components/trans"; +import { useTranslation } from "@/i18n/client"; import { useFormValidation } from "@/utils/form-validation"; import type { NewEventData } from "./types"; diff --git a/apps/web/src/components/forms/poll-options-form/date-navigation-toolbar.tsx b/apps/web/src/components/forms/poll-options-form/date-navigation-toolbar.tsx index a8b50f0ae..e13428f40 100644 --- a/apps/web/src/components/forms/poll-options-form/date-navigation-toolbar.tsx +++ b/apps/web/src/components/forms/poll-options-form/date-navigation-toolbar.tsx @@ -1,8 +1,9 @@ import { Button } from "@rallly/ui/button"; import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"; -import { useTranslation } from "next-i18next"; import * as React from "react"; +import { useTranslation } from "@/i18n/client"; + export interface DateNavigationToolbarProps { year: number; label: string; diff --git a/apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx b/apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx index 35e876f93..05710e355 100644 --- a/apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx +++ b/apps/web/src/components/forms/poll-options-form/month-calendar/month-calendar.tsx @@ -19,12 +19,12 @@ import { SparklesIcon, XIcon, } from "lucide-react"; -import { useTranslation } from "next-i18next"; import * as React from "react"; import { useFormContext } from "react-hook-form"; import type { NewEventData } from "@/components/forms"; import { Trans } from "@/components/trans"; +import { useTranslation } from "@/i18n/client"; import { expectTimeOption, diff --git a/apps/web/src/components/forms/poll-options-form/poll-options-form.tsx b/apps/web/src/components/forms/poll-options-form/poll-options-form.tsx index f030581ea..d26590bde 100644 --- a/apps/web/src/components/forms/poll-options-form/poll-options-form.tsx +++ b/apps/web/src/components/forms/poll-options-form/poll-options-form.tsx @@ -16,11 +16,12 @@ import { Switch } from "@rallly/ui/switch"; import { Tabs, TabsList, TabsTrigger } from "@rallly/ui/tabs"; import { Tooltip, TooltipContent, TooltipTrigger } from "@rallly/ui/tooltip"; import { CalendarIcon, GlobeIcon, InfoIcon, TableIcon } from "lucide-react"; -import { Trans, useTranslation } from "next-i18next"; import * as React from "react"; import { useFormContext } from "react-hook-form"; import { TimeZoneCommand } from "@/components/time-zone-picker/time-zone-select"; +import { Trans } from "@/components/trans"; +import { useTranslation } from "@/i18n/client"; import { getBrowserTimeZone } from "../../../utils/date-time-utils"; import type { NewEventData } from "../types"; diff --git a/apps/web/src/components/new-participant-modal.tsx b/apps/web/src/components/new-participant-modal.tsx index 83cbb521b..3a0cc942c 100644 --- a/apps/web/src/components/new-participant-modal.tsx +++ b/apps/web/src/components/new-participant-modal.tsx @@ -7,11 +7,11 @@ import { FormMessage } from "@rallly/ui/form"; import { Input } from "@rallly/ui/input"; import * as Sentry from "@sentry/nextjs"; import { TRPCClientError } from "@trpc/client"; -import { useTranslation } from "next-i18next"; import { useForm } from "react-hook-form"; import z from "zod"; import { usePoll } from "@/contexts/poll"; +import { useTranslation } from "@/i18n/client"; import { useAddParticipantMutation } from "./poll/mutations"; import VoteIcon from "./poll/vote-icon"; diff --git a/apps/web/src/components/participant-dropdown.tsx b/apps/web/src/components/participant-dropdown.tsx index e1fd648f8..4ea30fc68 100644 --- a/apps/web/src/components/participant-dropdown.tsx +++ b/apps/web/src/components/participant-dropdown.tsx @@ -29,7 +29,6 @@ import { } from "@rallly/ui/form"; import { Input } from "@rallly/ui/input"; import { PencilIcon, TagIcon, TrashIcon } from "lucide-react"; -import { useTranslation } from "next-i18next"; import React from "react"; import type { SubmitHandler } from "react-hook-form"; import { useForm } from "react-hook-form"; @@ -39,6 +38,7 @@ import { z } from "zod"; import { OptimizedAvatarImage } from "@/components/optimized-avatar-image"; import { useDeleteParticipantMutation } from "@/components/poll/mutations"; import { Trans } from "@/components/trans"; +import { useTranslation } from "@/i18n/client"; import { trpc } from "@/trpc/client"; import { useFormValidation } from "@/utils/form-validation"; diff --git a/apps/web/src/components/poll-context.tsx b/apps/web/src/components/poll-context.tsx index d754873aa..8ac0354d9 100644 --- a/apps/web/src/components/poll-context.tsx +++ b/apps/web/src/components/poll-context.tsx @@ -2,9 +2,9 @@ import type { Participant, VoteType } from "@rallly/database"; import dayjs from "dayjs"; import { keyBy } from "lodash"; import { TrashIcon } from "lucide-react"; -import { useTranslation } from "next-i18next"; import React from "react"; +import { useTranslation } from "@/i18n/client"; import type { GetPollApiResponse, Vote } from "@/trpc/client/types"; import type { ParsedDateOption, diff --git a/apps/web/src/components/poll/desktop-poll.tsx b/apps/web/src/components/poll/desktop-poll.tsx index 58559685f..dc56797e3 100644 --- a/apps/web/src/components/poll/desktop-poll.tsx +++ b/apps/web/src/components/poll/desktop-poll.tsx @@ -12,7 +12,6 @@ import { ShrinkIcon, Users2Icon, } from "lucide-react"; -import { Trans } from "next-i18next"; import * as React from "react"; import { RemoveScroll } from "react-remove-scroll"; import { useMeasure, useScroll } from "react-use"; @@ -25,6 +24,7 @@ import { EmptyStateTitle, } from "@/components/empty-state"; import { useVotingForm } from "@/components/poll/voting-form"; +import { Trans } from "@/components/trans"; import { usePermissions } from "@/contexts/permissions"; import { usePoll } from "@/contexts/poll"; import { useTranslation } from "@/i18n/client"; diff --git a/apps/web/src/components/poll/desktop-poll/participant-row-form.tsx b/apps/web/src/components/poll/desktop-poll/participant-row-form.tsx index 2a06b7d00..1c3a2f814 100644 --- a/apps/web/src/components/poll/desktop-poll/participant-row-form.tsx +++ b/apps/web/src/components/poll/desktop-poll/participant-row-form.tsx @@ -8,7 +8,6 @@ import { TooltipTrigger, } from "@rallly/ui/tooltip"; import { UndoIcon } from "lucide-react"; -import { useTranslation } from "next-i18next"; import * as React from "react"; import { Controller } from "react-hook-form"; @@ -17,6 +16,7 @@ import { Participant, ParticipantName } from "@/components/participant"; import { useVotingForm } from "@/components/poll/voting-form"; import { YouAvatar } from "@/components/poll/you-avatar"; import { Trans } from "@/components/trans"; +import { useTranslation } from "@/i18n/client"; import { usePoll } from "../../poll-context"; import { toggleVote, VoteSelector } from "../vote-selector"; diff --git a/apps/web/src/components/poll/manage-poll/finalize-poll-dialog.tsx b/apps/web/src/components/poll/manage-poll/finalize-poll-dialog.tsx index 033ccd475..2f171411a 100644 --- a/apps/web/src/components/poll/manage-poll/finalize-poll-dialog.tsx +++ b/apps/web/src/components/poll/manage-poll/finalize-poll-dialog.tsx @@ -19,7 +19,6 @@ import { } from "@rallly/ui/form"; import { RadioGroup, RadioGroupItem } from "@rallly/ui/radio-group"; import dayjs from "dayjs"; -import { Trans } from "next-i18next"; import React from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; @@ -27,6 +26,7 @@ import { z } from "zod"; import { DateIconInner } from "@/components/date-icon"; import { useParticipants } from "@/components/participants-provider"; import { ConnectedScoreSummary } from "@/components/poll/score-summary"; +import { Trans } from "@/components/trans"; import { VoteSummaryProgressBar } from "@/components/vote-summary-progress-bar"; import { usePoll } from "@/contexts/poll"; import { trpc } from "@/trpc/client"; diff --git a/apps/web/src/components/poll/manage-poll/use-csv-exporter.ts b/apps/web/src/components/poll/manage-poll/use-csv-exporter.ts index db73156db..605cd1a74 100644 --- a/apps/web/src/components/poll/manage-poll/use-csv-exporter.ts +++ b/apps/web/src/components/poll/manage-poll/use-csv-exporter.ts @@ -1,7 +1,7 @@ import dayjs from "dayjs"; -import { useTranslation } from "next-i18next"; import { useOptions, usePoll } from "@/components/poll-context"; +import { useTranslation } from "@/i18n/client"; import { useParticipants } from "../../participants-provider"; diff --git a/apps/web/src/components/poll/mobile-poll.tsx b/apps/web/src/components/poll/mobile-poll.tsx index 648c83f53..a3ccd7075 100644 --- a/apps/web/src/components/poll/mobile-poll.tsx +++ b/apps/web/src/components/poll/mobile-poll.tsx @@ -11,7 +11,6 @@ import { } from "@rallly/ui/select"; import { AnimatePresence, m } from "framer-motion"; import { MoreHorizontalIcon, PlusIcon, UsersIcon } from "lucide-react"; -import { useTranslation } from "next-i18next"; import * as React from "react"; import smoothscroll from "smoothscroll-polyfill"; @@ -24,6 +23,7 @@ import { YouAvatar } from "@/components/poll/you-avatar"; import { useOptions, usePoll } from "@/components/poll-context"; import { Trans } from "@/components/trans"; import { usePermissions } from "@/contexts/permissions"; +import { useTranslation } from "@/i18n/client"; import { useVisibleParticipants } from "../participants-provider"; import { useUser } from "../user-provider"; diff --git a/apps/web/src/components/poll/notifications-toggle.tsx b/apps/web/src/components/poll/notifications-toggle.tsx index 0160cd6a4..88aa7b3cb 100644 --- a/apps/web/src/components/poll/notifications-toggle.tsx +++ b/apps/web/src/components/poll/notifications-toggle.tsx @@ -4,12 +4,12 @@ import { Icon } from "@rallly/ui/icon"; import { Tooltip, TooltipContent, TooltipTrigger } from "@rallly/ui/tooltip"; import { BellOffIcon, BellRingIcon } from "lucide-react"; import { signIn } from "next-auth/react"; -import { useTranslation } from "next-i18next"; import * as React from "react"; import { Skeleton } from "@/components/skeleton"; import { Trans } from "@/components/trans"; import { useUser } from "@/components/user-provider"; +import { useTranslation } from "@/i18n/client"; import { trpc } from "@/trpc/client"; import { usePoll } from "../poll-context"; diff --git a/apps/web/src/components/pro-badge.tsx b/apps/web/src/components/pro-badge.tsx index 90b1ab4c8..17068626b 100644 --- a/apps/web/src/components/pro-badge.tsx +++ b/apps/web/src/components/pro-badge.tsx @@ -1,5 +1,6 @@ import { Badge } from "@rallly/ui/badge"; -import { Trans } from "next-i18next"; + +import { Trans } from "@/components/trans"; export const ProBadge = ({ className }: { className?: string }) => { return ( diff --git a/apps/web/src/components/settings/language-preference.tsx b/apps/web/src/components/settings/language-preference.tsx index 6768dde83..e948c8832 100644 --- a/apps/web/src/components/settings/language-preference.tsx +++ b/apps/web/src/components/settings/language-preference.tsx @@ -3,13 +3,13 @@ import { Form, FormField, FormItem, FormLabel } from "@rallly/ui/form"; import { ArrowUpRight } from "lucide-react"; import Link from "next/link"; import { useRouter } from "next/navigation"; -import { useTranslation } from "next-i18next"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { LanguageSelect } from "@/components/poll/language-selector"; import { Trans } from "@/components/trans"; import { usePreferences } from "@/contexts/preferences"; +import { useTranslation } from "@/i18n/client"; const formSchema = z.object({ language: z.string(), diff --git a/apps/web/src/components/steps/steps.tsx b/apps/web/src/components/steps/steps.tsx index 25611cff4..5b72cdfb6 100644 --- a/apps/web/src/components/steps/steps.tsx +++ b/apps/web/src/components/steps/steps.tsx @@ -1,7 +1,8 @@ import { cn } from "@rallly/ui"; -import { useTranslation } from "next-i18next"; import React from "react"; +import { useTranslation } from "@/i18n/client"; + export interface StepsProps { current: number; total: number; diff --git a/apps/web/src/components/time-zone-picker/time-zone-select.tsx b/apps/web/src/components/time-zone-picker/time-zone-select.tsx index 70f7accf0..1b220ff17 100644 --- a/apps/web/src/components/time-zone-picker/time-zone-select.tsx +++ b/apps/web/src/components/time-zone-picker/time-zone-select.tsx @@ -16,10 +16,10 @@ import { useDialog } from "@rallly/ui/dialog"; import { Icon } from "@rallly/ui/icon"; import dayjs from "dayjs"; import { CheckIcon, GlobeIcon } from "lucide-react"; -import { useTranslation } from "next-i18next"; import React from "react"; import { Trans } from "@/components/trans"; +import { useTranslation } from "@/i18n/client"; import { groupedTimeZones } from "@/utils/grouped-time-zone"; interface TimeZoneCommandProps { diff --git a/apps/web/src/components/upgrade-button.tsx b/apps/web/src/components/upgrade-button.tsx index 566af933b..4dca33e54 100644 --- a/apps/web/src/components/upgrade-button.tsx +++ b/apps/web/src/components/upgrade-button.tsx @@ -1,9 +1,10 @@ import { usePostHog } from "@rallly/posthog/client"; import { Button } from "@rallly/ui/button"; import Link from "next/link"; -import { Trans } from "next-i18next"; import React from "react"; +import { Trans } from "@/components/trans"; + export const UpgradeButton = ({ children, annual, diff --git a/apps/web/src/utils/form-validation.ts b/apps/web/src/utils/form-validation.ts index 2ac9b305e..3c3f64329 100644 --- a/apps/web/src/utils/form-validation.ts +++ b/apps/web/src/utils/form-validation.ts @@ -1,4 +1,4 @@ -import { useTranslation } from "next-i18next"; +import { useTranslation } from "@/i18n/client"; /** * @deprecated Use form validation hook instead diff --git a/yarn.lock b/yarn.lock index 46359da4d..07b053a54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2308,7 +2308,7 @@ resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.1.2", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.8", "@babel/runtime@^7.15.4", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.8", "@babel/runtime@^7.15.4", "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== @@ -2858,44 +2858,46 @@ dependencies: "@floating-ui/dom" "^1.2.7" -"@formatjs/ecma402-abstract@1.14.3": - version "1.14.3" - resolved "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.14.3.tgz" - integrity sha512-SlsbRC/RX+/zg4AApWIFNDdkLtFbkq3LNoZWXZCE/nHVKqoIJyaoQyge/I0Y38vLxowUn9KTtXgusLD91+orbg== +"@formatjs/ecma402-abstract@2.3.3": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.3.tgz#fbc7555c9e4fdd104cd5e23129fa3735be3ad0ba" + integrity sha512-pJT1OkhplSmvvr6i3CWTPvC/FGC06MbN5TNBfRO6Ox62AEz90eMq+dVvtX9Bl3jxCEkS0tATzDarRZuOLw7oFg== dependencies: - "@formatjs/intl-localematcher" "0.2.32" - tslib "^2.4.0" + "@formatjs/fast-memoize" "2.2.6" + "@formatjs/intl-localematcher" "0.6.0" + decimal.js "10" + tslib "2" -"@formatjs/fast-memoize@2.0.1": - version "2.0.1" - resolved "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.0.1.tgz" - integrity sha512-M2GgV+qJn5WJQAYewz7q2Cdl6fobQa69S1AzSM2y0P68ZDbK5cWrJIcPCO395Of1ksftGZoOt4LYCO/j9BKBSA== +"@formatjs/fast-memoize@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.6.tgz#fac0a84207a1396be1f1aa4ee2805b179e9343d1" + integrity sha512-luIXeE2LJbQnnzotY1f2U2m7xuQNj2DA8Vq4ce1BY9ebRZaoPB1+8eZ6nXpLzsxuW5spQxr7LdCg+CApZwkqkw== dependencies: - tslib "^2.4.0" + tslib "2" -"@formatjs/icu-messageformat-parser@2.3.1": - version "2.3.1" - resolved "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.3.1.tgz" - integrity sha512-knF2AkAKN4Upv4oIiKY4Wd/dLH68TNMPgV/tJMu/T6FP9aQwbv8fpj7U3lkyniPaNVxvia56Gxax8MKOjtxLSQ== +"@formatjs/icu-messageformat-parser@2.11.1": + version "2.11.1" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.1.tgz#59d69124b9cf3186800a576c0228947d10594347" + integrity sha512-o0AhSNaOfKoic0Sn1GkFCK4MxdRsw7mPJ5/rBpIqdvcC7MIuyUSW8WChUEvrK78HhNpYOgqCQbINxCTumJLzZA== dependencies: - "@formatjs/ecma402-abstract" "1.14.3" - "@formatjs/icu-skeleton-parser" "1.3.18" - tslib "^2.4.0" + "@formatjs/ecma402-abstract" "2.3.3" + "@formatjs/icu-skeleton-parser" "1.8.13" + tslib "2" -"@formatjs/icu-skeleton-parser@1.3.18": - version "1.3.18" - resolved "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.18.tgz" - integrity sha512-ND1ZkZfmLPcHjAH1sVpkpQxA+QYfOX3py3SjKWMUVGDow18gZ0WPqz3F+pJLYQMpS2LnnQ5zYR2jPVYTbRwMpg== +"@formatjs/icu-skeleton-parser@1.8.13": + version "1.8.13" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.13.tgz#5e8b1e1bb467c937735fecb4cb4b345932151a44" + integrity sha512-N/LIdTvVc1TpJmMt2jVg0Fr1F7Q1qJPdZSCs19unMskCmVQ/sa0H9L8PWt13vq+gLdLg1+pPsvBLydL1Apahjg== dependencies: - "@formatjs/ecma402-abstract" "1.14.3" - tslib "^2.4.0" + "@formatjs/ecma402-abstract" "2.3.3" + tslib "2" -"@formatjs/intl-localematcher@0.2.32": - version "0.2.32" - resolved "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.32.tgz" - integrity sha512-k/MEBstff4sttohyEpXxCmC3MqbUn9VvHGlZ8fauLzkbwXmVrEeyzS+4uhrvAk9DWU9/7otYWxyDox4nT/KVLQ== +"@formatjs/intl-localematcher@0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.6.0.tgz#33cf0d33279572c990e02ab75a93122569878082" + integrity sha512-4rB4g+3hESy1bHSBG3tDFaMY2CH67iT7yne1e+0CLTsGLDcmoEWWpJjjpWVaYgYfYuohIRuo0E+N536gd2ZHZA== dependencies: - tslib "^2.4.0" + tslib "2" "@hapi/hoek@^9.0.0": version "9.3.0" @@ -6408,14 +6410,6 @@ dependencies: "@types/unist" "*" -"@types/hoist-non-react-statics@^3.3.1": - version "3.3.1" - resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" - integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== - dependencies: - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - "@types/http-assert@*": version "1.5.3" resolved "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz" @@ -8111,11 +8105,6 @@ core-js-compat@^3.25.1: dependencies: browserslist "^4.21.5" -core-js@^3: - version "3.29.0" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.29.0.tgz" - integrity sha512-VG23vuEisJNkGl6XQmFJd3rEG/so/CNatqeE+7uZAwTSwFeB/qaO0be8xZYUNWprJ/GIwL8aMt9cj1kvbpTZhg== - core-js@^3.38.1: version "3.38.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.38.1.tgz#aa375b79a286a670388a1a363363d53677c0383e" @@ -8312,6 +8301,11 @@ decamelize@^1.1.0, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== +decimal.js@10: + version "10.5.0" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.5.0.tgz#0f371c7cf6c4898ce0afb09836db73cd82010f22" + integrity sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw== + decode-named-character-reference@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz" @@ -9963,7 +9957,7 @@ hast-util-whitespace@^3.0.0: dependencies: "@types/hast" "^3.0.0" -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -10037,22 +10031,17 @@ hyphenate-style-name@^1.0.3: resolved "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz" integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== -i18next-fs-backend@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/i18next-fs-backend/-/i18next-fs-backend-2.1.1.tgz" - integrity sha512-FTnj+UmNgT3YRml5ruRv0jMZDG7odOL/OP5PF5mOqvXud2vHrPOOs68Zdk6iqzL47cnnM0ZVkK2BAvpFeDJToA== - i18next-icu@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/i18next-icu/-/i18next-icu-2.3.0.tgz" integrity sha512-x+j7kd5nDJCfbU53uwsMfXD7ALPu5uv0bqjAMQ5nVvXRoj1L7gkmswKtM3XDWYo4YUHf1jznlhSdPyy0xEwU+Q== -i18next-resources-to-backend@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/i18next-resources-to-backend/-/i18next-resources-to-backend-1.1.4.tgz#d139ca0cacc270dcc90b7926e192f4cd5aa4db60" - integrity sha512-hMyr9AOmIea17AOaVe1srNxK/l3mbk81P7Uf3fdcjlw3ehZy3UNTd0OP3EEi6yu4J02kf9jzhCcjokz6AFlEOg== +i18next-resources-to-backend@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/i18next-resources-to-backend/-/i18next-resources-to-backend-1.2.1.tgz#fded121e63e3139ce839c9901b9449dbbea7351d" + integrity sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw== dependencies: - "@babel/runtime" "^7.21.5" + "@babel/runtime" "^7.23.2" i18next-scanner-typescript@^1.1.1: version "1.1.1" @@ -10214,15 +10203,15 @@ interpret@^1.0.0: resolved "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== -intl-messageformat@^10.3.4: - version "10.3.4" - resolved "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.3.4.tgz" - integrity sha512-/FxUIrlbPtuykSNX85CB5sp2FjLVeTmdD7TfRkVFPft2n4FgcSlAcilFytYiFAEmPHc+0PvpLCIPXeaGFzIvOg== +intl-messageformat@^10.7.15: + version "10.7.15" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.7.15.tgz#5cdc62139ef39ece1b083db32dae4d1c9fa5b627" + integrity sha512-LRyExsEsefQSBjU2p47oAheoKz+EOJxSLDdjOaEjdriajfHsMXOmV/EhMvYSg9bAgCUHasuAC+mcUBe/95PfIg== dependencies: - "@formatjs/ecma402-abstract" "1.14.3" - "@formatjs/fast-memoize" "2.0.1" - "@formatjs/icu-messageformat-parser" "2.3.1" - tslib "^2.4.0" + "@formatjs/ecma402-abstract" "2.3.3" + "@formatjs/fast-memoize" "2.2.6" + "@formatjs/icu-messageformat-parser" "2.11.1" + tslib "2" invariant@^2.2.4: version "2.2.4" @@ -11653,17 +11642,6 @@ next-auth@^5.0.0-beta.25: dependencies: "@auth/core" "0.37.2" -next-i18next@^13.0.3: - version "13.1.6" - resolved "https://registry.npmjs.org/next-i18next/-/next-i18next-13.1.6.tgz" - integrity sha512-Lgr3s3L20nAev9eJSdrXiZGZjKK69ZtH5xvu2307GfseSDtXNsZvqjNDBgucULBIbzxCsp/pmo21DdCLEUsFaw== - dependencies: - "@babel/runtime" "^7.20.13" - "@types/hoist-non-react-statics" "^3.3.1" - core-js "^3" - hoist-non-react-statics "^3.3.2" - i18next-fs-backend "^2.1.1" - next-mdx-remote@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/next-mdx-remote/-/next-mdx-remote-5.0.0.tgz#028a2cf5cf7f814d988d7ab11a401bed0f31b4ee" @@ -14130,6 +14108,11 @@ tsconfig-paths@^3.14.1, tsconfig-paths@^3.14.2: minimist "^1.2.6" strip-bom "^3.0.0" +tslib@2: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + tslib@^1.11.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"