diff --git a/.all-contributorsrc b/.all-contributorsrc index 85561970be5..f210c1310a7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -12697,6 +12697,24 @@ "contributions": [ "content" ] + }, + { + "login": "jenish-thapa", + "name": "Jenish Thapa", + "avatar_url": "https://avatars.githubusercontent.com/u/141203631?v=4", + "profile": "https://github.com/jenish-thapa", + "contributions": [ + "ideas" + ] + }, + { + "login": "iusx", + "name": "iusx", + "avatar_url": "https://avatars.githubusercontent.com/u/57232813?v=4", + "profile": "https://jiangxue.org/~ritsu", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/.env.example b/.env.example index 08e8ef5b97d..b16d4a8b822 100644 --- a/.env.example +++ b/.env.example @@ -29,7 +29,7 @@ IS_PREVIEW_DEPLOY=false # Build pages only for the specified langs. Leave it empty to build all the langs # e.g. `en,fr` will only build English and French pages # Note: always include `en` as it is the default lang of the site -BUILD_LOCALES= +NEXT_PUBLIC_BUILD_LOCALES= # If resource constraints are being hit during builds, change LIMIT_CPUS to a # fixed number of CPUs (e.g. 2) to limit the demand during build time diff --git a/.eslintrc.json b/.eslintrc.json index c8813d5bbf6..02e6c67aab5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,8 +23,6 @@ // Packages. `react` related packages come first. // Also, put `react-icons` in sorting order not with `react` ["^react(?!-.)$", "^\\w", "^@\\w"], - // The Chakra theme directory if imported to story file or other places - ["^@/@chakra-ui"], // From the `types` directory. ["^@/lib/types", "^@/lib/interfaces"], // From the `components` directory. @@ -65,17 +63,6 @@ "varsIgnorePattern": "^_$" } ], - "unused-imports/no-unused-imports-ts": "warn", - "no-restricted-imports": [ - "warn", - { - "paths": [ - { - "name": "react-i18next", - "message": "Please use next-i18next instead of react-i18next." - } - ] - } - ] + "unused-imports/no-unused-imports-ts": "warn" } } diff --git a/.github/ISSUE_TEMPLATE/suggest_quiz.yaml b/.github/ISSUE_TEMPLATE/suggest_quiz.yaml index 7ca8c1d7b93..af037b47770 100644 --- a/.github/ISSUE_TEMPLATE/suggest_quiz.yaml +++ b/.github/ISSUE_TEMPLATE/suggest_quiz.yaml @@ -1,5 +1,5 @@ name: Suggest quiz -description: Add, update, delete questions for a quiz on ethereum.osg +description: Add, update, delete questions for a quiz on ethereum.org title: Add/Update/Delete quiz question labels: ["feature ✨", "quiz 📚"] body: diff --git a/.github/labeler.yml b/.github/labeler.yml index e6d58364be9..db08d5281e7 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -16,7 +16,6 @@ "config ⚙️": - i18n.config.json - next.config.js - - next-i18next.config,js - next-sitemap.config.js - tsconfig.json - .nvmrc diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 3054c265b98..7422a81a40f 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -15,7 +15,6 @@ on: - "src/components/**/*" - "src/pages/**/*" - "src/layouts/**/*" - - "src/@chakra-ui/**/*" - ".storybook/**/*" - "tailwind.config.ts" - "src/styles/**/*" diff --git a/.storybook/ChakraDecorator.tsx b/.storybook/ChakraDecorator.tsx deleted file mode 100644 index dbde5985d55..00000000000 --- a/.storybook/ChakraDecorator.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { useEffect, useMemo, useState } from "react" -import { - ChakraBaseProvider, - extendBaseTheme, - useColorMode, -} from "@chakra-ui/react" -import type { Decorator } from "@storybook/react" - -import theme from "../src/@chakra-ui/theme" - -import i18n from "./i18next" - -type DecoratorProps = Parameters - -const ColorModeSync = ({ context }: { context: DecoratorProps[1] }) => { - const { setColorMode } = useColorMode() - - useEffect(() => { - const isDarkMode = localStorage.getItem("chakra-ui-color-mode") === "dark" - - context.globals.colorMode = isDarkMode ? "dark" : "light" - }, []) - - useEffect(() => { - setColorMode(context.globals.colorMode) - }, [setColorMode, context]) - - return null -} - -/** - * This is a custom local setup of the official Chakra UI Storybook addon. - * - * A local version was created in response to provide a better sync between - * updated local direction to the Chakra theme. - * - * (This would most likely not be updated in the addon due to ongoing creation of Chakra v3 at the time this - * setup was created.) - * - * Will be deprecated and removed when Chakra v3 is available for migration. - * - */ -export const ChakraDecorator: Decorator = (getStory, context) => { - const [dir, updateDir] = useState<"ltr" | "rtl">() - - i18n.on("languageChanged", (locale) => { - const direction = i18n.dir(locale) - document.documentElement.dir = direction - updateDir(direction) - }) - - const themeWithDirectionOverride = useMemo(() => { - return extendBaseTheme({ direction: dir }, theme) - }, [dir]) - - return ( - - <> - - {getStory(context)} - - - ) -} diff --git a/.storybook/main.ts b/.storybook/main.ts index 02d785aefdc..e0f73e81f1c 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,5 +1,4 @@ import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin" -import { propNames } from "@chakra-ui/react" import type { StorybookConfig } from "@storybook/nextjs" /** @@ -17,8 +16,8 @@ import type { StorybookConfig } from "@storybook/nextjs" const config: StorybookConfig = { stories: [ "../src/components/**/*.stories.{ts,tsx}", - "../src/@chakra-ui/stories/*.stories.tsx", "../src/layouts/stories/*.stories.tsx", + "../src/styles/*.stories.tsx", ], addons: [ "@storybook/addon-links", @@ -29,9 +28,9 @@ const config: StorybookConfig = { }, }, "@storybook/addon-interactions", - "storybook-react-i18next", "@storybook/addon-themes", "@chromatic-com/storybook", + "storybook-next-intl", ], staticDirs: ["../public"], framework: { @@ -41,11 +40,6 @@ const config: StorybookConfig = { docs: { autodocs: "tag", }, - refs: { - "@chakra-ui/react": { - disable: true, - }, - }, webpackFinal: async (config) => { config.module = config.module || {} config.module.rules = config.module.rules || [] @@ -79,23 +73,6 @@ const config: StorybookConfig = { typescript: { reactDocgenTypescriptOptions: { shouldExtractLiteralValuesFromEnum: true, - /** - * For handling bloated controls table of Chakra Props - * - * https://github.com/chakra-ui/chakra-ui/issues/2009#issuecomment-852793946 - */ - propFilter: (prop) => { - const excludedPropNames = propNames.concat([ - "as", - "apply", - "sx", - "__css", - ]) - const isStyledSystemProp = excludedPropNames.includes(prop.name) - const isHTMLElementProp = - prop.parent?.fileName.includes("node_modules") ?? false - return !(isStyledSystemProp || isHTMLElementProp) - }, }, reactDocgen: "react-docgen-typescript", diff --git a/.storybook/modes.ts b/.storybook/modes.ts index 086d07ab0d1..ed683104212 100644 --- a/.storybook/modes.ts +++ b/.storybook/modes.ts @@ -1,6 +1,6 @@ import pickBy from "lodash/pickBy" -import { baseLocales } from "./i18next" +import { baseLocales } from "./next-intl" import { breakpointSet } from "./preview" export const viewportModes = breakpointSet.reduce<{ diff --git a/.storybook/i18next.ts b/.storybook/next-intl.ts similarity index 71% rename from .storybook/i18next.ts rename to .storybook/next-intl.ts index a2fbde38908..4d2a7844b37 100644 --- a/.storybook/i18next.ts +++ b/.storybook/next-intl.ts @@ -1,7 +1,3 @@ -import i18n, { Resource } from "i18next" -// eslint-disable-next-line no-restricted-imports -import { initReactI18next } from "react-i18next" - export const baseLocales = { en: { title: "English", left: "En" }, zh: { title: "中国人", left: "Zh" }, @@ -32,7 +28,7 @@ const supportedLngs = Object.keys(baseLocales) /** * Taking the ns array and generating those files for each language available. */ -const resources: Resource = ns.reduce((acc, n) => { +const messagesByLocale = ns.reduce((acc, n) => { supportedLngs.forEach((lng) => { if (!acc[lng]) acc[lng] = {} @@ -57,16 +53,18 @@ const resources: Resource = ns.reduce((acc, n) => { return acc }, {}) -console.log("🚀 ~ constresources:Resource=ns.reduce ~ resources:", resources) +console.log( + "🚀 ~ constresources:Resource=ns.reduce ~ resources:", + messagesByLocale +) -i18n.use(initReactI18next).init({ - debug: true, - fallbackLng: "en", - interpolation: { escapeValue: false }, - react: { useSuspense: false }, - supportedLngs, - resources, - defaultNS: "common", -}) +const nextIntl = { + defaultLocale: "en", + messagesByLocale, + getMessageFallback: ({ key }: { key: string }) => { + const keyOnly = key.split(".").pop() + return keyOnly || key + }, +} -export default i18n +export default nextIntl diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 191fa7888d7..1095a3011c2 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -5,7 +5,7 @@ import type { Preview } from "@storybook/react" import ThemeProvider from "@/components/ThemeProvider" import { TooltipProvider } from "@/components/ui/tooltip" -import i18n, { baseLocales } from "./i18next" +import nextIntl, { baseLocales } from "./next-intl" import { withNextThemes } from "./withNextThemes" import "../src/styles/global.css" @@ -47,7 +47,7 @@ const preview: Preview = { ), ], parameters: { - i18n, + nextIntl, controls: { matchers: { color: /(background|color)$/i, diff --git a/.storybook/types.ts b/.storybook/types.ts deleted file mode 100644 index 1b8116ee78a..00000000000 --- a/.storybook/types.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { StyleConfig, ThemingProps } from "@chakra-ui/react" -import type { ArgTypes } from "@storybook/react" - -// Type declarations below pulled directly from `@chakra-ui/storybook-addon` -// with some alteration -// (Subject to deprecation and removal upon release of Chakra v3) - -/** - * `keyof` alternative which omits non-string keys - */ -type KeyOf = [T] extends [never] - ? never - : T extends object - ? Extract - : never - -export type ThemingArgTypeKey = "variant" | "size" - -/** - * Create Storybook controls based on a Chakra UI theme component. - * - * @example - * export default { - * title: "Components / Forms / Button", - * argTypes: getThemingArgTypes(theme, "Button"), - * } - * - * @example full example - * import { Meta, StoryFn } from "@storybook/react" - * import { getThemingArgTypes } from "@chakra-ui/storybook-addon" - * import { theme } from "" - * - * export default { - * title: "Components / Forms / Button", - * argTypes: { - * ...getThemingArgTypes(theme, "Button"), - * children: "string" - * }, - * args: { children: "Button" }, - * } as Meta - * - * interface StoryProps extends ThemingProps<"Button"> { - * children?: React.ReactNode - * } - * - * export const Basic: StoryFn = (props) => + ) }, diff --git a/src/components/CentralizedExchanges/index.tsx b/src/components/CentralizedExchanges/index.tsx index 555e3c6bdd1..3c2bb2ff3ff 100644 --- a/src/components/CentralizedExchanges/index.tsx +++ b/src/components/CentralizedExchanges/index.tsx @@ -1,5 +1,4 @@ -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" import type { ChildOnlyProp, Lang } from "@/lib/types" @@ -14,6 +13,7 @@ import { WEBSITE_EMAIL } from "@/lib/constants" import Select from "../Select" import { useCentralizedExchanges } from "@/hooks/useCentralizedExchanges" +import { useTranslation } from "@/hooks/useTranslation" const ListContainer = (props: ChildOnlyProp) => (
@@ -66,7 +66,7 @@ const CentralizedExchanges = ({ lastDataUpdateDate, }: CentralizedExchangesProps) => { const { t } = useTranslation("page-get-eth") - const { locale } = useRouter() + const locale = useLocale() const { selectOptions, handleSelectChange, @@ -84,7 +84,7 @@ const CentralizedExchanges = ({

{t("page-get-eth-exchanges-intro")}

-
+
- +

+ {String.fromCharCode(97 + index).toUpperCase()} +

+ + {label} + + ) } diff --git a/src/components/Quiz/QuizWidget/QuizSummary.tsx b/src/components/Quiz/QuizWidget/QuizSummary.tsx index f005385614d..c223a879963 100644 --- a/src/components/Quiz/QuizWidget/QuizSummary.tsx +++ b/src/components/Quiz/QuizWidget/QuizSummary.tsx @@ -1,5 +1,4 @@ -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" import { HStack, VStack } from "@/components/ui/flex" @@ -8,6 +7,7 @@ import { numberToPercent } from "@/lib/utils/numberToPercent" import { screens } from "@/lib/utils/screen" import { useMediaQuery } from "@/hooks/useMediaQuery" +import { useTranslation } from "@/hooks/useTranslation" type QuizSummaryProps = { numberOfCorrectAnswers: number @@ -22,7 +22,7 @@ export const QuizSummary = ({ ratioCorrect, isPassingScore, }: QuizSummaryProps) => { - const { locale } = useRouter() + const locale = useLocale() const { t } = useTranslation("learn-quizzes") const [largerThanMobile] = useMediaQuery([`(min-width: ${screens.sm})`]) diff --git a/src/components/Quiz/QuizWidget/useQuizWidget.tsx b/src/components/Quiz/QuizWidget/useQuizWidget.tsx index 9b7e1900db8..3a07b09c452 100644 --- a/src/components/Quiz/QuizWidget/useQuizWidget.tsx +++ b/src/components/Quiz/QuizWidget/useQuizWidget.tsx @@ -1,7 +1,6 @@ import { useEffect, useMemo, useState } from "react" import isChromatic from "chromatic" import shuffle from "lodash/shuffle" -import { useTranslation } from "next-i18next" import type { AnswerChoice, @@ -21,6 +20,8 @@ import { getNextQuiz } from "../utils" import { QuizWidgetProps } from "." +import useTranslation from "@/hooks/useTranslation" + export type AnswerStatus = "correct" | "incorrect" | null export const useQuizWidget = ({ @@ -63,7 +64,7 @@ export const useQuizWidget = ({ setQuizData(quiz) } - useEffect(initialize, [quizKey, t]) + useEffect(initialize, [quizKey]) const currentQuestionIndex = userQuizProgress.length const showResults = currentQuestionIndex === quizData?.questions.length diff --git a/src/components/Quiz/QuizzesStats.tsx b/src/components/Quiz/QuizzesStats.tsx index 3ecd7d20874..23b4c51f0c4 100644 --- a/src/components/Quiz/QuizzesStats.tsx +++ b/src/components/Quiz/QuizzesStats.tsx @@ -1,5 +1,4 @@ -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" import { FaXTwitter } from "react-icons/fa6" import { CompletedQuizzes, QuizShareStats } from "@/lib/types" @@ -21,6 +20,8 @@ import { shareOnTwitter, } from "./utils" +import { useTranslation } from "@/hooks/useTranslation" + const handleShare = ({ score, total }: QuizShareStats) => { shareOnTwitter({ score, @@ -45,7 +46,7 @@ const QuizzesStats = ({ averageScoresArray, completedQuizzes, }: QuizzesStatsProps) => { - const { locale } = useRouter() + const locale = useLocale() const { t } = useTranslation("learn-quizzes") const numberOfCompletedQuizzes = getNumberOfCompletedQuizzes(completedQuizzes) @@ -146,10 +147,7 @@ const QuizzesStats = ({ - + {/* Data from Matomo, manually updated */} {value} diff --git a/src/components/Quiz/stories/QuizButtonGroup.stories.tsx b/src/components/Quiz/stories/QuizButtonGroup.stories.tsx index 477ba87fce3..319431e21f9 100644 --- a/src/components/Quiz/stories/QuizButtonGroup.stories.tsx +++ b/src/components/Quiz/stories/QuizButtonGroup.stories.tsx @@ -1,10 +1,11 @@ +import { useTranslations } from "next-intl" import type { Meta, StoryObj } from "@storybook/react" import { fn } from "@storybook/test" import { QuizButtonGroup } from "../QuizWidget/QuizButtonGroup" import { QuizContent } from "../QuizWidget/QuizContent" -import { LAYER_2_QUIZ_TITLE, layer2Questions } from "./utils" +import { LAYER_2_QUIZ_TITLE_KEY, layer2Questions } from "./utils" const meta = { title: "Molecules / Display Content / Quiz / QuizWidget / ButtonGroup", @@ -18,7 +19,7 @@ const meta = { quizPageProps: false, quizScore: 0, showResults: false, - title: LAYER_2_QUIZ_TITLE, + title: LAYER_2_QUIZ_TITLE_KEY, userQuizProgress: [], handleReset: fn(), setCurrentQuestionAnswerChoice: fn(), @@ -26,11 +27,17 @@ const meta = { setUserQuizProgress: fn(), }, decorators: [ - (Story, { args }) => ( - - - - ), + (Story, { args }) => { + const t = useTranslations() + return ( + + + + ) + }, ], } satisfies Meta diff --git a/src/components/Quiz/stories/QuizProgressBar.stories.tsx b/src/components/Quiz/stories/QuizProgressBar.stories.tsx index 61005acc767..4f8121ef139 100644 --- a/src/components/Quiz/stories/QuizProgressBar.stories.tsx +++ b/src/components/Quiz/stories/QuizProgressBar.stories.tsx @@ -1,9 +1,8 @@ +import { useTranslations } from "next-intl" import type { Meta, StoryObj } from "@storybook/react" import allQuizzesData from "@/data/quizzes" -import { getTranslation } from "@/storybook-utils" - import { QuizContent } from "../QuizWidget/QuizContent" import { QuizProgressBar } from "../QuizWidget/QuizProgressBar" @@ -16,14 +15,18 @@ const meta = { questions: layer2Questions, }, decorators: [ - (Story, { args }) => ( - - - - ), + (Story, { args }) => { + const t = useTranslations() + + return ( + + + + ) + }, ], } satisfies Meta diff --git a/src/components/Quiz/stories/QuizRadioGroup.stories.tsx b/src/components/Quiz/stories/QuizRadioGroup.stories.tsx index 825becb30b5..025873374e0 100644 --- a/src/components/Quiz/stories/QuizRadioGroup.stories.tsx +++ b/src/components/Quiz/stories/QuizRadioGroup.stories.tsx @@ -1,20 +1,27 @@ +import { useTranslations } from "next-intl" import type { Meta, StoryObj } from "@storybook/react" import { expect, fireEvent, fn, within } from "@storybook/test" import { QuizContent } from "../QuizWidget/QuizContent" import { QuizRadioGroup } from "../QuizWidget/QuizRadioGroup" -import { LAYER_2_QUIZ_TITLE, layer2Questions } from "./utils" +import { LAYER_2_QUIZ_TITLE_KEY, layer2Questions } from "./utils" const meta = { title: "Molecules / Display Content / Quiz / QuizWidget / RadioGroup", component: QuizRadioGroup, decorators: [ - (Story, { args }) => ( - - - - ), + (Story, { args }) => { + const t = useTranslations() + return ( + + + + ) + }, ], } satisfies Meta diff --git a/src/components/Quiz/stories/QuizSummary.stories.tsx b/src/components/Quiz/stories/QuizSummary.stories.tsx index 034ef9927e9..2c3c99a7f77 100644 --- a/src/components/Quiz/stories/QuizSummary.stories.tsx +++ b/src/components/Quiz/stories/QuizSummary.stories.tsx @@ -1,9 +1,10 @@ +import { useTranslations } from "next-intl" import type { Meta, StoryObj } from "@storybook/react" import { QuizContent } from "../QuizWidget/QuizContent" import { QuizSummary } from "../QuizWidget/QuizSummary" -import { LAYER_2_QUIZ_TITLE, layer2Questions } from "./utils" +import { LAYER_2_QUIZ_TITLE_KEY, layer2Questions } from "./utils" const meta = { title: "Molecules / Display Content / Quiz / QuizWidget / Summary", @@ -12,11 +13,14 @@ const meta = { questionsLength: layer2Questions.length, }, decorators: [ - (Story) => ( - - - - ), + (Story) => { + const t = useTranslations() + return ( + + + + ) + }, ], } satisfies Meta diff --git a/src/components/Quiz/stories/QuizWidget.stories.tsx b/src/components/Quiz/stories/QuizWidget.stories.tsx index 20f6906eeaa..ea446371441 100644 --- a/src/components/Quiz/stories/QuizWidget.stories.tsx +++ b/src/components/Quiz/stories/QuizWidget.stories.tsx @@ -1,8 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react" import { expect, userEvent, waitFor, within } from "@storybook/test" -import { getTranslation } from "@/storybook-utils" - import { StandaloneQuizWidget } from "../QuizWidget" import { LAYER_2_QUIZ_KEY, layer2Questions } from "./utils" @@ -27,20 +25,21 @@ export default meta type Story = StoryObj export const AllCorrectQuestions: Story = { - play: async ({ canvasElement, step, args }) => { - const translatedQuizKey = getTranslation(args.quizKey, "common") - const translatedPassedQuiz = getTranslation("passed", "learn-quizzes") + play: async ({ canvasElement, step }) => { + // TODO: Fix this, the play function is not detecting i18n context + // const translatedQuizKey = t(`common.${args.quizKey}`) + // const translatedPassedQuiz = t("learn-quizzes.passed") const canvas = within(canvasElement) const quizWidget = canvas.getByTestId("quiz-widget") await expect(quizWidget).toBeInTheDocument() - await waitFor(() => - expect(canvas.getByTestId("answer-status-null")).toHaveTextContent( - translatedQuizKey - ) - ) + // await waitFor(() => + // expect(canvas.getByTestId("answer-status-null")).toHaveTextContent( + // translatedQuizKey + // ) + // ) await waitFor(() => expect(canvas.getByTestId("check-answer-button")).toBeDisabled() @@ -73,7 +72,7 @@ export const AllCorrectQuestions: Story = { }) await step("Check for successful results page", async () => { - await expect(canvasElement).toHaveTextContent(translatedPassedQuiz) + await expect(canvasElement).toHaveTextContent("100%") }) }, } diff --git a/src/components/Quiz/stories/QuizzesList.stories.tsx b/src/components/Quiz/stories/QuizzesList.stories.tsx index 755bd65c1af..d58e16f7ca9 100644 --- a/src/components/Quiz/stories/QuizzesList.stories.tsx +++ b/src/components/Quiz/stories/QuizzesList.stories.tsx @@ -1,3 +1,4 @@ +import { useTranslations } from "next-intl" import type { Meta, StoryObj } from "@storybook/react" import { fn } from "@storybook/test" @@ -5,8 +6,6 @@ import type { CompletedQuizzes } from "@/lib/types" import { ethereumBasicsQuizzes } from "@/data/quizzes" -import { getTranslation } from "@/storybook-utils" - import QuizzesListComponent from "../QuizzesList" /** @@ -20,8 +19,8 @@ const meta = { component: QuizzesListComponent, args: { content: ethereumBasicsQuizzes, - headingId: getTranslation("basics", "learn-quizzes"), - descriptionId: getTranslation("basics-description", "learn-quizzes"), + headingId: "learn-quizzes.basics", + descriptionId: "learn-quizzes.basics-description", userStats: { score: 0, average: [], @@ -50,5 +49,14 @@ export const OneCompletedQuiz: StoryObj = { }, }, }, - render: (args) => , + render: (args) => { + const t = useTranslations() + return ( + + ) + }, } diff --git a/src/components/Quiz/stories/utils.ts b/src/components/Quiz/stories/utils.ts index fee9f73ab55..1e46fcca982 100644 --- a/src/components/Quiz/stories/utils.ts +++ b/src/components/Quiz/stories/utils.ts @@ -1,13 +1,9 @@ import allQuizzesData from "@/data/quizzes" import questionBank from "@/data/quizzes/questionBank" -import { getTranslation } from "@/storybook-utils" - export const LAYER_2_QUIZ_KEY = "layer-2" as const -export const LAYER_2_QUIZ_TITLE = getTranslation( - allQuizzesData[LAYER_2_QUIZ_KEY].title -) +export const LAYER_2_QUIZ_TITLE_KEY = allQuizzesData[LAYER_2_QUIZ_KEY].title // TODO: Can a util be created to extract this question data here and in prod? export const layer2Questions = allQuizzesData[LAYER_2_QUIZ_KEY].questions.map( diff --git a/src/components/RandomAppList.tsx b/src/components/RandomAppList.tsx index c1926007587..c8ede5d204b 100644 --- a/src/components/RandomAppList.tsx +++ b/src/components/RandomAppList.tsx @@ -3,7 +3,7 @@ import shuffle from "lodash/shuffle" import type { TranslationKey } from "@/lib/types" -import InlineLink from "./Link" +import InlineLink from "./ui/Link" import Translation from "./Translation" interface App { diff --git a/src/components/Roadmap/RoadmapActionCard/RoadmapActionCard.stories.tsx b/src/components/Roadmap/RoadmapActionCard/RoadmapActionCard.stories.tsx index 314ff053bc5..bca59c5a8ba 100644 --- a/src/components/Roadmap/RoadmapActionCard/RoadmapActionCard.stories.tsx +++ b/src/components/Roadmap/RoadmapActionCard/RoadmapActionCard.stories.tsx @@ -1,4 +1,3 @@ -import { Box, SimpleGrid } from "@chakra-ui/react" import type { Meta, StoryObj } from "@storybook/react" import RoadmapActionCardComponent from "." @@ -8,13 +7,13 @@ const meta = { component: RoadmapActionCardComponent, decorators: [ (Story) => ( - +
- +
- +
- +
), ], } satisfies Meta diff --git a/src/components/Roadmap/RoadmapActionCard/index.tsx b/src/components/Roadmap/RoadmapActionCard/index.tsx index dedba08c862..1132d1d8d76 100644 --- a/src/components/Roadmap/RoadmapActionCard/index.tsx +++ b/src/components/Roadmap/RoadmapActionCard/index.tsx @@ -1,5 +1,5 @@ -import { ButtonLink } from "@/components/Buttons" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" +import { ButtonLink } from "@/components/ui/buttons/Button" import { Center, Flex } from "@/components/ui/flex" import { LinkBox } from "@/components/ui/link-box" import { LinkOverlay } from "@/components/ui/link-box" @@ -37,7 +37,7 @@ const RoadmapActionCard = ({ return (
- + {alt}

{title}

diff --git a/src/components/Roadmap/RoadmapImageContent.tsx b/src/components/Roadmap/RoadmapImageContent.tsx index 05420288bd6..b5398fef1e0 100644 --- a/src/components/Roadmap/RoadmapImageContent.tsx +++ b/src/components/Roadmap/RoadmapImageContent.tsx @@ -1,4 +1,4 @@ -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import { Center, Flex, Stack } from "@/components/ui/flex" import wallet from "@/public/images/wallet.png" @@ -14,7 +14,7 @@ const RoadmapImageContent = ({ children, title }: RoadmapImageContentProps) => ( {children}
- ( ({ className, ...props }, ref) => { const { t } = useTranslation("common") diff --git a/src/components/Search/SearchInputButton.tsx b/src/components/Search/SearchInputButton.tsx index fc278e2ad09..6505add78e9 100644 --- a/src/components/Search/SearchInputButton.tsx +++ b/src/components/Search/SearchInputButton.tsx @@ -1,11 +1,12 @@ import * as React from "react" -import { useTranslation } from "next-i18next" import { DocSearchButton } from "@docsearch/react" import { cn } from "@/lib/utils/cn" import { Button, type ButtonProps } from "../ui/buttons/Button" +import { useTranslation } from "@/hooks/useTranslation" + const SearchInputButton = React.forwardRef( ({ className, ...props }, ref) => { const { t } = useTranslation("common") diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index b1fefabda5c..aeda07fb849 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -1,7 +1,6 @@ import { useRef } from "react" import dynamic from "next/dynamic" -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" import { useDocSearchKeyboardEvents } from "@docsearch/react" import { DocSearchHit } from "@docsearch/react/dist/esm/types" import * as Portal from "@radix-ui/react-portal" @@ -11,6 +10,7 @@ import { sanitizeHitTitle } from "@/lib/utils/sanitizeHitTitle" import { sanitizeHitUrl } from "@/lib/utils/url" import { useDisclosure } from "@/hooks/useDisclosure" +import { useTranslation } from "@/hooks/useTranslation" const SearchModal = dynamic(() => import("./SearchModal")) @@ -22,7 +22,7 @@ const Search = ({ children }: Props) => { const disclosure = useDisclosure() const { isOpen, onOpen, onClose } = disclosure - const { locale } = useRouter() + const locale = useLocale() const searchButtonRef = useRef(null) const { t } = useTranslation("common") diff --git a/src/components/SideNav.tsx b/src/components/SideNav.tsx index 3e24f7090f8..8579f9d23cd 100644 --- a/src/components/SideNav.tsx +++ b/src/components/SideNav.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from "react" import { motion } from "framer-motion" -import { useTranslation } from "next-i18next" import { MdChevronRight } from "react-icons/md" import { ChildOnlyProp } from "@/lib/types" @@ -11,6 +10,8 @@ import docLinks from "../data/developer-docs-links.yaml" import { HStack } from "./ui/flex" import { BaseLink, LinkProps } from "./ui/Link" +import { useTranslation } from "@/hooks/useTranslation" + export const dropdownIconContainerVariant = { open: { rotate: 90, diff --git a/src/components/SideNavMobile.tsx b/src/components/SideNavMobile.tsx index 8532d4447ff..2f6f3f7939f 100644 --- a/src/components/SideNavMobile.tsx +++ b/src/components/SideNavMobile.tsx @@ -1,6 +1,5 @@ import React, { useState } from "react" import { AnimatePresence, motion } from "framer-motion" -import { useTranslation } from "next-i18next" import { MdChevronRight } from "react-icons/md" import type { ChildOnlyProp, TranslationKey } from "@/lib/types" @@ -15,6 +14,8 @@ import { type NavLinkProps as SideNavLinkProps, } from "./SideNav" +import { useTranslation } from "@/hooks/useTranslation" + // Traverse all links to find page id const getPageTitleId = ( href: string, diff --git a/src/components/Simulator/WalletHome/NFTList.tsx b/src/components/Simulator/WalletHome/NFTList.tsx index e9eff523ecc..153bc19e6af 100644 --- a/src/components/Simulator/WalletHome/NFTList.tsx +++ b/src/components/Simulator/WalletHome/NFTList.tsx @@ -1,4 +1,4 @@ -import { TwImage as Image } from "@/components/Image" +import { Image } from "@/components/Image" import { Flex, type FlexProps } from "@/components/ui/flex" import { cn } from "@/lib/utils/cn" diff --git a/src/components/Simulator/icons/EthTokenIcon.tsx b/src/components/Simulator/icons/EthTokenIcon.tsx index b225833aa14..e33ca3b15bc 100644 --- a/src/components/Simulator/icons/EthTokenIcon.tsx +++ b/src/components/Simulator/icons/EthTokenIcon.tsx @@ -1,6 +1,3 @@ -/* eslint-disable react/jsx-key */ -import React from "react" - import { createIconBase } from "@/components/icons/icon-base" export const EthTokenIcon = createIconBase({ @@ -9,15 +6,15 @@ export const EthTokenIcon = createIconBase({ className: "text-3xl/none fill-none", children: ( <> - + ), @@ -32,11 +29,11 @@ export const EthTokenIconGrayscale = createIconBase({ ), diff --git a/src/components/Simulator/index.tsx b/src/components/Simulator/index.tsx index be9768058b9..899d7e87f60 100644 --- a/src/components/Simulator/index.tsx +++ b/src/components/Simulator/index.tsx @@ -1,5 +1,5 @@ import { type ReactNode, useEffect, useMemo, useState } from "react" -import { useRouter } from "next/router" +import { useSearchParams } from "next/navigation" import { trackCustomEvent } from "@/lib/utils/matomo" @@ -18,7 +18,9 @@ import { Phone } from "./Phone" import { SimulatorModal } from "./SimulatorModal" import { Template } from "./Template" import type { PathId, SimulatorData } from "./types" -import { getValidPathId } from "./utils" +import { getValidPathId, isValidPathId } from "./utils" + +import { usePathname, useRouter } from "@/i18n/routing" type SimulatorProps = { children: ReactNode @@ -26,12 +28,14 @@ type SimulatorProps = { } export const Simulator = ({ children, data }: SimulatorProps) => { const router = useRouter() + const pathname = usePathname() + const searchParams = useSearchParams() // Track step const [step, setStep] = useState(0) // 0-indexed to use as array index // Track pathID - const pathId = getValidPathId(router.query.sim as string) + const pathId = getValidPathId(searchParams.get(PATH_ID_QUERY_PARAM)) const simulator: SimulatorDetails | null = pathId ? data[pathId] : null const totalSteps: number = simulator ? simulator.explanations.length : 0 @@ -39,8 +43,7 @@ export const Simulator = ({ children, data }: SimulatorProps) => { const isOpen = !!pathId const clearUrlParams = () => { - const pathWithoutParams = router.asPath.replace(/\?[^#]*/, "") - router.replace(pathWithoutParams) + router.replace(pathname, { scroll: false }) } // When simulator closed: log event, clear URL params and close modal @@ -59,7 +62,9 @@ export const Simulator = ({ children, data }: SimulatorProps) => { // Remove URL search param if invalid pathId useEffect(() => { setStep(0) - if (!pathId) clearUrlParams() + if (pathId && !isValidPathId(pathId)) { + clearUrlParams() + } // eslint-disable-next-line react-hooks/exhaustive-deps }, [pathId]) @@ -88,10 +93,15 @@ export const Simulator = ({ children, data }: SimulatorProps) => { const openPath = (id: PathId): void => { // Set new pathId in navigation - const params = new URLSearchParams() - params.set(PATH_ID_QUERY_PARAM, id) - const url = `?${params.toString()}#${SIMULATOR_ID}` - router.replace(url) + router.replace( + { + pathname, + query: { + [PATH_ID_QUERY_PARAM]: id, + }, + }, + { scroll: false } + ) } // Navigation object passed to child components diff --git a/src/components/Simulator/screens/ConnectWeb3/index.tsx b/src/components/Simulator/screens/ConnectWeb3/index.tsx index 8267e9b7ac5..7d2fdcb1209 100644 --- a/src/components/Simulator/screens/ConnectWeb3/index.tsx +++ b/src/components/Simulator/screens/ConnectWeb3/index.tsx @@ -8,7 +8,7 @@ import { import type { PhoneScreenProps } from "@/lib/types" -import { TwImage as Image } from "@/components/Image" +import { Image } from "@/components/Image" import { Button } from "@/components/ui/buttons/Button" import { Flex } from "@/components/ui/flex" diff --git a/src/components/Simulator/screens/SendReceive/ReceiveEther.tsx b/src/components/Simulator/screens/SendReceive/ReceiveEther.tsx index 4fa4d454dcd..19e92a06e1e 100644 --- a/src/components/Simulator/screens/SendReceive/ReceiveEther.tsx +++ b/src/components/Simulator/screens/SendReceive/ReceiveEther.tsx @@ -1,7 +1,7 @@ import { motion } from "framer-motion" import EthGlyph from "@/components/icons/eth-glyph-solid.svg" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import { Button } from "@/components/ui/buttons/Button" import { Flex } from "@/components/ui/flex" @@ -29,7 +29,7 @@ export const ReceiveEther = () => ( side="top" >
- { return pathIdString } -const isValidPathId = (pathIdString: string | null): pathIdString is PathId => { +export const isValidPathId = ( + pathIdString: string | null +): pathIdString is PathId => { return PATH_IDS.includes(pathIdString as PathId) } diff --git a/src/components/SkipLink.tsx b/src/components/SkipLink.tsx index bbfcf92243e..2314e92d61c 100644 --- a/src/components/SkipLink.tsx +++ b/src/components/SkipLink.tsx @@ -1,9 +1,9 @@ -import { useTranslation } from "next-i18next" - import { MAIN_CONTENT_ID } from "@/lib/constants" import { BaseLink } from "./ui/Link" +import { useTranslation } from "@/hooks/useTranslation" + export const SkipLink = () => { const { t } = useTranslation() return ( diff --git a/src/components/StablecoinAccordion/AccordionCustomItem.tsx b/src/components/StablecoinAccordion/AccordionCustomItem.tsx index d4d644f0189..0f2fffe8973 100644 --- a/src/components/StablecoinAccordion/AccordionCustomItem.tsx +++ b/src/components/StablecoinAccordion/AccordionCustomItem.tsx @@ -1,5 +1,4 @@ import { BaseHTMLAttributes, ReactNode, useState } from "react" -import { useTranslation } from "next-i18next" import type { ChildOnlyProp } from "@/lib/types" @@ -15,6 +14,8 @@ import { import { accordionButtonContent, CategoryNameType } from "./utils" +import { useTranslation } from "@/hooks/useTranslation" + type LeftColumnPanelElement = BaseHTMLAttributes export const LeftColumnPanel = ( diff --git a/src/components/StablecoinAccordion/index.tsx b/src/components/StablecoinAccordion/index.tsx index 2d58e75252f..892dc0dedd6 100644 --- a/src/components/StablecoinAccordion/index.tsx +++ b/src/components/StablecoinAccordion/index.tsx @@ -1,4 +1,3 @@ -import { useTranslation } from "next-i18next" import { MdArrowForward } from "react-icons/md" import { ChildOnlyProp, TranslationKey } from "@/lib/types" @@ -20,6 +19,8 @@ import { } from "./AccordionCustomItem" import { useStablecoinAccordion } from "./useStablecoinAccordion" +import { useTranslation } from "@/hooks/useTranslation" + const SectionTitle = (props: ChildOnlyProp) => (

) diff --git a/src/components/StablecoinAccordion/useStablecoinAccordion.ts b/src/components/StablecoinAccordion/useStablecoinAccordion.ts index 9d1259f3ce2..292f39d9c14 100644 --- a/src/components/StablecoinAccordion/useStablecoinAccordion.ts +++ b/src/components/StablecoinAccordion/useStablecoinAccordion.ts @@ -1,7 +1,6 @@ -import { useTranslation } from "next-i18next" - import { type CardProps } from "@/components/CardList" +import { useTranslation } from "@/hooks/useTranslation" import aaveImg from "@/public/images/dapps/aave.png" // -- borrow import compoundImg from "@/public/images/dapps/compound.png" diff --git a/src/components/StablecoinBoxGrid.tsx b/src/components/StablecoinBoxGrid.tsx index d7edc90905c..2ff712adcea 100644 --- a/src/components/StablecoinBoxGrid.tsx +++ b/src/components/StablecoinBoxGrid.tsx @@ -1,6 +1,4 @@ import { useState } from "react" -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" import { ChildOnlyProp } from "@/lib/types" @@ -13,6 +11,9 @@ import { isMobile } from "../lib/utils/isMobile" import Emoji from "./Emoji" +import { useTranslation } from "@/hooks/useTranslation" +import { useRouter } from "@/i18n/routing" + // Represent string as 32-bit integer const hashCode = (string: string): number => { let hash = 0 diff --git a/src/components/StablecoinsTable.tsx b/src/components/StablecoinsTable.tsx index 7fb2e9299b6..1e9973ecc8c 100644 --- a/src/components/StablecoinsTable.tsx +++ b/src/components/StablecoinsTable.tsx @@ -1,5 +1,3 @@ -import { useTranslation } from "next-i18next" - import { ButtonLink } from "./ui/buttons/Button" import { Flex } from "./ui/flex" import { @@ -12,6 +10,7 @@ import { } from "./ui/table" import { useRtlFlip } from "@/hooks/useRtlFlip" +import { useTranslation } from "@/hooks/useTranslation" export interface TableRow { name: string diff --git a/src/components/Staking/StakingCommunityCallout.tsx b/src/components/Staking/StakingCommunityCallout.tsx index f587f1e97a9..a7a31270fe5 100644 --- a/src/components/Staking/StakingCommunityCallout.tsx +++ b/src/components/Staking/StakingCommunityCallout.tsx @@ -1,5 +1,4 @@ import React from "react" -import { useTranslation } from "next-i18next" import CalloutBanner from "@/components/CalloutBanner" import { ButtonLink } from "@/components/ui/buttons/Button" @@ -7,6 +6,7 @@ import { Flex } from "@/components/ui/flex" import { trackCustomEvent } from "@/lib/utils/matomo" +import { useTranslation } from "@/hooks/useTranslation" import image from "@/public/images/enterprise-eth.png" export type StakingCommunityCalloutProps = diff --git a/src/components/Staking/StakingComparison.tsx b/src/components/Staking/StakingComparison.tsx index 77d205ad290..d8f13143062 100644 --- a/src/components/Staking/StakingComparison.tsx +++ b/src/components/Staking/StakingComparison.tsx @@ -1,5 +1,3 @@ -import { useTranslation } from "next-i18next" - import type { StakingPage, TranslationKey } from "@/lib/types" import { @@ -14,6 +12,8 @@ import { MatomoEventOptions, trackCustomEvent } from "@/lib/utils/matomo" import { Flex } from "../ui/flex" import InlineLink from "../ui/Link" +import { useTranslation } from "@/hooks/useTranslation" + interface DataType { title: TranslationKey linkText: TranslationKey diff --git a/src/components/Staking/StakingGuides.tsx b/src/components/Staking/StakingGuides.tsx index 4b207cef5cd..78eac599063 100644 --- a/src/components/Staking/StakingGuides.tsx +++ b/src/components/Staking/StakingGuides.tsx @@ -1,7 +1,7 @@ -import { useTranslation } from "next-i18next" - import CardList, { type CardProps } from "@/components/CardList" +import { useTranslation } from "@/hooks/useTranslation" + const StakingGuides = () => { const { t } = useTranslation("page-staking") diff --git a/src/components/Staking/StakingHierarchy.tsx b/src/components/Staking/StakingHierarchy.tsx index 4973b7e2c87..d871e794a32 100644 --- a/src/components/Staking/StakingHierarchy.tsx +++ b/src/components/Staking/StakingHierarchy.tsx @@ -1,5 +1,4 @@ import React, { HTMLAttributes } from "react" -import { useTranslation } from "next-i18next" import { IconBase } from "react-icons" import { ChildOnlyProp } from "@/lib/types" @@ -7,7 +6,6 @@ import { ChildOnlyProp } from "@/lib/types" import { cn } from "@/lib/utils/cn" import { trackCustomEvent } from "@/lib/utils/matomo" -import { ButtonLink } from "../Buttons" import { StakingGlyphCentralizedIcon, StakingGlyphCloudIcon, @@ -16,8 +14,11 @@ import { StakingGlyphTokenWalletIcon, } from "../icons/staking" import Translation from "../Translation" +import { ButtonLink } from "../ui/buttons/Button" import { Center, Flex, VStack } from "../ui/flex" +import { useTranslation } from "@/hooks/useTranslation" + type SectionGridProps = ChildOnlyProp const SectionGrid = ({ children }: SectionGridProps) => { @@ -134,7 +135,7 @@ const StakingHierarchy = () => { eventName: "clicked solo staking", }) }} - width={{ base: "100%", md: "auto" }} + className="max-md:w-full" > {t("page-staking-more-on-solo")} @@ -170,7 +171,7 @@ const StakingHierarchy = () => { eventName: "clicked staking as a service", }) }} - width={{ base: "100%", md: "auto" }} + className="max-md:w-full" > {t("page-staking-more-on-saas")} @@ -218,7 +219,7 @@ const StakingHierarchy = () => { eventName: "clicked pooled staking", }) }} - width={{ base: "100%", md: "auto" }} + className="max-md:w-full" > {t("page-staking-more-on-pools")} diff --git a/src/components/Staking/StakingHowSoloWorks.tsx b/src/components/Staking/StakingHowSoloWorks.tsx index efe4edc0e9b..9f99138eb2c 100644 --- a/src/components/Staking/StakingHowSoloWorks.tsx +++ b/src/components/Staking/StakingHowSoloWorks.tsx @@ -1,5 +1,5 @@ /* eslint-disable react/jsx-key */ -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import Translation from "@/components/Translation" import { Center } from "@/components/ui/flex" @@ -33,7 +33,7 @@ const StakingHowSoloWorks = () => { {item} ))} - +

) } diff --git a/src/components/Staking/StakingLaunchpadWidget.tsx b/src/components/Staking/StakingLaunchpadWidget.tsx index db099cf042d..f585adb547d 100644 --- a/src/components/Staking/StakingLaunchpadWidget.tsx +++ b/src/components/Staking/StakingLaunchpadWidget.tsx @@ -1,5 +1,4 @@ import { useState } from "react" -import { useTranslation } from "next-i18next" import { FaTools } from "react-icons/fa" import Translation from "@/components/Translation" @@ -11,6 +10,8 @@ import { trackCustomEvent } from "@/lib/utils/matomo" import Select, { type SelectOnChange } from "../Select" +import { useTranslation } from "@/hooks/useTranslation" + type StakingDataOption = { label: string; value: string } const StakingLaunchpadWidget = () => { diff --git a/src/components/Staking/StakingProductsCardGrid/StakingProductCard.tsx b/src/components/Staking/StakingProductsCardGrid/StakingProductCard.tsx index ae0bed01060..0e46a885e2f 100644 --- a/src/components/Staking/StakingProductsCardGrid/StakingProductCard.tsx +++ b/src/components/Staking/StakingProductsCardGrid/StakingProductCard.tsx @@ -1,4 +1,3 @@ -import { useTranslation } from "next-i18next" import type { ComponentType, ReactNode, SVGProps } from "react" import { @@ -14,6 +13,8 @@ import { Tag } from "@/components/ui/tag" import { FlagType, Product } from "./types" +import { useTranslation } from "@/hooks/useTranslation" + const getIconFromName = ( imageName: string ): ComponentType> => { diff --git a/src/components/Staking/StakingProductsCardGrid/useStakingProductsCardGrid.ts b/src/components/Staking/StakingProductsCardGrid/useStakingProductsCardGrid.ts index 5b26115b42d..06d3815741c 100644 --- a/src/components/Staking/StakingProductsCardGrid/useStakingProductsCardGrid.ts +++ b/src/components/Staking/StakingProductsCardGrid/useStakingProductsCardGrid.ts @@ -1,6 +1,5 @@ import { useEffect, useState } from "react" import { shuffle } from "lodash" -import { useColorModeValue } from "@chakra-ui/react" import stakingProducts from "@/data/staking-products.json" @@ -21,6 +20,8 @@ import { getTagProperties, } from "./utils" +import useColorModeValue from "@/hooks/useColorModeValue" + export const useStakingProductsCardGrid = ({ category, }: { diff --git a/src/components/Staking/StakingStatsBox.tsx b/src/components/Staking/StakingStatsBox.tsx index 5969239cb1d..5cc83623545 100644 --- a/src/components/Staking/StakingStatsBox.tsx +++ b/src/components/Staking/StakingStatsBox.tsx @@ -1,15 +1,17 @@ -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" import { MdInfoOutline } from "react-icons/md" import type { ChildOnlyProp, Lang, StakingStatsData } from "@/lib/types" -import InlineLink from "@/components/Link" import Tooltip from "@/components/Tooltip" import { Flex, VStack } from "@/components/ui/flex" import { getLocaleForNumberFormat } from "@/lib/utils/translations" +import InlineLink from "../ui/Link" + +import { useTranslation } from "@/hooks/useTranslation" + const Cell = ({ children }: ChildOnlyProp) => ( {children} ) @@ -38,7 +40,7 @@ type StakingStatsBoxProps = { data: StakingStatsData } const StakingStatsBox = ({ data }: StakingStatsBoxProps) => { - const { locale } = useRouter() + const locale = useLocale() const { t } = useTranslation("page-staking") const localeForStatsBoxNumbers = getLocaleForNumberFormat(locale! as Lang) diff --git a/src/components/Staking/WithdrawalCredentials.tsx b/src/components/Staking/WithdrawalCredentials.tsx index ae615e0311d..aa27fd95e55 100644 --- a/src/components/Staking/WithdrawalCredentials.tsx +++ b/src/components/Staking/WithdrawalCredentials.tsx @@ -1,5 +1,4 @@ import { ChangeEvent, FC, useMemo, useState } from "react" -import { useTranslation } from "next-i18next" import CopyToClipboard from "@/components/CopyToClipboard" import Emoji from "@/components/Emoji" @@ -13,6 +12,8 @@ import { Flex } from "../ui/flex" import Input from "../ui/input" import { Spinner } from "../ui/spinner" +import { useTranslation } from "@/hooks/useTranslation" + interface Validator { validatorIndex: number withdrawalCredentials: string @@ -94,7 +95,7 @@ const WithdrawalCredentials: FC = () => { {" "} {t("comp-withdrawal-credentials-upgraded-2")}{" "} diff --git a/src/components/Staking/WithdrawalsTabComparison.tsx b/src/components/Staking/WithdrawalsTabComparison.tsx index 45b4f896a27..18f6fdcb84d 100644 --- a/src/components/Staking/WithdrawalsTabComparison.tsx +++ b/src/components/Staking/WithdrawalsTabComparison.tsx @@ -1,5 +1,3 @@ -import { useTranslation } from "next-i18next" - import WithdrawalCredentials from "@/components/Staking/WithdrawalCredentials" import Translation from "@/components/Translation" import { ListItem, UnorderedList } from "@/components/ui/list" @@ -9,6 +7,8 @@ import { trackCustomEvent } from "@/lib/utils/matomo" import { ButtonLink } from "../ui/buttons/Button" +import { useTranslation } from "@/hooks/useTranslation" + const WithdrawalsTabComparison = () => { const { t } = useTranslation("page-staking") const handleMatomoEvent = (name: string): void => { diff --git a/src/components/StatsBoxGrid/useStatsBoxGrid.tsx b/src/components/StatsBoxGrid/useStatsBoxGrid.tsx index 4d6ab11bbbe..aaaf3ed1727 100644 --- a/src/components/StatsBoxGrid/useStatsBoxGrid.tsx +++ b/src/components/StatsBoxGrid/useStatsBoxGrid.tsx @@ -2,13 +2,14 @@ * TODO: Update metric for new homepage: * - [ ] Replace TVL DeFi with "Total value held on Ethereum" */ -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" import type { AllMetricData, Lang, StatsBoxMetric } from "@/lib/types" import { getLocaleForNumberFormat } from "@/lib/utils/translations" +import { useTranslation } from "@/hooks/useTranslation" + const formatLargeUSD = (value: number, locale: string): string => { return new Intl.NumberFormat(locale, { style: "currency", @@ -45,7 +46,7 @@ export const useStatsBoxGrid = ({ ethPrice, }: AllMetricData): StatsBoxMetric[] => { const { t } = useTranslation("page-index") - const { locale } = useRouter() + const locale = useLocale() const localeForNumberFormat = getLocaleForNumberFormat(locale! as Lang) diff --git a/src/components/TableOfContents/TableOfContents.stories.tsx b/src/components/TableOfContents/TableOfContents.stories.tsx index 9e2e923913e..8fd1284b5e1 100644 --- a/src/components/TableOfContents/TableOfContents.stories.tsx +++ b/src/components/TableOfContents/TableOfContents.stories.tsx @@ -1,9 +1,10 @@ -import { Stack } from "@chakra-ui/react" import { Meta, StoryObj } from "@storybook/react" import { ToCItem } from "@/lib/types" -import TableOfContents from "./" +import { Stack } from "../ui/flex" + +import TableOfContentsComponent from "./" const tocItems: ToCItem[] = [ { @@ -73,22 +74,26 @@ const tocItems: ToCItem[] = [ const meta = { title: "Molecules / Navigation / TableOfContents", + component: TableOfContentsComponent, parameters: { layout: "fullscreen", }, decorators: [ (Story) => ( - + ), ], -} satisfies Meta +} satisfies Meta export default meta type Story = StoryObj -export const Default: Story = { - render: () => , +export const TableOfContents: Story = { + args: { + items: tocItems, + maxDepth: 2, + }, } diff --git a/src/components/TableOfContents/TableOfContentsMobile.tsx b/src/components/TableOfContents/TableOfContentsMobile.tsx index fe962487250..605c1f2eeeb 100644 --- a/src/components/TableOfContents/TableOfContentsMobile.tsx +++ b/src/components/TableOfContents/TableOfContentsMobile.tsx @@ -1,5 +1,4 @@ import React from "react" -import { useTranslation } from "next-i18next" import { MdExpandMore } from "react-icons/md" import type { ToCItem } from "@/lib/types" @@ -13,6 +12,8 @@ import { import ItemsListMobile from "./ItemsListMobile" +import { useTranslation } from "@/hooks/useTranslation" + export type TableOfContentsMobileProps = { items?: Array maxDepth?: number diff --git a/src/components/TableOfContents/index.tsx b/src/components/TableOfContents/index.tsx index 526b7a98c54..cfd22572220 100644 --- a/src/components/TableOfContents/index.tsx +++ b/src/components/TableOfContents/index.tsx @@ -1,4 +1,3 @@ -import { useTranslation } from "next-i18next" import { FaGithub } from "react-icons/fa" import type { ToCItem } from "@/lib/types" @@ -11,6 +10,7 @@ import { cn } from "@/lib/utils/cn" import { ButtonLink } from "../ui/buttons/Button" import { useActiveHash } from "@/hooks/useActiveHash" +import { useTranslation } from "@/hooks/useTranslation" export type TableOfContentsProps = { items: Array diff --git a/src/components/ThemeProvider.tsx b/src/components/ThemeProvider.tsx index c5225546072..062bb87551f 100644 --- a/src/components/ThemeProvider.tsx +++ b/src/components/ThemeProvider.tsx @@ -1,45 +1,28 @@ -import { useMemo } from "react" -import merge from "lodash/merge" import { ThemeProvider as NextThemesProvider } from "next-themes" import type { ThemeProviderProps } from "next-themes/dist/types" -import { ChakraBaseProvider, createLocalStorageManager } from "@chakra-ui/react" - -import customTheme from "@/@chakra-ui/theme" import { COLOR_MODE_STORAGE_KEY } from "@/lib/constants" import { useLocaleDirection } from "@/hooks/useLocaleDirection" -const colorModeManager = createLocalStorageManager(COLOR_MODE_STORAGE_KEY) - /** * Primary theming wrapper for use with color mode. Uses the theme provider * from `next-themes`. * * Applied to _app.tsx as the main provider for the project, and supplied as the * primary decorator to Storybook. - * - * NOTE: This also includes the Chakra Provider. This will be removed after migration to ShadCN/Tailwind is complete */ const ThemeProvider = ({ children }: Pick) => { - const direction = useLocaleDirection() + useLocaleDirection() - const theme = useMemo(() => merge(customTheme, { direction }), [direction]) return ( - - {children} - + {children} ) } diff --git a/src/components/Tooltip/Tooltip.stories.tsx b/src/components/Tooltip/Tooltip.stories.tsx index 66638a9f22f..7beecaef1a6 100644 --- a/src/components/Tooltip/Tooltip.stories.tsx +++ b/src/components/Tooltip/Tooltip.stories.tsx @@ -1,9 +1,9 @@ import { RiInformationLine } from "react-icons/ri" -import { Box, Center } from "@chakra-ui/react" import { Meta, StoryObj } from "@storybook/react" -import InlineLink from "../Link" import Translation from "../Translation" +import { Center } from "../ui/flex" +import InlineLink from "../ui/Link" // TODO: remove `index` when we delete the old tooltip import TooltipComponent from "./index" @@ -21,9 +21,9 @@ const meta = { args: { content: , children: ( - + - + ), }, argTypes: { @@ -45,7 +45,7 @@ const meta = { }, decorators: [ (Story) => ( -
+
), diff --git a/src/components/TooltipLink.tsx b/src/components/TooltipLink.tsx index 837244a3e63..e02fa6e93f9 100644 --- a/src/components/TooltipLink.tsx +++ b/src/components/TooltipLink.tsx @@ -1,7 +1,7 @@ import React, { ReactNode } from "react" import GlossaryTooltip from "./Glossary/GlossaryTooltip" -import InlineLink from "./Link" +import InlineLink from "./ui/Link" interface Props { href?: string diff --git a/src/components/Translatathon/LocalCommunitiesList.tsx b/src/components/Translatathon/LocalCommunitiesList.tsx index 74de77d559a..317d44f3233 100644 --- a/src/components/Translatathon/LocalCommunitiesList.tsx +++ b/src/components/Translatathon/LocalCommunitiesList.tsx @@ -1,6 +1,5 @@ -import { ButtonLink } from "@/components/Buttons" - import Emoji from "../Emoji" +import { ButtonLink } from "../ui/buttons/Button" const localCommunitiesData = [ { @@ -90,7 +89,7 @@ export const LocalCommunitiesList = () => { Register here diff --git a/src/components/Translatathon/TranslatathonCalendar.tsx b/src/components/Translatathon/TranslatathonCalendar.tsx index c9d3719e013..5f9e103bfb8 100644 --- a/src/components/Translatathon/TranslatathonCalendar.tsx +++ b/src/components/Translatathon/TranslatathonCalendar.tsx @@ -1,4 +1,4 @@ -import { useRouter } from "next/router" +import { useLocale } from "next-intl" import { FaDiscord } from "react-icons/fa" import type { Lang } from "@/lib/types" @@ -53,7 +53,7 @@ const events = [ ] export const TranslatathonCalendar = () => { - const { locale } = useRouter() + const locale = useLocale() return ( diff --git a/src/components/Translatathon/TranslatathonInANutshell.tsx b/src/components/Translatathon/TranslatathonInANutshell.tsx index 62c360b8858..63361f3e8bd 100644 --- a/src/components/Translatathon/TranslatathonInANutshell.tsx +++ b/src/components/Translatathon/TranslatathonInANutshell.tsx @@ -1,4 +1,4 @@ -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import { ButtonLink } from "@/components/ui/buttons/Button" import { Flex } from "@/components/ui/flex" import Link from "@/components/ui/Link" @@ -23,7 +23,7 @@ export const TranslatathonInANutshell = () => {

- { - {

- { return ( diff --git a/src/components/Translatathon/TranslationHubCallout.tsx b/src/components/Translatathon/TranslationHubCallout.tsx index ed8f4561c44..48d00ff9e82 100644 --- a/src/components/Translatathon/TranslationHubCallout.tsx +++ b/src/components/Translatathon/TranslationHubCallout.tsx @@ -1,4 +1,4 @@ -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import { Center, Flex } from "@/components/ui/flex" import { ButtonLink } from "../ui/buttons/Button" @@ -17,7 +17,7 @@ export const TranslationHubCallout = ({ children }) => {
- { - const { asPath } = useRouter() - const requiredNamespaces = getRequiredNamespacesForPage(asPath) - - const { t } = useTranslation(requiredNamespaces) - const translatedText = t(id, options) +const Translation = ({ id, ns, values, transform = {} }: TranslationProps) => { + const { t } = useTranslation(ns) + const translatedText = t(id, values) // Custom components mapping to be used by `htmr` when parsing the translation // text diff --git a/src/components/TranslationBanner.tsx b/src/components/TranslationBanner.tsx index db28f087edb..af985b24f87 100644 --- a/src/components/TranslationBanner.tsx +++ b/src/components/TranslationBanner.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from "react" -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" import { MdClose } from "react-icons/md" import type { Lang } from "@/lib/types" @@ -13,6 +12,8 @@ import { isLangRightToLeft } from "@/lib/utils/translations" import Emoji from "./Emoji" +import { useTranslation } from "@/hooks/useTranslation" + export type TranslationBannerProps = { shouldShow: boolean originalPagePath: string @@ -26,7 +27,7 @@ const TranslationBanner = ({ }: TranslationBannerProps) => { const [isOpen, setIsOpen] = useState(shouldShow) const { t } = useTranslation("common") - const { locale } = useRouter() + const locale = useLocale() const dir = isLangRightToLeft(locale! as Lang) ? "rtl" : "ltr" useEffect(() => { diff --git a/src/components/TranslationChartImage/index.tsx b/src/components/TranslationChartImage/index.tsx index d7d5f8e07b7..b617c35de65 100644 --- a/src/components/TranslationChartImage/index.tsx +++ b/src/components/TranslationChartImage/index.tsx @@ -1,4 +1,4 @@ -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import useColorModeValue from "@/hooks/useColorModeValue" import pageviewsDark from "@/public/images/translation-program/pageviews-dark.png" @@ -8,7 +8,7 @@ const TranslationChartImage = () => { const ethImage = useColorModeValue(pageviewsLight, pageviewsDark) return ( - { return ( @@ -140,7 +141,7 @@ const TranslationLeaderboard = ({
- void isDecentralizedAndSecure: boolean diff --git a/src/components/Trilemma/index.tsx b/src/components/Trilemma/index.tsx index af0602b3a4c..1e82fce90db 100644 --- a/src/components/Trilemma/index.tsx +++ b/src/components/Trilemma/index.tsx @@ -1,5 +1,3 @@ -import { useTranslation } from "next-i18next" - import Card from "@/components/Card" import { Flex, Stack, VStack } from "@/components/ui/flex" import { Sheet, SheetClose, SheetContent } from "@/components/ui/sheet" @@ -7,6 +5,8 @@ import { Sheet, SheetClose, SheetContent } from "@/components/ui/sheet" import { TriangleSVG, TriangleSVGProps } from "./Triangle" import { useTrilemma } from "./useTrilemma" +import { useTranslation } from "@/hooks/useTranslation" + const Trilemma = () => { const { t } = useTranslation("page-roadmap-vision") diff --git a/src/components/Trilemma/useTrilemma.tsx b/src/components/Trilemma/useTrilemma.tsx index cbe2bb60b5d..5ec36e1fb02 100644 --- a/src/components/Trilemma/useTrilemma.tsx +++ b/src/components/Trilemma/useTrilemma.tsx @@ -1,10 +1,11 @@ import { useState } from "react" -import { useTranslation } from "next-i18next" import { isMobile } from "@/lib/utils/isMobile" import { CardProps } from "../Card" +import { useTranslation } from "@/hooks/useTranslation" + /** * The `selection` param accepted values for the click handler */ diff --git a/src/components/TutorialMetadata.tsx b/src/components/TutorialMetadata.tsx index 0fbb8307100..263bdd28476 100644 --- a/src/components/TutorialMetadata.tsx +++ b/src/components/TutorialMetadata.tsx @@ -1,20 +1,21 @@ -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" import type { Lang, TranslationKey } from "@/lib/types" import { TutorialFrontmatter } from "@/lib/interfaces" import CopyToClipboard from "@/components/CopyToClipboard" import Emoji from "@/components/Emoji" -import InlineLink from "@/components/Link" import Translation from "@/components/Translation" import TutorialTags from "@/components/TutorialTags" import { getLocaleTimestamp } from "@/lib/utils/time" import { Flex } from "./ui/flex" +import InlineLink from "./ui/Link" import { Tag } from "./ui/tag" +import { useTranslation } from "@/hooks/useTranslation" + export type TutorialMetadataProps = { frontmatter: TutorialFrontmatter timeToRead: number @@ -35,7 +36,7 @@ const TutorialMetadata = ({ frontmatter, timeToRead, }: TutorialMetadataProps) => { - const { locale } = useRouter() + const locale = useLocale() const { t } = useTranslation("page-developers-tutorials") const hasSource = frontmatter.source && frontmatter.sourceUrl diff --git a/src/components/UpcomingEventsList.tsx b/src/components/UpcomingEventsList.tsx index 107691f1b22..b6647600cb0 100644 --- a/src/components/UpcomingEventsList.tsx +++ b/src/components/UpcomingEventsList.tsx @@ -1,7 +1,6 @@ import { useEffect, useState } from "react" import _ from "lodash" -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" import type { CommunityConference, Lang } from "@/lib/types" @@ -15,8 +14,10 @@ import { getLocaleTimestamp } from "@/lib/utils/time" import communityEvents from "@/data/community-events.json" +import { useTranslation } from "@/hooks/useTranslation" + const UpcomingEventsList = () => { - const { locale } = useRouter() + const locale = useLocale() const { t } = useTranslation("page-community") const monthsPerLoad = 2 diff --git a/src/components/UpgradeStatus.tsx b/src/components/UpgradeStatus.tsx index 6cf191099bb..ece95d25b6b 100644 --- a/src/components/UpgradeStatus.tsx +++ b/src/components/UpgradeStatus.tsx @@ -1,9 +1,9 @@ -import { useTranslation } from "next-i18next" - import type { TranslationKey } from "@/lib/types" import { cn } from "@/lib/utils/cn" +import { useTranslation } from "@/hooks/useTranslation" + export type UpgradeStatusProps = { children?: React.ReactNode dateKey: TranslationKey diff --git a/src/components/icons/HighlightDarkIcon.tsx b/src/components/icons/HighlightDarkIcon.tsx index 5f83dc9a052..1d6548d31f9 100644 --- a/src/components/icons/HighlightDarkIcon.tsx +++ b/src/components/icons/HighlightDarkIcon.tsx @@ -1,14 +1,10 @@ -import * as React from "react" -import { createIcon } from "@chakra-ui/react" +import { createIconBase } from "./icon-base" -export const HighlightDarkIcon = createIcon({ +export const HighlightDarkIcon = createIconBase({ displayName: "HighlightDarkIcon", viewBox: "0 0 280 28", - defaultProps: { - width: "280px", - height: "28px", - }, - path: ( + className: "w-[280px] h-[28px]", + children: ( +} satisfies Meta export default meta @@ -197,15 +196,10 @@ iconsDefinitions.sort((a, b) => const items = iconsDefinitions.map((IconDef) => (
- +
{IconDef.displayName}
@@ -213,6 +207,10 @@ const items = iconsDefinitions.map((IconDef) => ( export const Icons: StoryObj = { render: () => { - return {items} + return ( +
+ {items} +
+ ) }, } diff --git a/src/components/ui/Link.tsx b/src/components/ui/Link.tsx index ec1df595401..531c5cd0577 100644 --- a/src/components/ui/Link.tsx +++ b/src/components/ui/Link.tsx @@ -1,6 +1,5 @@ -import { AnchorHTMLAttributes, forwardRef } from "react" -import NextLink, { type LinkProps as NextLinkProps } from "next/link" -import { useRouter } from "next/router" +import { AnchorHTMLAttributes, ComponentProps, forwardRef } from "react" +import NextLink from "next/link" import { RxExternalLink } from "react-icons/rx" import { VisuallyHidden } from "@radix-ui/react-visually-hidden" @@ -12,6 +11,8 @@ import * as url from "@/lib/utils/url" import { DISCORD_PATH, SITE_URL } from "@/lib/constants" import { useRtlFlip } from "@/hooks/useRtlFlip" +import { Link as I18nLink } from "@/i18n/routing" +import { usePathname } from "@/i18n/routing" type BaseProps = { hideArrow?: boolean @@ -22,7 +23,7 @@ type BaseProps = { export type LinkProps = BaseProps & AnchorHTMLAttributes & - Omit + Omit, "href"> /** * Link wrapper which handles: @@ -49,7 +50,7 @@ export const BaseLink = forwardRef(function Link( }: LinkProps, ref ) { - const { asPath } = useRouter() + const pathname = usePathname() const { twFlipForRtl } = useRtlFlip() if (!href) { @@ -57,17 +58,17 @@ export const BaseLink = forwardRef(function Link( return } - const isActive = url.isHrefActive(href, asPath, isPartiallyActive) + const isActive = url.isHrefActive(href, pathname || "", isPartiallyActive) const isDiscordInvite = url.isDiscordInvite(href) - const isPdf = url.isPdf(href) + const isFile = url.isFile(href) const isExternal = url.isExternal(href) - const isInternalPdf = isPdf && !isExternal + const isInternalFile = isFile && !isExternal const isHash = url.isHash(href) - // Get proper download link for internally hosted PDF's & static files (ex: whitepaper) + // Get proper download link for internally hosted files (ex: whitepaper.pdf) // Opens in separate window. - if (isInternalPdf) { - href = getRelativePath(asPath, href) + if (isInternalFile && !href.startsWith("/")) { + href = "/" + getRelativePath(pathname, href) } if (isDiscordInvite) { @@ -112,15 +113,11 @@ export const BaseLink = forwardRef(function Link( ) } - if (isInternalPdf) { + if (isInternalFile) { return ( trackCustomEvent( customEventOptions ?? { @@ -160,7 +157,7 @@ export const BaseLink = forwardRef(function Link( } return ( - trackCustomEvent( customEventOptions ?? { @@ -174,7 +171,7 @@ export const BaseLink = forwardRef(function Link( {...commonProps} > {children} - + ) }) BaseLink.displayName = "BaseLink" diff --git a/src/components/ui/__stories__/Link.stories.tsx b/src/components/ui/__stories__/Link.stories.tsx index f76526c7551..72da6edf602 100644 --- a/src/components/ui/__stories__/Link.stories.tsx +++ b/src/components/ui/__stories__/Link.stories.tsx @@ -1,15 +1,15 @@ -import * as React from "react" -import { Center, ListItem, Stack, Text, UnorderedList } from "@chakra-ui/react" import { Meta, StoryObj } from "@storybook/react" +import { Center, Stack } from "../flex" import Link from "../Link" +import { ListItem, UnorderedList } from "../list" const meta = { title: "Molecules / Navigation / Links", component: Link, decorators: [ (Story) => ( -
+
), @@ -21,12 +21,12 @@ export default meta type Story = StoryObj const MockParagraph = ({ href }: { href: string }) => ( - +

Text body normal. Ethereum is open access to digital money and data-friendly services for everyone – no matter your background or location. It's a community-built technology behind the cryptocurrency ether (ETH) and thousands of applications you can use today. - +

) export const InternalLink: Story = { @@ -45,14 +45,14 @@ export const ExternalLink: Story = { export const LinkList: Story = { render: () => ( - - + +

Text body normal. Ethereum is open access to digital money and data-friendly services for everyone – no matter your background or location. It's a community-built technology behind the cryptocurrency ether (ETH) and thousands of applications you can use today. - +

{Array.from({ length: 9 }).map((_, idx) => ( diff --git a/src/components/ui/__stories__/Table/Table.stories.tsx b/src/components/ui/__stories__/Table/Table.stories.tsx index 15480c28fba..9da2168a39b 100644 --- a/src/components/ui/__stories__/Table/Table.stories.tsx +++ b/src/components/ui/__stories__/Table/Table.stories.tsx @@ -1,7 +1,9 @@ -import * as React from "react" -import { Flex } from "@chakra-ui/react" +import type { CSSProperties } from "react" import { Meta, StoryObj } from "@storybook/react" +import { screens } from "@/lib/utils/screen" + +import { Flex } from "../../flex" import { Table as TableComponent } from "../../table" import { @@ -15,7 +17,10 @@ const meta = { component: TableComponent, decorators: [ (Story) => ( - + ), diff --git a/src/components/ui/__stories__/Table/mockMdxData.tsx b/src/components/ui/__stories__/Table/mockMdxData.tsx index 4802cf6e842..48a220a289c 100644 --- a/src/components/ui/__stories__/Table/mockMdxData.tsx +++ b/src/components/ui/__stories__/Table/mockMdxData.tsx @@ -10,16 +10,6 @@ import { TableRow, } from "../../table" -/* - * Note on the Chakra Table components: - * - * Only the `TableCell`, `Th`, `Tr`, `TableBody`, and `TableHeader` components are used because those are the - * only table elements we are defining styles with and sending to the MDX provider - * - * The use of `align` is a mock for the `align` prop from the MDX parsing going to - * the former prop in the given Chakra component. - */ - export const MdxDemoData = () => ( <> diff --git a/src/components/ui/__stories__/Text.stories.tsx b/src/components/ui/__stories__/Text.stories.tsx index ccd292b4378..2ed713992d0 100644 --- a/src/components/ui/__stories__/Text.stories.tsx +++ b/src/components/ui/__stories__/Text.stories.tsx @@ -3,9 +3,9 @@ import { Meta, StoryObj } from "@storybook/react" import { cn } from "@/lib/utils/cn" -import LinkComponent from "../../Link" import Translation from "../../Translation" import { Center, Flex, Stack, VStack } from "../flex" +import LinkComponent from "../Link" const meta = { title: "Atoms / Typography / Text", diff --git a/src/components/Buttons/SvgButtonLink.tsx b/src/components/ui/buttons/SvgButtonLink.tsx similarity index 91% rename from src/components/Buttons/SvgButtonLink.tsx rename to src/components/ui/buttons/SvgButtonLink.tsx index 001216b2722..1e13dd7e51e 100644 --- a/src/components/Buttons/SvgButtonLink.tsx +++ b/src/components/ui/buttons/SvgButtonLink.tsx @@ -1,11 +1,12 @@ -import { cva, VariantProps } from "class-variance-authority" import type { FC, SVGProps } from "react" +import { tv, type VariantProps } from "tailwind-variants" import { cn } from "@/lib/utils/cn" -import { BaseLink, LinkProps } from "../ui/Link" +import { BaseLink, LinkProps } from "../Link" -const variants = cva("flex items-center gap-3.5", { +const variants = tv({ + base: "flex items-center gap-3.5", variants: { variant: { col: "flex-col text-center [&_.body]:text-center", diff --git a/src/components/ui/swiper.tsx b/src/components/ui/swiper.tsx index 9c6ef00a843..e74bcac005c 100644 --- a/src/components/ui/swiper.tsx +++ b/src/components/ui/swiper.tsx @@ -1,6 +1,5 @@ import * as React from "react" import { cva, VariantProps } from "class-variance-authority" -import { useTranslation } from "next-i18next" import { EffectCards, Keyboard, Navigation, Pagination } from "swiper/modules" import { Swiper as SwiperReact, @@ -20,6 +19,8 @@ import "swiper/css/navigation" import "swiper/css/pagination" import "swiper/css/effect-cards" +import { useTranslation } from "@/hooks/useTranslation" + const SwiperContainer = React.forwardRef< HTMLDivElement, React.HTMLAttributes diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx index abce6ca20f9..d5cf6206d1e 100644 --- a/src/components/ui/switch.tsx +++ b/src/components/ui/switch.tsx @@ -28,6 +28,6 @@ const Switch = React.forwardRef< ) }) -Switch.displayName = SwitchPrimitives.Root.displayName +Switch.displayName = "Switch" export default Switch diff --git a/src/data/NetworkUpgradeSummaryData.ts b/src/data/NetworkUpgradeSummaryData.ts index 7e9bb46a68a..302044d376b 100644 --- a/src/data/NetworkUpgradeSummaryData.ts +++ b/src/data/NetworkUpgradeSummaryData.ts @@ -1,6 +1,9 @@ import type { NetworkUpgradeData } from "@/lib/types" const NetworkUpgradeSummaryData: NetworkUpgradeData = { + pectra: { + isPending: true, + }, dencun: { dateTimeAsString: "2024-03-13T13:55:35.000Z", ethPriceInUSD: 3984, diff --git a/src/data/WalletSimulatorData.tsx b/src/data/WalletSimulatorData.tsx index b851087ee8b..24ecc556729 100644 --- a/src/data/WalletSimulatorData.tsx +++ b/src/data/WalletSimulatorData.tsx @@ -1,9 +1,9 @@ import { Stack } from "@/components/ui/flex" +import Link from "@/components/ui/Link" import { ListItem, OrderedList, UnorderedList } from "@/components/ui/list" import Emoji from "../components/Emoji" import GlossaryTooltip from "../components/Glossary/GlossaryTooltip" -import Link from "../components/Link" import { CONNECT_WEB3, CREATE_ACCOUNT, @@ -337,7 +337,7 @@ export const walletOnboardingSimData: SimulatorData = { <>

Your wallet can be used to connect to all sorts of applications, - allowing you to interact with your on-chain assets. + allowing you to interact with your onchain assets.

Your friend just sent an NFT art piece to your address! Let's @@ -354,7 +354,7 @@ export const walletOnboardingSimData: SimulatorData = { Your account is universal across all Ethereum and Ethereum-compatible applications.

-

Assets stored on-chain can be accessed from any application.

+

Assets stored onchain can be accessed from any application.

), }, diff --git a/src/data/chains.ts b/src/data/chains.ts index bb6f3691a8b..948a5fa472a 100644 --- a/src/data/chains.ts +++ b/src/data/chains.ts @@ -252,6 +252,17 @@ const chains = [ }, chain: "FETH", }, + { + name: "Unichain", + infoURL: "https://unichain.org", + chainId: 130, + nativeCurrency: { + name: "Ether", + symbol: "ETH", + decimals: 18, + }, + chain: "ETH", + }, { name: "Defi Oracle Meta Mainnet", infoURL: "https://info.defi-oracle.io/", @@ -1594,6 +1605,17 @@ const chains = [ }, chain: "henez", }, + { + name: "Lumoz Chain Mainnet", + infoURL: "https://lumoz.org", + chainId: 96370, + nativeCurrency: { + name: "Lumoz Mainnet Token", + symbol: "MOZ", + decimals: 18, + }, + chain: "ETH", + }, { name: "Plume Devnet", infoURL: "https://plumenetwork.xyz/", diff --git a/src/data/community-events.json b/src/data/community-events.json index b48f24a5de1..2f770e57b72 100644 --- a/src/data/community-events.json +++ b/src/data/community-events.json @@ -42,7 +42,7 @@ "href": "https://ethkyiv.com", "location": "Kyiv, Ukraine", "description": "Welcome to the 1st edition of ETHKyiv, hosted this June 21-23 and bringing together participants from diverse backgrounds, including developers, designers, entrepreneurs, and blockchain enthusiasts!", - "imageUrl": "" + "imageUrl": "https://ethkyiv.com/_next/image?url=%2Fimages%2Fmain-banner_01.png&w=1920&q=75" }, { "title": "DappCon", @@ -237,7 +237,7 @@ "title": "BUIDL Asia", "startDate": "2025-04-15", "endDate": "2025-04-16", - "href": "https://-", + "href": "https://www.buidl.asia/", "location": "Seoul, KR", "description": "", "imageUrl": "" @@ -543,10 +543,10 @@ "title": "Crecimiento", "startDate": "2025-03-05", "endDate": "2025-03-28", - "href": "https://crecimientoar", - "location": "TBD, ARG", - "description": "", - "imageUrl": "" + "href": "https://aleph.crecimiento.build/", + "location": "Buenos Aires, Argentina", + "description": "The Crecimiento Pop-Up City is a moment-in-time for these visionaries to come together with renowned experts, and transform Argentina into a world-leading startup & innovation hub.", + "imageUrl": "https://cdn.prod.website-files.com/6661b1a3c1bce60cd61fc966/669e83df3c3a7535a9cc05fa_1200xlogo.png" }, { "title": "EthereumSF", @@ -617,7 +617,7 @@ "endDate": "2025-09-06", "href": "https://ethaccra.xyz", "location": "Accra, GHA", - "description": "", + "description": "ETHAccra", "imageUrl": "http://eth-accra-website.vercel.app/assets/pngs/meta_image.png" }, { @@ -628,5 +628,59 @@ "location": "Tokyo, JAP", "description": "View and subscribe to events from ETHTokyo on Luma. ETHTokyo", "imageUrl": "https://images.lumacdn.com/calendar-cover-images/rv/316a4b25-a9fb-4ff0-ab1a-d7f23a2ba0e0" + }, + { + "title": "Edge City Austin", + "startDate": "2025-03-02", + "endDate": "2025-03-07", + "href": "https://www.edgecity.live/austin", + "location": "Austin, USA", + "description": "Edge City Austin", + "imageUrl": "https://cdn.prod.website-files.com/65b2cb5abdecf7cd7747e170/67aba5d16f625f40658dde92_edge-sxsw-10.png" + }, + { + "title": "Edge Expedition South Africa", + "startDate": "2025-04-03", + "endDate": "2025-04-12", + "href": "https://www.edgecity.live/southafrica", + "location": "Capetown, ZA", + "description": "Edge Expedition | South Africa", + "imageUrl": "https://cdn.prod.website-files.com/65b2cb5abdecf7cd7747e170/67802a19fb53c877dd9f5eb0_og-southafricaexpedition%20(1).png" + }, + { + "title": "ETH Seoul", + "startDate": "2025-04-12", + "endDate": "2025-04-12", + "href": "https://ethseoul.org", + "location": "Seoul, KR", + "description": "", + "imageUrl": "" + }, + { + "title": "ETH Cinco de Mayo", + "startDate": "2025-05-01", + "endDate": "2025-05-04", + "href": "https://ethcdm.com/", + "location": "Mexico, MX", + "description": "ETH Cinco de Mayo Hackathon, Feb. 2nd-4th 2024, Puebla, Mexico. A perfect combination of competition, workshops, networking, entrepreneurship and culture!", + "imageUrl": "https://ethcdm.com/assets/images/og-918.jpg" + }, + { + "title": "World Expo on Blockchain*", + "startDate": "2025-05-10", + "endDate": "2025-06-03", + "href": "https://web2025.world/", + "location": "Osaka, JPN", + "description": "A future without financial inclusion, digital trust, data privacy and security is no future at all. Blockchain isn’t just relevant—it’s essential.", + "imageUrl": "https://framerusercontent.com/images/Ivp1oWg8CFUDERZIoey9dadW7E.png" + }, + { + "title": "ETHBratislava", + "startDate": "2025-05-23", + "endDate": "2025-05-25", + "href": "https://ethbratislava.com/", + "location": "Bratislava, SVK", + "description": "Two-day conference and hackathon focused on sharing knowledge and sparking innovative ideas aimed at energizing the entire ethereum ecosystem.", + "imageUrl": "https://framerusercontent.com/assets/IBAFZwu44FpNo95n3OoOapeFUyw.png" } ] diff --git a/src/data/crowdin/combined-translators.json b/src/data/crowdin/combined-translators.json index 0ff30db9288..6cf639ed389 100644 --- a/src/data/crowdin/combined-translators.json +++ b/src/data/crowdin/combined-translators.json @@ -3871,6 +3871,12 @@ { "fileId": "5487", "contributors": [ + { + "id": 15123193, + "username": "Coram_Deo", + "totalCosts": 505, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15123193/medium/b3211607cc43c707c0034f7502299d8d.jpeg" + }, { "id": 14920111, "username": "JueK3y", @@ -3896,7 +3902,7 @@ { "id": 15123193, "username": "Coram_Deo", - "totalCosts": 2176.55, + "totalCosts": 2276.54, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15123193/medium/b3211607cc43c707c0034f7502299d8d.jpeg" }, { @@ -8235,7 +8241,7 @@ { "id": 14568334, "username": "mr_giorgos", - "totalCosts": 377.74, + "totalCosts": 392.89, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14568334/medium/245b5c69aab62ffabb575daf603b70b8.jpg" } ] @@ -8246,7 +8252,7 @@ { "id": 14568334, "username": "mr_giorgos", - "totalCosts": 720.13, + "totalCosts": 728.21, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14568334/medium/245b5c69aab62ffabb575daf603b70b8.jpg" } ] @@ -31877,7 +31883,7 @@ { "id": 15954931, "username": "XofEE", - "totalCosts": 1165.54, + "totalCosts": 1260.48, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15954931/medium/7254d648c451b822632980e5bfcb61fa.png" }, { @@ -35578,18 +35584,18 @@ "totalCosts": 254.52, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15594493/medium/ada4e2f5276b6085495631bb59486bc8.gif" }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 84.84, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" + }, { "id": 14907079, "username": "Ayano85", "totalCosts": 62.62, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14907079/medium/546f51cbefa424d02ea4aafec17bc45f_default.png" }, - { - "id": 14866604, - "username": "yeremiaryangunadi", - "totalCosts": 59.59, - "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" - }, { "id": 14682718, "username": "ketut", @@ -35999,7 +36005,7 @@ { "id": 14866604, "username": "yeremiaryangunadi", - "totalCosts": 106.05, + "totalCosts": 146.45, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" }, { @@ -36174,7 +36180,7 @@ { "id": 14866604, "username": "yeremiaryangunadi", - "totalCosts": 572.67, + "totalCosts": 598.93, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" }, { @@ -36392,18 +36398,18 @@ "totalCosts": 323.2, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15934037/medium/e913f10d6d3550452e0b7c072e15aa40.jpeg" }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 99.99, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" + }, { "id": 14861756, "username": "RahayuRafika_12", "totalCosts": 84.84, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14861756/medium/68ce2b760b107d1cf2a5a1508aa8ee96.jpeg" }, - { - "id": 14866604, - "username": "yeremiaryangunadi", - "totalCosts": 74.74, - "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" - }, { "id": 14708760, "username": "hypebeans", @@ -36930,18 +36936,18 @@ "totalCosts": 264.62, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15927303/medium/e39f725004e850246a765bb86dddf780_default.png" }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 175.74, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" + }, { "id": 14891244, "username": "vaiahmad", "totalCosts": 166.65, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14891244/medium/d51812ca6f71924544bf03b9a23efb68_default.png" }, - { - "id": 14866604, - "username": "yeremiaryangunadi", - "totalCosts": 144.43, - "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" - }, { "id": 15126147, "username": "anggunh", @@ -37357,7 +37363,7 @@ { "id": 14866604, "username": "yeremiaryangunadi", - "totalCosts": 50.5, + "totalCosts": 71.71, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" }, { @@ -38530,7 +38536,7 @@ { "id": 14866604, "username": "yeremiaryangunadi", - "totalCosts": 1550.35, + "totalCosts": 1580.65, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" }, { @@ -38791,6 +38797,12 @@ "username": "Ediii_id", "totalCosts": 34.34, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/16495377/medium/b5707b9b085d2e9bdb7e28873bbf24f2.jpg" + }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 21.21, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" } ] }, @@ -38873,6 +38885,12 @@ "username": "fuji.anggara10", "totalCosts": 16.16, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15934037/medium/e913f10d6d3550452e0b7c072e15aa40.jpeg" + }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 15.15, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" } ] }, @@ -39071,6 +39089,12 @@ "totalCosts": 658.52, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15662523/medium/a1bde18af96dc28c3fd1c1dd610e8896.JPG" }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 209.07, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" + }, { "id": 14861756, "username": "RahayuRafika_12", @@ -39190,6 +39214,12 @@ "username": "fuji.anggara10", "totalCosts": 371.68, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15934037/medium/e913f10d6d3550452e0b7c072e15aa40.jpeg" + }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 15.15, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" } ] }, @@ -39207,6 +39237,12 @@ "username": "hypebeans", "totalCosts": 25.25, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14708760/medium/c99d5e08a676eaebe6f2a383a81222e1.jpg" + }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 8.08, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" } ] }, @@ -39218,6 +39254,12 @@ "username": "fuji.anggara10", "totalCosts": 175.74, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15934037/medium/e913f10d6d3550452e0b7c072e15aa40.jpeg" + }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 22.22, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" } ] }, @@ -39242,6 +39284,12 @@ "totalCosts": 102.01, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14861756/medium/68ce2b760b107d1cf2a5a1508aa8ee96.jpeg" }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 36.36, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" + }, { "id": 15962457, "username": "danimeister", @@ -39459,6 +39507,12 @@ "username": "AI_bangkit", "totalCosts": 27.27, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/16863657/medium/0d11ffa1616fbe44fe28aa36c70cf2a6_default.png" + }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 12.12, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" } ] }, @@ -39493,6 +39547,12 @@ "username": "RahayuRafika_12", "totalCosts": 11.11, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14861756/medium/68ce2b760b107d1cf2a5a1508aa8ee96.jpeg" + }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 7.07, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" } ] }, @@ -39807,6 +39867,12 @@ "totalCosts": 112.11, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15927303/medium/e39f725004e850246a765bb86dddf780_default.png" }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 7.07, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" + }, { "id": 15620833, "username": "IrfanSidik.id", @@ -39862,6 +39928,12 @@ "username": "danimeister", "totalCosts": 595.9, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15962457/medium/97c701528b519a4a784b0d6b5f845fb8.jpg" + }, + { + "id": 14866604, + "username": "yeremiaryangunadi", + "totalCosts": 47.47, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" } ] }, @@ -39894,7 +39966,7 @@ { "id": 14866604, "username": "yeremiaryangunadi", - "totalCosts": 127.26, + "totalCosts": 141.4, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14866604/medium/285a89179a206f3621ba14bf04085b27.png" }, { @@ -40953,6 +41025,12 @@ "totalCosts": 79.79, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15185884/medium/0d349af8ba0364fdd96b55b46c40590c.jpg" }, + { + "id": 14618598, + "username": "emanuele-vacca", + "totalCosts": 36.36, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14618598/medium/42897a4bea750f0e5720bb0fe6f23077.jpg" + }, { "id": 15754717, "username": "Tgualtieri1976", @@ -41015,6 +41093,12 @@ "username": "Herbie_23", "totalCosts": 1105.95, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/13461670/medium/c9291075edb8582a7efe26fe983237e1.jpg" + }, + { + "id": 14618598, + "username": "emanuele-vacca", + "totalCosts": 59.59, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14618598/medium/42897a4bea750f0e5720bb0fe6f23077.jpg" } ] }, @@ -41033,6 +41117,12 @@ "totalCosts": 423.19, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15946127/medium/fb8809671278895b42cf50c752fd7bf2.png" }, + { + "id": 14618598, + "username": "emanuele-vacca", + "totalCosts": 78.78, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14618598/medium/42897a4bea750f0e5720bb0fe6f23077.jpg" + }, { "id": 15185884, "username": "carmen1912", @@ -41091,6 +41181,12 @@ "totalCosts": 41.41, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15266690/medium/beb929d96ab06718fce198051fdffaae.jpg" }, + { + "id": 14618598, + "username": "emanuele-vacca", + "totalCosts": 40.4, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14618598/medium/42897a4bea750f0e5720bb0fe6f23077.jpg" + }, { "id": 15754717, "username": "Tgualtieri1976", @@ -45465,7 +45561,7 @@ { "id": 14618598, "username": "emanuele-vacca", - "totalCosts": 3496.62, + "totalCosts": 4618.73, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14618598/medium/42897a4bea750f0e5720bb0fe6f23077.jpg" }, { @@ -49702,6 +49798,12 @@ "totalCosts": 105.04, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15488702/medium/05e244b35702080883c4e5730ef4d1e5.jpeg" }, + { + "id": 14899254, + "username": "shouki", + "totalCosts": 101, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/14899254/medium/68c57b6a2745f9ffc60fab8463011d87.jpeg" + }, { "id": 14880458, "username": "sekisanchi", @@ -58947,6 +59049,12 @@ "totalCosts": 475.71, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/15515516/medium/cad56d6fa7c03af94b18ead23e791019.png" }, + { + "id": 13315100, + "username": "timbalabuch", + "totalCosts": 177.76, + "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/13315100/medium/eb8b94eb99e44f8a238e797e9adb078a.JPG" + }, { "id": 16496053, "username": "henderson.mateus1", @@ -62191,7 +62299,7 @@ { "id": 13315100, "username": "timbalabuch", - "totalCosts": 142.41, + "totalCosts": 787.8, "avatarUrl": "https://crowdin-static.cf-downloads.crowdin.com/avatar/13315100/medium/eb8b94eb99e44f8a238e797e9adb078a.JPG" }, { diff --git a/src/data/externalTutorials.json b/src/data/externalTutorials.json index 7204118e040..18b3512f1e1 100644 --- a/src/data/externalTutorials.json +++ b/src/data/externalTutorials.json @@ -557,7 +557,7 @@ { "url": "https://docs.replit.com/tutorials/web3/build-smart-contract-oracle", "title": "Build a smart contract oracle with Solidity, Node.js, and Replit", - "description": "Learn how to use oracles in smart contracts and how oracles work internally, and gain experience with hybrid on-and-off chain systems.", + "description": "Learn how to use oracles in smart contracts and how oracles work internally, and gain experience with hybrid on-and-offchain systems.", "author": "replit", "authorGithub": "https://github.com/replit", "tags": ["solidity", "oracles", "javascript"], diff --git a/src/data/published.json b/src/data/published.json index 0c4018d6eb6..3afb12a725c 100644 --- a/src/data/published.json +++ b/src/data/published.json @@ -1 +1 @@ -{"date":"2025-02-12"} +{"date":"2025-02-25"} diff --git a/src/data/translationProgress.json b/src/data/translationProgress.json index 8642addad15..a4d4373cec9 100644 --- a/src/data/translationProgress.json +++ b/src/data/translationProgress.json @@ -79,7 +79,7 @@ { "languageId": "cs", "words": { - "approved": 113096, + "approved": 132738, "total": 277274 } }, @@ -114,7 +114,7 @@ { "languageId": "el", "words": { - "approved": 205960, + "approved": 216561, "total": 277274 } }, @@ -177,14 +177,14 @@ { "languageId": "fr", "words": { - "approved": 272957, + "approved": 276688, "total": 277274 } }, { "languageId": "ga-IE", "words": { - "approved": 0, + "approved": 392, "total": 277336 } }, @@ -240,7 +240,7 @@ { "languageId": "hu", "words": { - "approved": 260003, + "approved": 260460, "total": 277274 } }, @@ -268,7 +268,7 @@ { "languageId": "it", "words": { - "approved": 271658, + "approved": 272957, "total": 277274 } }, @@ -464,7 +464,7 @@ { "languageId": "pt-BR", "words": { - "approved": 266613, + "approved": 267177, "total": 277274 } }, @@ -569,7 +569,7 @@ { "languageId": "te", "words": { - "approved": 26550, + "approved": 26691, "total": 277274 } }, @@ -625,7 +625,7 @@ { "languageId": "uk", "words": { - "approved": 81899, + "approved": 81999, "total": 277274 } }, diff --git a/src/hooks/useCentralizedExchanges.ts b/src/hooks/useCentralizedExchanges.ts index da6544c9f77..b89b56afdbe 100644 --- a/src/hooks/useCentralizedExchanges.ts +++ b/src/hooks/useCentralizedExchanges.ts @@ -1,7 +1,6 @@ import { useState } from "react" import shuffle from "lodash/shuffle" -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" +import { useLocale } from "next-intl" // TODO: Remove unused? // import argent from "@/public/images/wallets/argent.png" @@ -18,6 +17,7 @@ import { trackCustomEvent } from "@/lib/utils/matomo" import exchangeData from "@/data/exchangesByCountry" +import { useTranslation } from "@/hooks/useTranslation" import binance from "@/public/images/exchanges/binance.png" import bitbuy from "@/public/images/exchanges/bitbuy.png" import bitfinex from "@/public/images/exchanges/bitfinex.png" @@ -303,7 +303,7 @@ const exchanges: ExchangeDetails = { } export const useCentralizedExchanges = () => { - const { locale } = useRouter() + const locale = useLocale() const { t } = useTranslation("page-get-eth") const [selectedCountry, setSelectedCountry] = useState() diff --git a/src/hooks/useLocaleDirection.ts b/src/hooks/useLocaleDirection.ts index e9f86e376bf..ba9213c81f0 100644 --- a/src/hooks/useLocaleDirection.ts +++ b/src/hooks/useLocaleDirection.ts @@ -1,5 +1,5 @@ -import { useEffect, useState } from "react" -import { useRouter } from "next/router" +import { useEffect } from "react" +import { useLocale } from "next-intl" import { Lang } from "@/lib/types" @@ -9,15 +9,11 @@ import { isLangRightToLeft } from "@/lib/utils/translations" * Custom hook that sets the DOM direction based on the locale, * responding to changes in the locale without requiring refresh. */ -export const useLocaleDirection = (): string => { - const [direction, setDirection] = useState<"ltr" | "rtl">("ltr") - const { locale } = useRouter() +export const useLocaleDirection = () => { + const locale = useLocale() useEffect(() => { const dir = isLangRightToLeft(locale as Lang) ? "rtl" : "ltr" document.documentElement.setAttribute("dir", dir) - setDirection(dir) }, [locale]) - - return direction } diff --git a/src/hooks/useRtlFlip.ts b/src/hooks/useRtlFlip.ts index 3c684d06800..07fb662a140 100644 --- a/src/hooks/useRtlFlip.ts +++ b/src/hooks/useRtlFlip.ts @@ -1,4 +1,4 @@ -import { useRouter } from "next/router" +import { useLocale } from "next-intl" import type { Lang } from "@/lib/types" @@ -18,7 +18,7 @@ type UseDirection = { * @returns An object containing the Tailwind className, RTL flag, and direction. */ export const useRtlFlip = (): UseDirection => { - const { locale } = useRouter() + const locale = useLocale() const isRtl = isLangRightToLeft(locale as Lang) return { flipForRtl: isRtl ? "scaleX(-1)" : undefined, // transform (deprecated) diff --git a/src/hooks/useStakingConsiderations.tsx b/src/hooks/useStakingConsiderations.tsx index 70b070f6ebe..d315d17ded3 100644 --- a/src/hooks/useStakingConsiderations.tsx +++ b/src/hooks/useStakingConsiderations.tsx @@ -1,5 +1,4 @@ import { ElementType, useState } from "react" -import { useTranslation } from "next-i18next" import type { StakingPage } from "@/lib/types" @@ -20,6 +19,8 @@ import { StakingConsiderationsProps } from "@/components/Staking/StakingConsider import { MatomoEventOptions } from "@/lib/utils/matomo" +import { useTranslation } from "@/hooks/useTranslation" + type DataType = { title: string description: string diff --git a/src/hooks/useSurvey.ts b/src/hooks/useSurvey.ts index b8fcb8f0ba1..a9762ca738b 100644 --- a/src/hooks/useSurvey.ts +++ b/src/hooks/useSurvey.ts @@ -1,15 +1,21 @@ import path from "path" import { useMemo } from "react" -import { useRouter } from "next/router" +import { useLocale } from "next-intl" import type { Lang } from "@/lib/types" import { SITE_URL } from "@/lib/constants" +import { usePathname } from "@/i18n/routing" + export const useSurvey = (feedbackSubmitted: boolean) => { - const { asPath, locale } = useRouter() - const { href: url } = new URL(path.join(locale! as Lang, asPath), SITE_URL) + const locale = useLocale() + const pathname = usePathname() + const { href: url } = new URL( + path.join(locale! as Lang, pathname || ""), + SITE_URL + ) return useMemo((): string | null => { if (!feedbackSubmitted) return null return `https://ethereumorg.paperform.co//?url=${url}` diff --git a/src/hooks/useTranslation.ts b/src/hooks/useTranslation.ts new file mode 100644 index 00000000000..9928ae365b1 --- /dev/null +++ b/src/hooks/useTranslation.ts @@ -0,0 +1,55 @@ +import { useTranslations } from "next-intl" + +/** + * Cases to handle: + * + * - using t("key") + * - & useTranslation() => "common.key" + * - & useTranslation("namespace") => "namespace.key" + * - & useTranslation(["namespace1", "namespace2"]) => "namespace1.key" + * + * - using t("namespace:key") + * - & useTranslation("namespace") and t("namespace:key") => "namespace.key" + * - & useTranslation(["namespace1", "namespace2"]) and t("namespace1:key") => "namespace1.key" + * - & useTranslation(["namespace1", "namespace2"]) and t("namespace2:key") => "namespace2.key" + */ + +const DEFAULT_NAMESPACE = "common" + +export function useTranslation(namespaces?: string[] | string) { + const t = useTranslations() + + const customT: typeof t = (fullKey, values) => { + try { + if (fullKey.includes(":")) { + const [namespace, key] = fullKey.split(":") + + if (values) { + return t(`${namespace}.${key}`, values) + } + + return t.raw(`${namespace}.${key}`) + } + + const namespace = Array.isArray(namespaces) + ? namespaces[0] + : namespaces || DEFAULT_NAMESPACE + + return t.raw(`${namespace}.${fullKey}`) + } catch (error) { + // Suppress errors by default, enable if needed to debug + // console.error(error) + return fullKey + } + } + + // keep the original methods + customT.raw = t.raw + customT.rich = t.rich + customT.markup = t.markup + customT.has = t.has + + return { t: customT } +} + +export default useTranslation diff --git a/src/i18n/loadNamespaces.ts b/src/i18n/loadNamespaces.ts new file mode 100644 index 00000000000..c5940b2ebd1 --- /dev/null +++ b/src/i18n/loadNamespaces.ts @@ -0,0 +1,31 @@ +import { DEFAULT_LOCALE } from "@/lib/constants" + +export default async function loadNamespaces( + locale: string, + namespaces: string[] +) { + const byNamespace = await Promise.all( + namespaces.map(async (namespace) => { + try { + const defaultNamespace = ( + await import(`../intl/${DEFAULT_LOCALE}/${namespace}.json`) + ).default + const localeNamespace = ( + await import(`../intl/${locale}/${namespace}.json`) + ).default + + // Merge the namespaces to have default translations for keys that are not present in the locale + return { ...defaultNamespace, ...localeNamespace } + } catch (error) { + // If the namespace is not found, return the default namespace + return (await import(`../intl/${DEFAULT_LOCALE}/${namespace}.json`)) + .default + } + }) + ) + + return byNamespace.reduce((acc, namespace, index) => { + acc[namespaces[index]] = namespace + return acc + }, {}) +} diff --git a/src/i18n/request.ts b/src/i18n/request.ts new file mode 100644 index 00000000000..c27ae4c2bc0 --- /dev/null +++ b/src/i18n/request.ts @@ -0,0 +1,20 @@ +import { getRequestConfig } from "next-intl/server" + +import { Lang } from "@/lib/types" + +import { routing } from "./routing" + +export default getRequestConfig(async ({ requestLocale }) => { + // This typically corresponds to the `[locale]` segment + let locale = await requestLocale + + // Ensure that the incoming locale is valid + if (!locale || !routing.locales.includes(locale as Lang)) { + locale = routing.defaultLocale + } + + return { + locale, + messages: (await import(`../../intl/${locale}/common.json`)).default, + } +}) diff --git a/src/i18n/routing.ts b/src/i18n/routing.ts new file mode 100644 index 00000000000..9e4a073dca4 --- /dev/null +++ b/src/i18n/routing.ts @@ -0,0 +1,14 @@ +import { createNavigation } from "next-intl/navigation" +import { defineRouting } from "next-intl/routing" + +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + +export const routing = defineRouting({ + locales: LOCALES_CODES, + defaultLocale: DEFAULT_LOCALE, +}) + +// Lightweight wrappers around Next.js' navigation APIs +// that will consider the routing configuration +export const { Link, redirect, usePathname, useRouter, getPathname } = + createNavigation(routing) diff --git a/src/intl/en/glossary-tooltip.json b/src/intl/en/glossary-tooltip.json index 17099323f81..ac6643bde32 100644 --- a/src/intl/en/glossary-tooltip.json +++ b/src/intl/en/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "A software client that participates in the network.
More on nodes and clients.", "ommer-term": "Ommer (uncle) block", "ommer-definition": "When a proof-of-work miner finds a valid block, another miner may have published a competing block which is added to the tip of the blockchain first. This valid, but stale, block can be included by newer blocks as ommers and receive a partial block reward. The term \"ommer\" is the preferred gender-neutral term for the sibling of a parent block, but this is also sometimes referred to as an \"uncle\". This was common for Ethereum when it was a proof-of-work network. Now that Ethereum uses proof-of-stake, only one block proposer is selected per slot.", - "on-chain-term": "On-chain", - "on-chain-definition": "Refers to actions or transactions that happen on the blockchain and are publicly available.", + "onchain-term": "Onchain", + "onchain-definition": "Refers to actions or transactions that happen on the blockchain and are publicly available.", "optimistic-rollup-term": "Optimistic rollup", "optimistic-rollup-definition": "Optimistic Rollup is a Layer 2 solution that speeds up transactions on Ethereum, assuming they're valid by default unless challenged. More on Optimistic rollups.", "peer-to-peer-network-term": "Peer-to-peer network", @@ -150,7 +150,7 @@ "validator-term": "Validator", "validator-definition": "A node in a proof-of-stake system responsible for storing data, processing transactions, and adding new blocks to the blockchain. To activate validator software, you need to be able to stake 32 ETH. More on staking in Ethereum.", "validity-proof-term": "Validity proof", - "validity-proof-definition": "A security model for certain layer 2 solutions where, to increase speed, transactions are rolled up into batches and submitted to Ethereum in a single transaction. The transaction computation is done off-chain and then supplied to the main chain with a proof of their validity. This method increases the amount of transactions possible while maintaining security. Some rollups use fraud proof. More on zero-knowledge rollups.", + "validity-proof-definition": "A security model for certain layer 2 solutions where, to increase speed, transactions are rolled up into batches and submitted to Ethereum in a single transaction. The transaction computation is done offchain and then supplied to the main chain with a proof of their validity. This method increases the amount of transactions possible while maintaining security. Some rollups use fraud proof. More on zero-knowledge rollups.", "wallet-term": "Wallet", "wallet-definition": "A wallet is a digital tool to store, send, and receive digital currency, like a virtual purse for your online money. More on Ethereum wallets.", "web2-term": "Web2", diff --git a/src/intl/en/glossary.json b/src/intl/en/glossary.json index b878aff0a80..90ae44a9515 100644 --- a/src/intl/en/glossary.json +++ b/src/intl/en/glossary.json @@ -112,7 +112,7 @@ "distributed-hash-table-term": "Distributed hash table (DHT)", "distributed-hash-table-definition": "A data structure containing `(key, value)` pairs used by Ethereum nodes to identify peers to connect to and determine which protocols to use to communicate.", "double-spend-term": "Double spend", - "double-spend-definition": "A deliberate blockchain fork, where a user with a sufficiently large amount of mining power/stake sends a transaction moving some currency off-chain (e.g. exiting into fiat money or making an off-chain purchase) then reorganizing the blockchain to remove that transaction. A successful double spend leaves the attacker with both their on and off-chain assets.", + "double-spend-definition": "A deliberate blockchain fork, where a user with a sufficiently large amount of mining power/stake sends a transaction moving some currency offchain (e.g. exiting into fiat money or making an offchain purchase) then reorganizing the blockchain to remove that transaction. A successful double spend leaves the attacker with both their on and offchain assets.", "ecdsa-term": "Elliptic Curve Digital Signature Algorithm (ECDSA)", "ecdsa-definition": "A cryptographic algorithm used by Ethereum to ensure that funds can only be spent by their owners. It's the preferred method for creating public and private keys. Relevant for account address generation and transaction verification.", "encryption-term": "Encryption", @@ -257,16 +257,16 @@ "node-definition": "A software client that participates in the network. More on nodes and clients.", "nonce-term": "Nonce", "nonce-definition": "In cryptography, a value that can only be used once. An account nonce is a transaction counter in each account, which is used to prevent replay attacks.", - "off-chain-term": "Off-Chain", - "off-chain-definition": "Off-chain means any transaction or data that exists outside the blockchain. Because committing every transaction on-chain can be expensive and inefficient, third-party tools like oracles that handle pricing data, or layer 2 solutions that execute a higher throughput of transactions, handle a bulk of the processing work off-chain, and will submit information on-chain at less frequent intervals.", + "offchain-term": "Offchain", + "offchain-definition": "Offchain means any transaction or data that exists outside the blockchain. Because committing every transaction onchain can be expensive and inefficient, third-party tools like oracles that handle pricing data, or layer 2 solutions that execute a higher throughput of transactions, handle a bulk of the processing work offchain, and will submit information onchain at less frequent intervals.", "ommer-term": "Ommer (uncle) block", "ommer-definition": "When a proof-of-work miner finds a valid block, another miner may have published a competing block which is added to the tip of the blockchain first. This valid, but stale, block can be included by newer blocks as ommers and receive a partial block reward. The term \"ommer\" is the preferred gender-neutral term for the sibling of a parent block, but this is also sometimes referred to as an \"uncle\". This was common for Ethereum when it was a proof-of-work network. Now that Ethereum uses proof-of-stake, only one block proposer is selected per slot.", - "on-chain-term": "On-Chain", - "on-chain-definition": "Refers to actions or transactions that happen on the blockchain and are publicly available.

Think of it as writing something in a big, shared notebook that everyone can see and check, making sure that whatever is written (like sending digital money or making a contract) is permanent and can't be changed or erased.", + "onchain-term": "Onchain", + "onchain-definition": "Refers to actions or transactions that happen on the blockchain and are publicly available.

Think of it as writing something in a big, shared notebook that everyone can see and check, making sure that whatever is written (like sending digital money or making a contract) is permanent and can't be changed or erased.", "optimistic-rollup-term": "Optimistic rollup", "optimistic-rollup-definition": "Optimistic Rollup is a Layer 2 solution that speeds up transactions on Ethereum, assuming they're valid by default unless challenged. More on Optimistic rollups.", "oracle-term": "Oracle", - "oracle-definition": "An oracle is a bridge between the blockchain and the real world. They act as on-chain APIs that can be queried for information and used in smart contracts. More on oracles.", + "oracle-definition": "An oracle is a bridge between the blockchain and the real world. They act as onchain APIs that can be queried for information and used in smart contracts. More on oracles.", "peer-term": "Peer", "peer-definition": "Connected computers running Ethereum client software that have identical copies of the blockchain.", "peer-to-peer-network-term": "Peer-to-peer network", @@ -274,7 +274,7 @@ "permissionless-term": "Permissionless", "permissionless-definition": "Permissionless means anyone can join and use a system like Ethereum. It's open for everyone to participate and doesn't require any approval.", "plasma-term": "Plasma", - "plasma-definition": "An off-chain scaling solution that uses fraud proofs, like optimistic rollups. Plasma is limited to simple transactions like basic token transfers and swaps. More on plasma.", + "plasma-definition": "An offchain scaling solution that uses fraud proofs, like optimistic rollups. Plasma is limited to simple transactions like basic token transfers and swaps. More on plasma.", "private-key-term": "Private key", "private-key-definition": "A private key is a secret code that proves you own your digital money and lets you spend it, like a PIN for your account. DO NOT SHARE IT.", "public-goods-term": "Public goods", @@ -378,9 +378,9 @@ "validator-lifecycle-term": "Validator lifecycle", "validator-lifecycle-definition": "The sequence of states that a validator can exist in. These include:

  • deposited: At least 32 ETH has been deposited to the deposit contract by the validator
  • pending: the validator is in the activation queue waiting to be voted into the network by existing validators
  • active: currently attesting and proposing blocks
  • slashing: the validator has misbehaved and is being slashed
  • exiting: the validator has been flagged for exiting the network, either voluntarily or because they have been ejected.
", "validity-proof-term": "Validity proof", - "validity-proof-definition": "A security model for certain layer 2 solutions where, to increase speed, transactions are rolled up into batches and submitted to Ethereum in a single transaction. The transaction computation is done off-chain and then supplied to the main chain with a proof of their validity. This method increases the amount of transactions possible while maintaining security. Some rollups use fraud proof. More on zero-knowledge rollups.", + "validity-proof-definition": "A security model for certain layer 2 solutions where, to increase speed, transactions are rolled up into batches and submitted to Ethereum in a single transaction. The transaction computation is done offchain and then supplied to the main chain with a proof of their validity. This method increases the amount of transactions possible while maintaining security. Some rollups use fraud proof. More on zero-knowledge rollups.", "validium-term": "Validium", - "validium-definition": "An off-chain solution that uses validity proofs to improve transaction throughput. Unlike Zero-knowledge rollups, validium data isn't stored on layer 1 Mainnet. More on validium.", + "validium-definition": "An offchain solution that uses validity proofs to improve transaction throughput. Unlike Zero-knowledge rollups, validium data isn't stored on layer 1 Mainnet. More on validium.", "vyper-term": "Vyper", "vyper-definition": "A high-level programming language with Python-like syntax. Intended to get closer to a pure functional language. Created by Vitalik Buterin. More on Vyper.", "wallet-term": "Wallet", diff --git a/src/intl/en/learn-quizzes.json b/src/intl/en/learn-quizzes.json index 1b41af9995c..62ca7fc486e 100644 --- a/src/intl/en/learn-quizzes.json +++ b/src/intl/en/learn-quizzes.json @@ -348,7 +348,7 @@ "daos-3-a-label": "Usually hierarchical", "daos-3-a-explanation": "DAOs are usually flat, and fully democratized.", "daos-3-b-label": "Transparent and fully public about their activities", - "daos-3-b-explanation": "Thanks to on-chain voting, decisions are transparent on the blockchain. Discussions and other elements of the decision-making process are open to all members.", + "daos-3-b-explanation": "Thanks to onchain voting, decisions are transparent on the blockchain. Discussions and other elements of the decision-making process are open to all members.", "daos-3-c-label": "Controlled by a central party", "daos-3-c-explanation": "Changes require voting by the members. Services offered are handled automatically in a decentralized manner.", "daos-3-d-label": "Restricted regarding who can suggest changes", @@ -369,8 +369,8 @@ "daos-5-b-explanation": "Share-based DAOs are more permissioned but still quite open. Any prospective member can submit a proposal to join the DAO, usually offering a tribute of some value in the form of tokens or work.", "daos-5-c-label": "Reputation-based membership", "daos-5-c-explanation": "Unlike token or share-based membership, reputation-based DAOs don't transfer ownership to contributors. DAO members must earn reputation through participation.", - "daos-5-d-label": "Executive board and off-chain treasury management", - "daos-5-d-explanation": "This approach uses highly centralized and opaque mechanisms of governing. On the contrary, DAOs use verifiable voting mechanisms and on-chain treasury management to ensure transparency and accountability.", + "daos-5-d-label": "Executive board and offchain treasury management", + "daos-5-d-explanation": "This approach uses highly centralized and opaque mechanisms of governing. On the contrary, DAOs use verifiable voting mechanisms and onchain treasury management to ensure transparency and accountability.", "staking-solo-1-prompt": "Which is true about slashing?", "staking-solo-1-a-label": "Penalty for being offline, rewards resume when back online", "staking-solo-1-a-explanation": "Being offline does NOT result in slashing. Small penalties are incurred for being offline, and rewards resume when the validator returns online and resumes attestations.", diff --git a/src/intl/en/page-dapps.json b/src/intl/en/page-dapps.json index 9c8734d69f2..9ecb4862060 100644 --- a/src/intl/en/page-dapps.json +++ b/src/intl/en/page-dapps.json @@ -97,7 +97,7 @@ "page-dapps-dapp-description-meeds": "Web3 community hubs for the age of decentralized work. Reward fairly and transparently contributions that matter.", "page-dapps-dapp-description-mirror": "Built on web3 for web3, Mirror’s robust publishing platform pushes the boundaries of writing online", "page-dapps-dapp-description-multichain": "The ultimate Router for web3. It is an infrastructure developed for arbitrary cross-chain interactions.", - "page-dapps-dapp-description-nifty-gateway": "Buy works on-chain from top artists, athletes, brands, and creators.", + "page-dapps-dapp-description-nifty-gateway": "Buy works onchain from top artists, athletes, brands, and creators.", "page-dapps-dapp-description-summerfi": "Trade, borrow, and save with Dai, an Ethereum stablecoin.", "page-dapps-dapp-description-opensea": "Buy, sell, discover, and trade limited-edition goods.", "page-dapps-dapp-description-opera": "Send crypto from your browser to merchants, other users and apps.", @@ -198,7 +198,7 @@ "page-dapps-hero-header": "Ethereum-powered tools and services", "page-dapps-hero-subtitle": "Dapps are a growing movement of applications that use Ethereum to disrupt business models or invent new ones.", "page-dapps-how-dapps-work-p1": "Dapps have their backend code (smart contracts) running on a decentralized network and not a centralized server. They use the Ethereum blockchain for data storage and smart contracts for their app logic.", - "page-dapps-how-dapps-work-p2": "A smart contract is like a set of rules that live on-chain for all to see and run exactly according to those rules. Imagine a vending machine: if you supply it with enough funds and the right selection, you'll get the item you want. And like vending machines, smart contracts can hold funds much like your Ethereum account. This allows code to mediate agreements and transactions.", + "page-dapps-how-dapps-work-p2": "A smart contract is like a set of rules that live onchain for all to see and run exactly according to those rules. Imagine a vending machine: if you supply it with enough funds and the right selection, you'll get the item you want. And like vending machines, smart contracts can hold funds much like your Ethereum account. This allows code to mediate agreements and transactions.", "page-dapps-how-dapps-work-p3": "Once dapps are deployed on the Ethereum network you can't change them. Dapps can be decentralized because they are controlled by the logic written into the contract, not an individual or a company.", "page-dapps-how-dapps-work-title": "How dapps work", "page-dapps-ipfs-logo-alt": "IPFS logo", @@ -283,7 +283,7 @@ "page-wallets-get-some": "Get some ETH", "page-dapps-dapp-description-curve": "Curve is a dex focused on stablecoins", "page-dapps-curve-image-alt": "Curve logo", - "page-dapps-dapp-description-dodo": "DODO is a on-chain liquidity provider, which leverages the Proactive Market Maker algorithm (PMM)", + "page-dapps-dapp-description-dodo": "DODO is a onchain liquidity provider, which leverages the Proactive Market Maker algorithm (PMM)", "page-dapps-dodo-image-alt": "DODO logo", "page-dapps-dapp-description-artblocks": "Art Blocks is dedicated to bringing compelling works of contemporary generative art to life", "page-dapps-artblocks-image-alt": "Art Blocks logo", diff --git a/src/intl/en/page-developers-index.json b/src/intl/en/page-developers-index.json index f4e6a175f5e..f03059ed36b 100644 --- a/src/intl/en/page-developers-index.json +++ b/src/intl/en/page-developers-index.json @@ -59,7 +59,7 @@ "page-developers-networks-link": "Networks", "page-developers-node-clients-desc": "How blocks and transactions are verified in the network", "page-developers-node-clients-link": "Nodes and clients", - "page-developers-oracle-desc": "Getting off-chain data into your smart contracts", + "page-developers-oracle-desc": "Getting offchain data into your smart contracts", "page-developers-oracles-link": "Oracles", "page-developers-play-code": "Play with code", "page-developers-read-docs": "Read the docs", diff --git a/src/intl/en/page-layer-2-learn.json b/src/intl/en/page-layer-2-learn.json index 0940906aad4..28c9e5b980b 100644 --- a/src/intl/en/page-layer-2-learn.json +++ b/src/intl/en/page-layer-2-learn.json @@ -37,7 +37,7 @@ "page-layer-2-learn-rollupCards-optimistic-description": "Optimistic rollups use fault proofs where transactions are assumed to be valid, but can be challenged if an invalid transaction is suspected. If an invalid transaction is suspected, a fault proof is ran to see if this has taken place.", "page-layer-2-learn-rollupCards-optimistic-childSentence": "More on optimistic rollups", "page-layer-2-learn-rollupCards-zk-title": "Zero knowledge rollups", - "page-layer-2-learn-rollupCards-zk-description": "Zero Knowledge rollups use validity proofs where transactions calculations are computed off-chain, and then this data is then supplied to Ethereum Mainnet with a proof of their validity.", + "page-layer-2-learn-rollupCards-zk-description": "Zero Knowledge rollups use validity proofs where transactions calculations are computed offchain, and then this data is then supplied to Ethereum Mainnet with a proof of their validity.", "page-layer-2-learn-rollupCards-zk-childSentence": "More on zk-rollups", "page-layer-2-learn-dyor-title": "Do your own research: Risks of layer 2", "page-layer-2-learn-dyor-1": "Because layer 2 chains inherit security from Ethereum, in an ideal world, they are as safe as L1 Ethereum. However, many of the projects are still young and somewhat experimental. After years of R&D, many of the L2 technologies that will scale Ethereum went live in 2021. This is not to say these L2s are not secure, only that no layer 2 is as battle tested as Ethereum Mainnet. Always do your own research and decide if you're comfortable with any risks involved.", diff --git a/src/intl/en/page-roadmap-vision.json b/src/intl/en/page-roadmap-vision.json index a58f789226c..0b8698e1262 100644 --- a/src/intl/en/page-roadmap-vision.json +++ b/src/intl/en/page-roadmap-vision.json @@ -14,7 +14,7 @@ "page-roadmap-vision-problems": "Today's problems", "page-roadmap-vision-scalability": "Scalability", "page-roadmap-vision-scalability-desc": "Ethereum needs to be able to handle more transactions per second without increasing the size of the nodes in the network. Nodes are vital network participants who store and run the blockchain. Increasing node size isn't practical because only those with powerful and expensive computers could do it. To scale, Ethereum needs more transactions per second, coupled with more nodes. More nodes means more security.", - "page-roadmap-vision-scalability-desc-3": "Layer 2 rollups scale Ethereum by moving transactions off-chain and only posting summary data to Ethereum. This batching increases Ethereum's throughput while drastically reducing costs for users.", + "page-roadmap-vision-scalability-desc-3": "Layer 2 rollups scale Ethereum by moving transactions offchain and only posting summary data to Ethereum. This batching increases Ethereum's throughput while drastically reducing costs for users.", "page-roadmap-vision-scalability-desc-4": "Rollups need low-cost storage on layer 1 to make transactions as cheap as possible for users. This will be provided in the form of blobs attached to Ethereum blocks. Eventually, many blobs will be attached to Ethereum blocks, providing cheap storage for many rollups.", "page-roadmap-vision-security": "Security", "page-roadmap-vision-security-desc": "The planned upgrades improve Ethereum's security against coordinated attacks.", diff --git a/src/intl/en/page-staking.json b/src/intl/en/page-staking.json index ed2b6ae241d..6854bbfe4f1 100644 --- a/src/intl/en/page-staking.json +++ b/src/intl/en/page-staking.json @@ -10,7 +10,7 @@ "comp-withdrawal-comparison-new-link": "Visit Staking Launchpad", "comp-withdrawal-credentials-placeholder": "Validator index", "comp-withdrawal-credentials-error": "Oops! Double check validator index number and try again.", - "comp-withdrawal-credentials-upgraded-1": "Validator index {{validatorIndex}} is ready to start receiving rewards!", + "comp-withdrawal-credentials-upgraded-1": "Validator index {validatorIndex} is ready to start receiving rewards!", "comp-withdrawal-credentials-upgraded-2": "Withdrawal credentials linked to execution address:", "comp-withdrawal-credentials-not-upgraded-1": "This validator needs to be upgraded.", "comp-withdrawal-credentials-not-upgraded-1-testnet": "This Holesky testnet validator needs to be upgraded.", diff --git a/src/intl/en/page-upgrades-index.json b/src/intl/en/page-upgrades-index.json index 6c0de035828..d8f087c7243 100644 --- a/src/intl/en/page-upgrades-index.json +++ b/src/intl/en/page-upgrades-index.json @@ -97,7 +97,7 @@ "page-upgrades-question-6-answer-5": "You can also join the discussion on Ethereum research and development at ethresear.ch.", "page-upgrades-question-6-title": "What do I need to do with my dapp?", "page-upgrades-question-6-desc": "The Merge was designed to have minimal impact on dapp developers, though there were a couple of small changes worth noting.", - "page-upgrades-question-6-answer-1": "Dapp developers familiar with pre-merge Ethereum should be aware of some changes. These changes include block structure and timing, a few opcode changes, sources of on-chain randomness and the concept of epoch finalization.", + "page-upgrades-question-6-answer-1": "Dapp developers familiar with pre-merge Ethereum should be aware of some changes. These changes include block structure and timing, a few opcode changes, sources of onchain randomness and the concept of epoch finalization.", "page-upgrades-question-6-answer-1-link": "How The Merge Impacted Ethereum's Application Layer", "page-upgrades-question-6-answer-2": "Applications were almost entirely unaffected.", "page-upgrades-question-7-desc": "Many different teams from all over the community are working on the various Ethereum upgrades.", diff --git a/src/intl/es/glossary-tooltip.json b/src/intl/es/glossary-tooltip.json index 4520386c78b..1e338427134 100644 --- a/src/intl/es/glossary-tooltip.json +++ b/src/intl/es/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "Un cliente de software que participa en la red. Más sobre nodos y clientes.", "ommer-term": "Bloque Ommer (tío)", "ommer-definition": "Cuando un minero de prueba de trabajo encuentra un bloque válido, otro minero puede haber publicado un bloque en competencia que se agrega primero a la punta de la cadena de bloques. Este bloque válido, pero estancado, puede ser incluido por bloques más nuevos como ommers y recibir una recompensa de bloque parcial. El término \"ommer\" es el término de género neutral preferido para el hermano de un bloque padre (principal), pero a veces también se lo conoce como \"tío\" (uncle). Esto era común para Ethereum cuando era una red de prueba de trabajo. Ahora que Ethereum utiliza prueba de participación, solo se selecciona un proponente de bloques por ranura.", - "on-chain-term": "En cadena", - "on-chain-definition": "Se refiere a las acciones o transacciones que ocurren en la cadena de bloques y están disponibles públicamente.", + "onchain-term": "En cadena", + "onchain-definition": "Se refiere a las acciones o transacciones que ocurren en la cadena de bloques y están disponibles públicamente.", "optimistic-rollup-term": "Acumulaciones optimistas (Optimistic rollups)", "optimistic-rollup-definition": "Un Rollup Optimista es una solución de Capa 2 que acelera las transacciones en Ethereum, asumiendo que son válidas por defecto, a menos que se las cuestione o ponga en duda. Más información acerca de los Rollups Optimistas.", "peer-to-peer-network-term": "Red entre pares (o peer-to-peer)", diff --git a/src/intl/es/glossary.json b/src/intl/es/glossary.json index 0d47f90f9b6..96021ab51e1 100644 --- a/src/intl/es/glossary.json +++ b/src/intl/es/glossary.json @@ -257,12 +257,12 @@ "node-definition": "Un cliente de software que participa en la red. Más sobre nodos y clientes.", "nonce-term": "Nonce", "nonce-definition": "En criptografía, un valor que solo se puede usar una vez. Un nonce de cuenta es un contador de transacciones en cada cuenta que se utiliza para evitar ataques de repetición.", - "off-chain-term": "Fuera de la cadena", - "off-chain-definition": "Fuera de la cadena significa cualquier transacción o dato que exista fuera de la cadena de bloques. Debido a que la comisión de cada transacción en cadena puede ser costosa e ineficiente, herramientas de terceros, como los oráculos que manejan datos de precios, o las soluciones de capa 2 que tienen un mayor rendimiento de transacciones, manejan gran parte del trabajo de procesamiento fuera de la cadena y envían información a la cadena a intervalos menos frecuentes.", + "offchain-term": "Fuera de la cadena", + "offchain-definition": "Fuera de la cadena significa cualquier transacción o dato que exista fuera de la cadena de bloques. Debido a que la comisión de cada transacción en cadena puede ser costosa e ineficiente, herramientas de terceros, como los oráculos que manejan datos de precios, o las soluciones de capa 2 que tienen un mayor rendimiento de transacciones, manejan gran parte del trabajo de procesamiento fuera de la cadena y envían información a la cadena a intervalos menos frecuentes.", "ommer-term": "Bloque Ommer (tío)", "ommer-definition": "Cuando un minero de prueba de trabajo encuentra un bloque válido, otro minero puede haber publicado un bloque en competencia que se agrega primero a la punta de la cadena de bloques. Este bloque válido, pero estancado, puede ser incluido por bloques más nuevos como ommers y recibir una recompensa de bloque parcial. El término \"ommer\" es el término de género neutral preferido para el hermano de un bloque padre (principal), pero a veces también se lo conoce como \"tío\" (uncle). Esto era común para Ethereum cuando era una red de prueba de trabajo. Ahora que Ethereum utiliza prueba de participación, solo se selecciona un proponente de bloques por ranura.", - "on-chain-term": "En cadena", - "on-chain-definition": "Se refiere a acciones o transacciones que ocurren en la cadena de bloques y que están disponibles públicamente.

Piénselo como escribir algo en un gran cuaderno compartido que todo el mundo puede ver y comprobar, asegurándose de que lo que se escribe (como enviar dinero digital o hacer un contrato) es permanente y no se puede cambiar ni borrar.", + "onchain-term": "En cadena", + "onchain-definition": "Se refiere a acciones o transacciones que ocurren en la cadena de bloques y que están disponibles públicamente.

Piénselo como escribir algo en un gran cuaderno compartido que todo el mundo puede ver y comprobar, asegurándose de que lo que se escribe (como enviar dinero digital o hacer un contrato) es permanente y no se puede cambiar ni borrar.", "optimistic-rollup-term": "Acumulaciones optimistas (Optimistic rollups)", "optimistic-rollup-definition": "Un Rollup Optimista es una solución de Capa 2 que acelera las transacciones en Ethereum, asumiendo que son válidas por defecto, a menos que se las cuestione o ponga en duda. Más información acerca de los Rollups Optimistas.", "oracle-term": "Oráculo", diff --git a/src/intl/fa/glossary-tooltip.json b/src/intl/fa/glossary-tooltip.json index f9e9883dfad..763bea8aac4 100644 --- a/src/intl/fa/glossary-tooltip.json +++ b/src/intl/fa/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "یک کلاینت نرم افزاری که در شبکه شرکت می کند. اطلاعات بیشتر در مورد گره ها و کلاینت ها.", "ommer-term": "بلوک Ommer (عمو)", "ommer-definition": "وقتی یک miner اثبات کار، یک بلوک معتبر پیدا می‌کند، ممکن است معدنچی دیگری منتشر کرده باشد. یک بلوک رقیب که ابتدا به نوک بلاکچین اضافه می شود. این بلوک معتبر، اما قدیمی، می‌تواند توسط بلوک‌های جدیدتر به‌عنوان ommers گنجانده شود و یک پاداش بلوک جزئی دریافت کند. اصطلاح \"ommer\" اصطلاح ترجیحی از نظر جنسیتی خنثی برای خواهر یا برادر بلوک والدین است، اما گاهی اوقات به آن \"عمو\" نیز گفته می شود. زمانی که اتریوم یک شبکه اثبات کار بود، این برای اتریوم رایج بود. اکنون که اتریوم از اثبات سهام استفاده می‌کند، تنها یک پیشنهاد دهنده بلوک در هر اسلات انتخاب می‌شود.", - "on-chain-term": "روی زنجیره", - "on-chain-definition": "به اقدامات یا تراکنش‌هایی اشاره دارد که روی بلاکچین اتفاق می‌افتند و در دسترس عموم هستند.", + "onchain-term": "روی زنجیره", + "onchain-definition": "به اقدامات یا تراکنش‌هایی اشاره دارد که روی بلاکچین اتفاق می‌افتند و در دسترس عموم هستند.", "optimistic-rollup-term": "رول آپ خوش بینانه", "optimistic-rollup-definition": "رول‌آپ خوش‌بینانه یک راه حل لایه 2 است که به تراکنش ها در اتریوم سرعت می بخشد، با این فرض که به طور پیش فرض معتبر هستند مگر اینکه به چالش کشیده شوند. اطلاعات بیشتر در مورد رول‌آپ خوش‌بینانه.", "peer-to-peer-network-term": "شبکه همتا به همتا", diff --git a/src/intl/fa/glossary.json b/src/intl/fa/glossary.json index 9dc86ef8a85..19736afd0f2 100644 --- a/src/intl/fa/glossary.json +++ b/src/intl/fa/glossary.json @@ -257,12 +257,12 @@ "node-definition": "یک کلاینت نرم افزاری که در شبکه شرکت می کند. اطلاعات بیشتر در مورد گره ها و کلاینت ها.", "nonce-term": "Nonce", "nonce-definition": "در مبحث رمزنگاری، مقداری که فقط یک بار قابل استفاده است. نانس یک حساب یک شمارنده تراکنش در هر حساب است که برای جلوگیری از حملات مجدد استفاده می شود.", - "off-chain-term": "برون‌زنجیره‌ای", - "off-chain-definition": "برون‌زنجیره ای یا آف‌چین به معنای هر تراکنش یا داده‌ای است که خارج از بلاکچین وجود دارد. از آنجایی که انجام هر تراکنش در زنجیره می تواند گران و ناکارآمد باشد، ابزارهای شخص ثالث مانند اوراکل ها که داده های قیمت گذاری را مدیریت می کنند، یا راهکارهای لایه2 که توان عملیاتی بالاتری از تراکنش‌ها را انجام می‌دهند، بخش عمده‌ای از کارهای پردازشی را خارج از زنجیره انجام می‌دهند و اطلاعات آنچین را در فواصل زمانی کمتر ارسال می‌کنند.", + "offchain-term": "برون‌زنجیره‌ای", + "offchain-definition": "برون‌زنجیره ای یا آف‌چین به معنای هر تراکنش یا داده‌ای است که خارج از بلاکچین وجود دارد. از آنجایی که انجام هر تراکنش در زنجیره می تواند گران و ناکارآمد باشد، ابزارهای شخص ثالث مانند اوراکل ها که داده های قیمت گذاری را مدیریت می کنند، یا راهکارهای لایه2 که توان عملیاتی بالاتری از تراکنش‌ها را انجام می‌دهند، بخش عمده‌ای از کارهای پردازشی را خارج از زنجیره انجام می‌دهند و اطلاعات آنچین را در فواصل زمانی کمتر ارسال می‌کنند.", "ommer-term": "بلوک Ommer (عمو)", "ommer-definition": "وقتی یک miner اثبات کار، یک بلوک معتبر پیدا می‌کند، ممکن است معدنچی دیگری منتشر کرده باشد. یک بلوک رقیب که ابتدا به نوک بلاکچین اضافه می شود. این بلوک معتبر، اما قدیمی، می‌تواند توسط بلوک‌های جدیدتر به‌عنوان ommers گنجانده شود و یک پاداش بلوک جزئی دریافت کند. اصطلاح \"ommer\" اصطلاح ترجیحی از نظر جنسیتی خنثی برای خواهر یا برادر بلوک والدین است، اما گاهی اوقات به آن \"عمو\" نیز گفته می شود. زمانی که اتریوم یک شبکه اثبات کار بود، این برای اتریوم رایج بود. اکنون که اتریوم از اثبات سهام استفاده می‌کند، تنها یک پیشنهاد دهنده بلوک در هر اسلات انتخاب می‌شود.", - "on-chain-term": "آنچین", - "on-chain-definition": "به اقدامات یا تراکنش‌هایی اشاره دارد که روی بلاک چین اتفاق می‌افتند و به صورت عمومی در دسترس هستند.

فکر کنید چیزی در یک دفترچه یادداشت مشترک و بزرگ می‌نویسید که همه می‌توانند ببینند و بررسی کنند، و مطمئن شوید که هر چیزی نوشته شده است (مانند ارسال پول دیجیتال یا بستن قرارداد) دائمی است و قابل تغییر یا پاک کردن نیست.", + "onchain-term": "آنچین", + "onchain-definition": "به اقدامات یا تراکنش‌هایی اشاره دارد که روی بلاک چین اتفاق می‌افتند و به صورت عمومی در دسترس هستند.

فکر کنید چیزی در یک دفترچه یادداشت مشترک و بزرگ می‌نویسید که همه می‌توانند ببینند و بررسی کنند، و مطمئن شوید که هر چیزی نوشته شده است (مانند ارسال پول دیجیتال یا بستن قرارداد) دائمی است و قابل تغییر یا پاک کردن نیست.", "optimistic-rollup-term": "رول آپ خوش بینانه", "optimistic-rollup-definition": "رول‌آپ خوش‌بینانه یک راه حل لایه 2 است که به تراکنش ها در اتریوم سرعت می بخشد، با این فرض که به طور پیش فرض معتبر هستند مگر اینکه به چالش کشیده شوند. اطلاعات بیشتر در مورد رول‌آپ خوش‌بینانه.", "oracle-term": "اوراکل", diff --git a/src/intl/fr/glossary-tooltip.json b/src/intl/fr/glossary-tooltip.json index 97a20387b15..4e62f394913 100644 --- a/src/intl/fr/glossary-tooltip.json +++ b/src/intl/fr/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "Un client logiciel qui participe au réseau. En savoir plus sur les nœuds et les clients.", "ommer-term": "Bloc oncle (ommer)", "ommer-definition": "Lorsqu'un mineur en preuve de travail trouve un bloc valide, un autre mineur peut avoir publié un bloc concurrent qui est ajouté en premier à l'extrémité de la blockchain. Ce bloc valide, mais périmé, peut être inclus par des blocs plus récents en tant qu'ommers et recevoir une récompense de bloc partielle. Le terme « ommer » est le terme de genre neutre préféré pour désigner le frère ou la sœur d'un bloc parent, mais il est parfois également appelé « oncle ». Cela était frequent pour Ethereum lorsqu'il s'agissait d'un réseau basé sur la preuve de travail. Maintenant qu'Ethereum utilise la preuve d'enjeu, un seul proposeur de bloc est sélectionné par créneau.", - "on-chain-term": "En chaîne", - "on-chain-definition": "Fait référence aux actions ou transactions qui se produisent sur la blockchain et qui sont accessibles au public.", + "onchain-term": "En chaîne", + "onchain-definition": "Fait référence aux actions ou transactions qui se produisent sur la blockchain et qui sont accessibles au public.", "optimistic-rollup-term": "Rollup optimisé", "optimistic-rollup-definition": "Le rollup optimiste est une solution de couche 2 qui accélère les transactions sur Ethereum, en supposant qu’elles soient valides par défaut, sauf si elles sont contestées. En savoir plus sur les rollups optimistes.", "peer-to-peer-network-term": "Réseaux Pair-à-Pair", diff --git a/src/intl/fr/glossary.json b/src/intl/fr/glossary.json index afa87855cc4..4ab4fb9e3b8 100644 --- a/src/intl/fr/glossary.json +++ b/src/intl/fr/glossary.json @@ -257,12 +257,12 @@ "node-definition": "Un client logiciel qui participe au réseau. En savoir plus sur les nœuds et les clients.", "nonce-term": "Nonce", "nonce-definition": "En cryptographie, une valeur qui ne peut être utilisée qu'une seule fois. Un nonce de compte est un compteur de transactions dans chaque compte, qui est utilisé pour empêcher les attaques par rejeu.", - "off-chain-term": "Hors-chaine", - "off-chain-definition": "Hors-chaine se réfère à toute transaction ou donnée qui existe en dehors de la blockchain. Parce que la validation de chaque transaction sur la chaîne peut être coûteuse et inefficace, des outils tiers tels que des oracles qui gèrent les données de tarification, ou des solutions de couche 2 qui exécutent un débit de transactions plus élevé, gèrent une grande partie du travail de traitement hors chaîne et présentera des renseignements sur la chaîne à des intervalles moins fréquents.", + "offchain-term": "Hors-chaine", + "offchain-definition": "Hors-chaine se réfère à toute transaction ou donnée qui existe en dehors de la blockchain. Parce que la validation de chaque transaction sur la chaîne peut être coûteuse et inefficace, des outils tiers tels que des oracles qui gèrent les données de tarification, ou des solutions de couche 2 qui exécutent un débit de transactions plus élevé, gèrent une grande partie du travail de traitement hors chaîne et présentera des renseignements sur la chaîne à des intervalles moins fréquents.", "ommer-term": "Bloc oncle (ommer)", "ommer-definition": "Lorsqu'un mineur en preuve de travail trouve un bloc valide, un autre mineur peut avoir publié un bloc concurrent qui est ajouté en premier à l'extrémité de la blockchain. Ce bloc valide, mais périmé, peut être inclus par des blocs plus récents en tant qu'ommers et recevoir une récompense de bloc partielle. Le terme « ommer » est le terme de genre neutre préféré pour désigner le frère ou la sœur d'un bloc parent, mais il est parfois également appelé « oncle ». Cela était frequent pour Ethereum lorsqu'il s'agissait d'un réseau basé sur la preuve de travail. Maintenant qu'Ethereum utilise la preuve d'enjeu, un seul proposeur de bloc est sélectionné par créneau.", - "on-chain-term": "Sur la chaîne", - "on-chain-definition": "Fait référence aux actions ou transactions qui se produisent sur la blockchain et sont accessibles au public.

Voyez cela comme le fait d'écrire quelque chose dans un carnet partagé que tout le monde peut voir et vérifier, en vous assurant que tout ce qui est écrit (comme envoyer de l’argent numérique ou conclure un contrat) est permanent et ne peut pas être modifié ou effacé.", + "onchain-term": "Sur la chaîne", + "onchain-definition": "Fait référence aux actions ou transactions qui se produisent sur la blockchain et sont accessibles au public.

Voyez cela comme le fait d'écrire quelque chose dans un carnet partagé que tout le monde peut voir et vérifier, en vous assurant que tout ce qui est écrit (comme envoyer de l’argent numérique ou conclure un contrat) est permanent et ne peut pas être modifié ou effacé.", "optimistic-rollup-term": "Rollup optimisé", "optimistic-rollup-definition": "Le rollup optimiste est une solution de couche 2 qui accélère les transactions sur Ethereum, en supposant qu’elles soient valides par défaut, sauf si elles sont contestées. En savoir plus sur les rollups optimistes.", "oracle-term": "Oracle", diff --git a/src/intl/hu/glossary-tooltip.json b/src/intl/hu/glossary-tooltip.json index 374751649b7..5a06ed53fd8 100644 --- a/src/intl/hu/glossary-tooltip.json +++ b/src/intl/hu/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "Egy szoftverkliens, mely részt vesz a hálózatban. Bővebben a csomópontokról és a kliensekről.", "ommer-term": "Ommer (nagybácsi) blokk", "ommer-definition": "Amikor egy proof-of-work (munkaigazolás) mechanizmus bányásza talált egy érvényes blokkot, egy másik bányász talán beküldött egy ezzel versenyző blokkot, amelyet először tettek hozzá a blokklánc elejéhez. Ez az érvényes, de elévült blokk bekerülhet az újabb blokkokba ommer-ként (a szülőblokk testvére) és részleges blokkjutalmat lehet érte kapni. Ez a kifejezés a semleges megfogalmazása a szülőblokk testvérére vonatkozóan, de néha nagybácsinak (uncle) is nevezik. Ez általános volt az Ethereum esetében, amikor még proof-of-work-alapú hálózat volt. Most, hogy az Ethereum proof-of-stake alapra váltott, helyenként csak egy blokkjavaslat van kiválasztva.", - "on-chain-term": "Láncon belüli", - "on-chain-definition": "Olyan műveletekre vagy tranzakciókra utal, amelyek a blokkláncon történnek és nyilvánosan elérhetőek.", + "onchain-term": "Láncon belüli", + "onchain-definition": "Olyan műveletekre vagy tranzakciókra utal, amelyek a blokkláncon történnek és nyilvánosan elérhetőek.", "optimistic-rollup-term": "Optimista típusú összevont tranzakciók", "optimistic-rollup-definition": "Az optimista összesítés egy 2. rétegű megoldás, amely felgyorsítja a tranzakciókat az Ethereumon, azt feltételezve, hogy alapértelmezés szerint érvényesek, hacsak nem támadják meg őket. További információk az optimista összesítésekről.", "peer-to-peer-network-term": "Közvetítőmentes (peer-to-peer) hálózat", diff --git a/src/intl/hu/glossary.json b/src/intl/hu/glossary.json index ff35482c0bb..1a2db299bb4 100644 --- a/src/intl/hu/glossary.json +++ b/src/intl/hu/glossary.json @@ -257,12 +257,12 @@ "node-definition": "Egy szoftverkliens, mely részt vesz a hálózatban. Bővebben a csomópontokról és a kliensekről.", "nonce-term": "Nonce", "nonce-definition": "A kriptográfiában egy olyan érték, melyet acsak egyszer lehet használni. Egy számla nonce az egy tranzakciószámláló minden számlánál, amellyel meg lehet akadályozni az újrajátszási támadásokat.", - "off-chain-term": "Láncon kívüli", - "off-chain-definition": "A láncon kívüli olyan tranzakcióra vagy adatra vonatkozik, amely a blokkláncon kívül létezik. Mivel minden tranzakció lácon belüli kezelése költséges és nem feltétlen hatékony, a harmadik féltől származó eszközök, például az áradatokat szolgáltató oracle-ök, vagy a nagyobb tranzakcióátvitelre képes második blokkláncrétegbeli (L2) megoldások a feldolgozás nagy részét a blokkláncon kívül végzik, és ritkábban küldik be az információkat a blokkláncra.", + "offchain-term": "Láncon kívüli", + "offchain-definition": "A láncon kívüli olyan tranzakcióra vagy adatra vonatkozik, amely a blokkláncon kívül létezik. Mivel minden tranzakció lácon belüli kezelése költséges és nem feltétlen hatékony, a harmadik féltől származó eszközök, például az áradatokat szolgáltató oracle-ök, vagy a nagyobb tranzakcióátvitelre képes második blokkláncrétegbeli (L2) megoldások a feldolgozás nagy részét a blokkláncon kívül végzik, és ritkábban küldik be az információkat a blokkláncra.", "ommer-term": "Ommer (nagybácsi) blokk", "ommer-definition": "Amikor egy proof-of-work (munkaigazolás) mechanizmus bányásza talált egy érvényes blokkot, egy másik bányász talán beküldött egy ezzel versenyző blokkot, amelyet először tettek hozzá a blokklánc elejéhez. Ez az érvényes, de elévült blokk bekerülhet az újabb blokkokba ommer-ként (a szülőblokk testvére) és részleges blokkjutalmat lehet érte kapni. Ez a kifejezés a semleges megfogalmazása a szülőblokk testvérére vonatkozóan, de néha nagybácsinak (uncle) is nevezik. Ez általános volt az Ethereum esetében, amikor még proof-of-work-alapú hálózat volt. Most, hogy az Ethereum proof-of-stake alapra váltott, helyenként csak egy blokkjavaslat van kiválasztva.", - "on-chain-term": "Láncon belüli", - "on-chain-definition": "A láncon belüli olyan műveletekre vagy tranzakciókra utal, amelyek a blokkláncon történnek, és nyilvánosan elérhetőek.

Gondoljon rá úgy, mintha egy nagy, közös jegyzetfüzetbe írna valamit, amit mindenki láthat és ellenőrizhet, ezel biztosítva, hogy Ön bármit is ír (például digitális pénzt küld vagy szerződést köt), az végleges legyen, és ne lehessen megváltoztatni vagy törölni.", + "onchain-term": "Láncon belüli", + "onchain-definition": "A láncon belüli olyan műveletekre vagy tranzakciókra utal, amelyek a blokkláncon történnek, és nyilvánosan elérhetőek.

Gondoljon rá úgy, mintha egy nagy, közös jegyzetfüzetbe írna valamit, amit mindenki láthat és ellenőrizhet, ezel biztosítva, hogy Ön bármit is ír (például digitális pénzt küld vagy szerződést köt), az végleges legyen, és ne lehessen megváltoztatni vagy törölni.", "optimistic-rollup-term": "Optimista típusú összevont tranzakciók", "optimistic-rollup-definition": "Az optimista összesítés egy 2. rétegű megoldás, amely felgyorsítja a tranzakciókat az Ethereumon, azt feltételezve, hogy alapértelmezés szerint érvényesek, hacsak nem támadják meg őket. További információk az optimista összesítésekről.", "oracle-term": "Orákulum", diff --git a/src/intl/it/glossary-tooltip.json b/src/intl/it/glossary-tooltip.json index 3a7f6565a3b..9e4149089ca 100644 --- a/src/intl/it/glossary-tooltip.json +++ b/src/intl/it/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "Un client software che partecipa alla rete. Maggiori informazioni sui nodi e i client.", "ommer-term": "Blocco ommer (zio)", "ommer-definition": "Quando un miner di proof-of-work trova un blocco valido, un altro miner potrebbe aver pubblicato un blocco concorrente che viene aggiunto prima alla testa della catena. Questo blocco valido, ma obsoleto, può essere incluso in blocchi più recenti come ommer e ricevere una ricompensa parziale del blocco. Il termine \"ommer\" è il termine preferito, neutro dal punto di vista di genere, per lo stesso livello di un blocco genitore, ma talvolta è anche indicato come \"zio\". Questo era comune per Ethereum quando era una rete di proof-of-work. Ora che Ethereum utilizza il proof-of-stake, viene selezionato soltanto un propositore del blocco per slot.", - "on-chain-term": "Sulla catena", - "on-chain-definition": "Si riferisce alle azioni o transazioni che si verificano sulla blockchain e sono disponibili pubblicamente.", + "onchain-term": "Sulla catena", + "onchain-definition": "Si riferisce alle azioni o transazioni che si verificano sulla blockchain e sono disponibili pubblicamente.", "optimistic-rollup-term": "Optimistic rollup", "optimistic-rollup-definition": "Un rollup ottimistico è una soluzione del Livello 2 che velocizza le transazioni su Ethereum, supponendo che siano valide di default se non contestate. Maggiori informazioni sui rollup ottimistici.", "peer-to-peer-network-term": "Rete peer-to-peer", diff --git a/src/intl/it/glossary.json b/src/intl/it/glossary.json index 33d3cfc36fa..138a5ccc6eb 100644 --- a/src/intl/it/glossary.json +++ b/src/intl/it/glossary.json @@ -257,12 +257,12 @@ "node-definition": "Un client software che partecipa alla rete. Maggiori informazioni sui nodi e i client.", "nonce-term": "Nonce", "nonce-definition": "In crittografia, un valore utilizzabile una sola volta. Il nonce di un conto è un contatore di transazioni in ogni conto, utilizzato per impedire gli attacchi di riproduzione.", - "off-chain-term": "Esterno alla catena", - "off-chain-definition": "Esterno alla catena si riferisce a qualsiasi transazione o dato che esiste al di fuori della blockchain. Poiché effettuare il commit di ogni transazione su catena può essere costoso e inefficiente, strumenti di terze parti come gli oracoli che gestiscono i dati sui prezzi, o le soluzioni di livello 2 che eseguono un volume maggiore di transazioni, gestiscono molto del lavoro di elaborazione all'esterno della catena, e invieranno le informazioni sulla catena a intervalli meno frequenti.", + "offchain-term": "Esterno alla catena", + "offchain-definition": "Esterno alla catena si riferisce a qualsiasi transazione o dato che esiste al di fuori della blockchain. Poiché effettuare il commit di ogni transazione su catena può essere costoso e inefficiente, strumenti di terze parti come gli oracoli che gestiscono i dati sui prezzi, o le soluzioni di livello 2 che eseguono un volume maggiore di transazioni, gestiscono molto del lavoro di elaborazione all'esterno della catena, e invieranno le informazioni sulla catena a intervalli meno frequenti.", "ommer-term": "Blocco ommer (zio)", "ommer-definition": "Quando un miner di proof-of-work trova un blocco valido, un altro miner potrebbe aver pubblicato un blocco concorrente che viene aggiunto prima alla testa della catena. Questo blocco valido, ma obsoleto, può essere incluso in blocchi più recenti come ommer e ricevere una ricompensa parziale del blocco. Il termine \"ommer\" è il termine preferito, neutro dal punto di vista di genere, per lo stesso livello di un blocco genitore, ma talvolta è anche indicato come \"zio\". Questo era comune per Ethereum quando era una rete di proof-of-work. Ora che Ethereum utilizza il proof-of-stake, viene selezionato soltanto un propositore del blocco per slot.", - "on-chain-term": "Sulla catena", - "on-chain-definition": "Si riferisce alle azioni o transazioni che si verificano sulla blockchain e sono disponibili pubblicamente.

Immaginalo come scrivere qualcosa su un grande taccuino condiviso che tutti possono leggere e controllare, assicurandosi che qualsiasi cosa sia stata scritta (come inviare moneta digitale o stipulare un contratto) sia permanente e non possa essere modificata o cancellata.", + "onchain-term": "Sulla catena", + "onchain-definition": "Si riferisce alle azioni o transazioni che si verificano sulla blockchain e sono disponibili pubblicamente.

Immaginalo come scrivere qualcosa su un grande taccuino condiviso che tutti possono leggere e controllare, assicurandosi che qualsiasi cosa sia stata scritta (come inviare moneta digitale o stipulare un contratto) sia permanente e non possa essere modificata o cancellata.", "optimistic-rollup-term": "Optimistic rollup", "optimistic-rollup-definition": "Un rollup ottimistico è una soluzione del Livello 2 che velocizza le transazioni su Ethereum, supponendo che siano valide di default se non contestate. Maggiori informazioni sui rollup ottimistici.", "oracle-term": "Oracolo", diff --git a/src/intl/ja/glossary-tooltip.json b/src/intl/ja/glossary-tooltip.json index 2bb4066a87d..73f0353afd7 100644 --- a/src/intl/ja/glossary-tooltip.json +++ b/src/intl/ja/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "ネットワークに参加するソフトウェアクライアント。詳細は、ノードとクライアントをご覧ください。", "ommer-term": "オマー(アンクル)ブロック", "ommer-definition": "プルーフ・オブ・ワークのマイナーが有効なブロックを見つけた時に、別のマイナーが先に、ブロックチェーンの先端に競合しているブロックを公開している場合があります。この有効ではあるが、古いブロックはオマーとして新しいブロックに含むことができ、ブロック報酬の一部を受け取ることができます。「オマー」という用語は、親ブロックの兄弟を表す性別に依存しない用語として好まれます。時には、「アンクル」と呼ばれることもあります。 イーサリアムが プルーフ・オブ・ワーク ネットワークだった頃にこの呼び名が一般的でした。現在、イーサリアムは プルーフ・オブ・ステーク を使用するため、スロットごとに1つのブロック提案者のみが選択されます。", - "on-chain-term": "オンチェーン", - "on-chain-definition": "ブロックチェーン上で行われたアクションやトランザクションを意味し、公開され参照可能であることです。", + "onchain-term": "オンチェーン", + "onchain-definition": "ブロックチェーン上で行われたアクションやトランザクションを意味し、公開され参照可能であることです。", "optimistic-rollup-term": "オプティミスティック・ロールアップ", "optimistic-rollup-definition": "オプティミスティック・ロールアップは、レイヤー2ソリューションでイーサリアムのトランザクションの速度を上げます。トランザクションは、異議申し立てが行われない限り、デフォルトでは有効であると仮定されます。詳細はオプティミスティック・ロールアップをご覧ください。", "peer-to-peer-network-term": "ピアツーピアネットワーク", diff --git a/src/intl/ja/glossary.json b/src/intl/ja/glossary.json index 9ccec6e1ab9..67e8e1e04c4 100644 --- a/src/intl/ja/glossary.json +++ b/src/intl/ja/glossary.json @@ -257,12 +257,12 @@ "node-definition": "ネットワークに参加するソフトウェアクライアント。詳細は、ノードとクライアントをご覧ください。", "nonce-term": "ノンス", "nonce-definition": "暗号技術において、ただ一度だけ使える値。アカウントノンスは、各アカウントのトランザクションのカウンターで、リプレイ攻撃を防ぐために使用されます。", - "off-chain-term": "オフチェーン", - "off-chain-definition": "オフチェーンは、トランザクションまたはデータがブロックチェーンの外にあることを指します。すべてのトランザクションをオンチェーンでコミットするのは高額で非効率な場合があるため、価格データを扱うオラクルのようなサードパーティーツールや、より高いスループットを実行するレイヤー2ソリューションがオフチェーンで大量の計算を扱い、少ない頻度で情報をオンチェーンに送信します。", + "offchain-term": "オフチェーン", + "offchain-definition": "オフチェーンは、トランザクションまたはデータがブロックチェーンの外にあることを指します。すべてのトランザクションをオンチェーンでコミットするのは高額で非効率な場合があるため、価格データを扱うオラクルのようなサードパーティーツールや、より高いスループットを実行するレイヤー2ソリューションがオフチェーンで大量の計算を扱い、少ない頻度で情報をオンチェーンに送信します。", "ommer-term": "オマー(アンクル)ブロック", "ommer-definition": "プルーフ・オブ・ワークのマイナーが有効なブロックを見つけた時に、別のマイナーが先に、ブロックチェーンの先端に競合しているブロックを公開している場合があります。この有効ではあるが、古いブロックはオマーとして新しいブロックに含むことができ、ブロック報酬の一部を受け取ることができます。「オマー」という用語は、親ブロックの兄弟を表す性別に依存しない用語として好まれます。時には、「アンクル」と呼ばれることもあります。 イーサリアムが プルーフ・オブ・ワーク ネットワークだった頃にこの呼び名が一般的でした。現在、イーサリアムは プルーフ・オブ・ステーク を使用するため、スロットごとに1つのブロック提案者のみが選択されます。", - "on-chain-term": "オンチェーン", - "on-chain-definition": "ブロックチェーンで発生した公開されているアクションやトランザクションを指します。

誰もが閲覧してチェックできる、共有の大きなノートブックに何かを書くことを想像してみてください。これにより、書かれたもの(デジタルマネーの送信やコントラクトの作成など)が何であれ、永続的で変更または消去できないことが確実になります。", + "onchain-term": "オンチェーン", + "onchain-definition": "ブロックチェーンで発生した公開されているアクションやトランザクションを指します。

誰もが閲覧してチェックできる、共有の大きなノートブックに何かを書くことを想像してみてください。これにより、書かれたもの(デジタルマネーの送信やコントラクトの作成など)が何であれ、永続的で変更または消去できないことが確実になります。", "optimistic-rollup-term": "オプティミスティック・ロールアップ", "optimistic-rollup-definition": "オプティミスティック・ロールアップは、レイヤー2ソリューションでイーサリアムのトランザクションの速度を上げます。トランザクションは、異議申し立てが行われない限り、デフォルトでは有効であると仮定されます。詳細はオプティミスティック・ロールアップをご覧ください。", "oracle-term": "オラクル", diff --git a/src/intl/pt-br/glossary-tooltip.json b/src/intl/pt-br/glossary-tooltip.json index 160ab70524c..cd5df921f60 100644 --- a/src/intl/pt-br/glossary-tooltip.json +++ b/src/intl/pt-br/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "Um cliente de software que participa da rede. Mais sobre nós e clientes.", "ommer-term": "Bloco ommer (tio)", "ommer-definition": "Quando um minerador de prova de trabalho encontra um bloco válido, outro minerador pode ter publicado um bloco concorrente que é adicionado à ponta da blockchain primeiro. Este bloco válido, mas obsoleto, pode ser incluído por blocos mais novos como ommers e receber uma recompensa de bloco parcial. O termo \"ommer\" é o termo neutro de gênero preferido para o irmão de um bloco pai, mas às vezes também é chamado de \"tio\". Isso era comum para o Ethereum quando era uma rede de prova de trabalho. Agora que o Ethereum usa prova de participação, apenas um proponente de bloco é selecionado por slot.", - "on-chain-term": "On-chain", - "on-chain-definition": "Refere-se a ações ou transações que ocorrem na blockchain e estão disponíveis publicamente.", + "onchain-term": "On-chain", + "onchain-definition": "Refere-se a ações ou transações que ocorrem na blockchain e estão disponíveis publicamente.", "optimistic-rollup-term": "Acúmulo otimista", "optimistic-rollup-definition": "O Optimistic Rollup é uma solução de Camada 2 que acelera as transações no Ethereum, assumindo que elas são válidas por padrão, a menos que sejam contestadas. Mais sobre Optimistic rollups.", "peer-to-peer-network-term": "Rede ponto a ponto", diff --git a/src/intl/pt-br/glossary.json b/src/intl/pt-br/glossary.json index 803b6b332f7..ed748e25622 100644 --- a/src/intl/pt-br/glossary.json +++ b/src/intl/pt-br/glossary.json @@ -257,12 +257,12 @@ "node-definition": "Um cliente de software que participa da rede. Mais sobre nós e clientes.", "nonce-term": "Nonce", "nonce-definition": "Em criptografia, um valor que só pode ser usado uma vez. Um nonce de conta é um contador de transações em cada conta, que é usado para evitar ataques de repetição.", - "off-chain-term": "Off-Chain", - "off-chain-definition": "Off-chain significa qualquer transação ou dado que exista fora da blockchain. Como o comprometimento de cada transação na cadeia pode ser caro e ineficiente, ferramentas de terceiros, como oráculos que lidam com dados de preços, ou soluções de camada 2 que executam um maior volume de transações, lidam com a maior parte do trabalho de processamento fora da cadeia e enviam informações para a cadeia em intervalos menos frequentes.", + "offchain-term": "Off-Chain", + "offchain-definition": "Off-chain significa qualquer transação ou dado que exista fora da blockchain. Como o comprometimento de cada transação na cadeia pode ser caro e ineficiente, ferramentas de terceiros, como oráculos que lidam com dados de preços, ou soluções de camada 2 que executam um maior volume de transações, lidam com a maior parte do trabalho de processamento fora da cadeia e enviam informações para a cadeia em intervalos menos frequentes.", "ommer-term": "Bloco ommer (tio)", "ommer-definition": "Quando um minerador de prova de trabalho encontra um bloco válido, outro minerador pode ter publicado um bloco concorrente que é adicionado à ponta da blockchain primeiro. Este bloco válido, mas obsoleto, pode ser incluído por blocos mais novos como ommers e receber uma recompensa de bloco parcial. O termo \"ommer\" é o termo neutro de gênero preferido para o irmão de um bloco pai, mas às vezes também é chamado de \"tio\". Isso era comum para o Ethereum quando era uma rede de prova de trabalho. Agora que o Ethereum usa prova de participação, apenas um proponente de bloco é selecionado por slot.", - "on-chain-term": "On-Chain", - "on-chain-definition": "Refere-se a ações ou transações que ocorrem no blockchain e estão disponíveis publicamente.

Pense nisso como se estivesse escrevendo algo em um caderno grande e compartilhado que todos podem ver e verificar, certificando-se de que tudo o que está escrito (como enviar dinheiro digital ou fazer um contrato) é permanente e não pode ser alterado ou apagado.", + "onchain-term": "On-Chain", + "onchain-definition": "Refere-se a ações ou transações que ocorrem no blockchain e estão disponíveis publicamente.

Pense nisso como se estivesse escrevendo algo em um caderno grande e compartilhado que todos podem ver e verificar, certificando-se de que tudo o que está escrito (como enviar dinheiro digital ou fazer um contrato) é permanente e não pode ser alterado ou apagado.", "optimistic-rollup-term": "Acúmulo otimista", "optimistic-rollup-definition": "O Optimistic Rollup é uma solução de Camada 2 que acelera as transações no Ethereum, assumindo que elas são válidas por padrão, a menos que sejam contestadas. Mais sobre Optimistic rollups.", "oracle-term": "Oráculo", diff --git a/src/intl/tr/glossary-tooltip.json b/src/intl/tr/glossary-tooltip.json index 5a06e815ecb..64dff2f6641 100644 --- a/src/intl/tr/glossary-tooltip.json +++ b/src/intl/tr/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "Ağa katılan bir yazılım istemcisidir. Düğümler ve istemciler hakkında daha fazla bilgi.", "ommer-term": "Ommer (amca) bloğu", "ommer-definition": "Bir iş ispatı madencisi geçerli bir blok bulduğunda, başka bir madenci ondan önce blokzincirin ucuna eklenen rakip bir blok yayınlamış olabilir. Bu geçerli ancak eski blok, ommer olarak daha yeni bloklara dahil edilebilir ve kısmi bir blok ödülü alabilir. \"Ommer\" terimi, bir ebeveyn bloğunun kardeşi için tercih edilen cinsiyet ayrımı gözetmeyen bir terimdir ancak buna bazen \"amca\" da denir. Bu, bir iş ispatı ağıyken Ethereum için yaygındı. Ethereum artık hisse ispatı kullandığından, yuva başına yalnızca bir blok önerici seçilir.", - "on-chain-term": "Zincir üstünde", - "on-chain-definition": "Blokzincir üstünde gerçekleşen ve herkese açık olan eylemleri veya işlemleri ifade eder.", + "onchain-term": "Zincir üstünde", + "onchain-definition": "Blokzincir üstünde gerçekleşen ve herkese açık olan eylemleri veya işlemleri ifade eder.", "optimistic-rollup-term": "İyimser toplama", "optimistic-rollup-definition": "İyimser Toplama, Ethereum üzerindeki işlemlerin itiraz edilmediği sürece varsayılan olarak doğru olduğunu kabul eden ve onları hızlandıran bir Katman 2 çözümüdür. İyimser toplamalar hakkında daha fazla bilgi.", "peer-to-peer-network-term": "Eşler arası ağ", diff --git a/src/intl/tr/glossary.json b/src/intl/tr/glossary.json index ea6cccef22a..498d719972f 100644 --- a/src/intl/tr/glossary.json +++ b/src/intl/tr/glossary.json @@ -257,12 +257,12 @@ "node-definition": "Ağa katılan bir yazılım istemcisidir. Düğümler ve istemciler hakkında daha fazla bilgi.", "nonce-term": "Nonce", "nonce-definition": "Kriptografide, yalnızca bir kez kullanılabilen bir değerdir. Hesap nonce'ı, tekrar saldırılarını önlemek için her hesapta kullanılan bir işlem sayacıdır.", - "off-chain-term": "Zincir Dışında", - "off-chain-definition": "Zincir dışında, blokzincirin dışında var olan herhangi bir işlem veya veri anlamına gelir. Her işlemi zincir üstünde gerçekleştirmek pahalı ve verimsiz olabileceğinden, fiyatlandırma verilerini işleyen kâhinler veya daha yüksek işlem hacmi yürüten katman 2 çözümleri gibi üçüncü taraf araçlar, işleme işinin büyük bir kısmını zincir dışında gerçekleştirir ve zincir üstünde daha az sıklıkta bilgi gönderir.", + "offchain-term": "Zincir Dışında", + "offchain-definition": "Zincir dışında, blokzincirin dışında var olan herhangi bir işlem veya veri anlamına gelir. Her işlemi zincir üstünde gerçekleştirmek pahalı ve verimsiz olabileceğinden, fiyatlandırma verilerini işleyen kâhinler veya daha yüksek işlem hacmi yürüten katman 2 çözümleri gibi üçüncü taraf araçlar, işleme işinin büyük bir kısmını zincir dışında gerçekleştirir ve zincir üstünde daha az sıklıkta bilgi gönderir.", "ommer-term": "Ommer (amca) bloğu", "ommer-definition": "Bir iş ispatı madencisi geçerli bir blok bulduğunda, başka bir madenci ondan önce blokzincirin ucuna eklenen rakip bir blok yayınlamış olabilir. Bu geçerli ancak eski blok, ommer olarak daha yeni bloklara dahil edilebilir ve kısmi bir blok ödülü alabilir. \"Ommer\" terimi, bir ebeveyn bloğunun kardeşi için tercih edilen cinsiyet ayrımı gözetmeyen bir terimdir ancak buna bazen \"amca\" da denir. Bu, bir iş ispatı ağıyken Ethereum için yaygındı. Ethereum artık hisse ispatı kullandığından, yuva başına yalnızca bir blok önerici seçilir.", - "on-chain-term": "Zincir Üstünde", - "on-chain-definition": "Blokzincirde gerçekleşen ve halka açık olan eylem veya işlemleri ifade eder.

Bunu, herkesin görebileceği ve kontrol edebileceği büyük, paylaşılan bir not defterine bir şeyler yazmak gibi düşünün. Yazılanların (örneğin dijital para göndermek veya sözleşme yapmak) hem kalıcı hem de değiştirilemez veya silinemez olmasını sağlayın.", + "onchain-term": "Zincir Üstünde", + "onchain-definition": "Blokzincirde gerçekleşen ve halka açık olan eylem veya işlemleri ifade eder.

Bunu, herkesin görebileceği ve kontrol edebileceği büyük, paylaşılan bir not defterine bir şeyler yazmak gibi düşünün. Yazılanların (örneğin dijital para göndermek veya sözleşme yapmak) hem kalıcı hem de değiştirilemez veya silinemez olmasını sağlayın.", "optimistic-rollup-term": "İyimser toplama", "optimistic-rollup-definition": "İyimser Toplama, Ethereum üzerindeki işlemlerin itiraz edilmediği sürece varsayılan olarak doğru olduğunu kabul eden ve onları hızlandıran bir Katman 2 çözümüdür. İyimser toplamalar hakkında daha fazla bilgi.", "oracle-term": "Kâhin", diff --git a/src/intl/zh-tw/glossary-tooltip.json b/src/intl/zh-tw/glossary-tooltip.json index e4ea8072f97..5ff8f15e3f1 100644 --- a/src/intl/zh-tw/glossary-tooltip.json +++ b/src/intl/zh-tw/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "參與網路的軟體用戶端。更多關於節點和用戶端的資訊。", "ommer-term": "Ommer(叔)區塊", "ommer-definition": "當工作量證明礦工發現有效的區塊時,另一個礦工可能已經發布了首先新增到區塊鏈頂端的競爭區塊。這個有效但過時的區塊可以作為 ommer 被新區塊包含,並獲得部分區塊獎勵。術語「ommer」是對父塊的兄弟姐妹區塊的首選中性術語,但有時也被稱為「叔」。當以太坊仍是工作證明網路時,這對於以太坊來說很常見。現在以太坊使用權益證明,每個時隙只會選擇一個區塊提議者。", - "on-chain-term": "鏈上", - "on-chain-definition": "指在區塊鏈上發生且公開的操作或交易。", + "onchain-term": "鏈上", + "onchain-definition": "指在區塊鏈上發生且公開的操作或交易。", "optimistic-rollup-term": "樂觀卷軸", "optimistic-rollup-definition": "樂觀卷軸是一種二層網路解決方案,可以加速以太坊上的交易,假設除非受到挑戰,否則預設交易都是有效的。更多關於樂觀卷軸的資訊。", "peer-to-peer-network-term": "點對點網路", diff --git a/src/intl/zh-tw/glossary.json b/src/intl/zh-tw/glossary.json index 3c33752574d..b92580ef626 100644 --- a/src/intl/zh-tw/glossary.json +++ b/src/intl/zh-tw/glossary.json @@ -257,12 +257,12 @@ "node-definition": "參與網路的軟體用戶端。更多關於節點和用戶端的資訊。", "nonce-term": "隨機數", "nonce-definition": "在密碼學裏,只能使用一次的值。帳戶隨機數是每個帳戶中的交易計數器,用於防止重播攻擊。", - "off-chain-term": "鏈下", - "off-chain-definition": "鏈下是指存在於區塊鏈以外的任何交易或資料。由於在鏈上提交每筆交易可能成本高昂且效率低下,因此第三方工具(例如處理定價資料的預言機)或執行更高吞吐量交易的二層網路解決方案,在鏈下處理大量工作並會以較低的頻率提交資訊到鏈上。", + "offchain-term": "鏈下", + "offchain-definition": "鏈下是指存在於區塊鏈以外的任何交易或資料。由於在鏈上提交每筆交易可能成本高昂且效率低下,因此第三方工具(例如處理定價資料的預言機)或執行更高吞吐量交易的二層網路解決方案,在鏈下處理大量工作並會以較低的頻率提交資訊到鏈上。", "ommer-term": "Ommer(叔)區塊", "ommer-definition": "當工作量證明礦工發現有效的區塊時,另一個礦工可能已經發布了首先新增到區塊鏈頂端的競爭區塊。這個有效但過時的區塊可以作為 ommer 被新區塊包含,並獲得部分區塊獎勵。術語「ommer」是對父塊的兄弟姐妹區塊的首選中性術語,但有時也被稱為「叔」。當以太坊仍是工作證明網路時,這對於以太坊來說很常見。現在以太坊使用權益證明,每個時隙只會選擇一個區塊提議者。", - "on-chain-term": "鏈上", - "on-chain-definition": "指在區塊鏈上發生且公開的操作或交易。

可以將其視為在一個共享大筆記本中寫一些東西,每個人都可以看到和檢查,確保所寫的內容(例如傳送數位貨幣或簽訂合約)是永久性的並且無法更改或刪除。", + "onchain-term": "鏈上", + "onchain-definition": "指在區塊鏈上發生且公開的操作或交易。

可以將其視為在一個共享大筆記本中寫一些東西,每個人都可以看到和檢查,確保所寫的內容(例如傳送數位貨幣或簽訂合約)是永久性的並且無法更改或刪除。", "optimistic-rollup-term": "樂觀卷軸", "optimistic-rollup-definition": "樂觀卷軸是一種二層網路解決方案,可以加速以太坊上的交易,假設除非受到挑戰,否則預設交易都是有效的。更多關於樂觀卷軸的資訊。", "oracle-term": "預言機", diff --git a/src/intl/zh/glossary-tooltip.json b/src/intl/zh/glossary-tooltip.json index c0a7004d7a2..64e47a9e30c 100644 --- a/src/intl/zh/glossary-tooltip.json +++ b/src/intl/zh/glossary-tooltip.json @@ -101,8 +101,8 @@ "node-definition": "参与网络的软件客户端。了解有关节点和客户端的更多信息。", "ommer-term": "叔块", "ommer-definition": "当工作量证明矿工发现有效的区块时,另一个矿工可能已经发布了首先添加到区块链顶端的竞争区块。这个有效但过时的区块可以作为叔块包含在新区块内,并获得部分区块奖励。术语“ommer”是指代父块同胞的首选中性术语,但有时也称为“uncle”。当以太坊曾经是一个工作量证明网络时,这对于以太坊来说很常见。现在以太坊使用权益证明,每个时隙只选择一个区块提议者。", - "on-chain-term": "链上", - "on-chain-definition": "是指发生在区块链上并且公开的操作或交易。", + "onchain-term": "链上", + "onchain-definition": "是指发生在区块链上并且公开的操作或交易。", "optimistic-rollup-term": "乐观卷叠", "optimistic-rollup-definition": "乐观卷叠是一种二层网络解决方案,可以加速以太坊上的交易,假设交易默认有效,除非受到质疑。了解有关乐观卷叠的更多信息。", "peer-to-peer-network-term": "对等网络", diff --git a/src/intl/zh/glossary.json b/src/intl/zh/glossary.json index aba62911eb0..130b98fcaca 100644 --- a/src/intl/zh/glossary.json +++ b/src/intl/zh/glossary.json @@ -257,12 +257,12 @@ "node-definition": "参与网络的软件客户端。了解有关节点和客户端的更多信息。", "nonce-term": "Nonce", "nonce-definition": "在密码学中,只能使用一次的值。帐户随机数是每个帐户中的交易计数器,用于防止重放攻击。", - "off-chain-term": "链下", - "off-chain-definition": "链下是指存在于区块链之外的任何交易或数据。由于在链上进行每笔交易可能成本高昂且效率低下,因此第三方工具(例如处理定价数据的预言机)或执行较高吞吐量交易的二层网络解决方案在链下执行大量处理工作,并以更低的频率在链上提交信息。", + "offchain-term": "链下", + "offchain-definition": "链下是指存在于区块链之外的任何交易或数据。由于在链上进行每笔交易可能成本高昂且效率低下,因此第三方工具(例如处理定价数据的预言机)或执行较高吞吐量交易的二层网络解决方案在链下执行大量处理工作,并以更低的频率在链上提交信息。", "ommer-term": "叔块", "ommer-definition": "当工作量证明矿工发现有效的区块时,另一个矿工可能已经发布了首先添加到区块链顶端的竞争区块。这个有效但过时的区块可以作为叔块包含在新区块内,并获得部分区块奖励。术语“ommer”是指代父块同胞的首选中性术语,但有时也称为“uncle”。当以太坊曾经是一个工作量证明网络时,这对于以太坊来说很常见。现在以太坊使用权益证明,每个时隙只选择一个区块提议者。", - "on-chain-term": "链上", - "on-chain-definition": "指区块链上发生的公开操作或交易。

将其视为在一个共享大笔记本中写一些东西,每个人都可以看到和检查,确保所写的任何内容(例如发送数字货币或签订合约)是永久性的,无法更改或删除。", + "onchain-term": "链上", + "onchain-definition": "指区块链上发生的公开操作或交易。

将其视为在一个共享大笔记本中写一些东西,每个人都可以看到和检查,确保所写的任何内容(例如发送数字货币或签订合约)是永久性的,无法更改或删除。", "optimistic-rollup-term": "乐观卷叠", "optimistic-rollup-definition": "乐观卷叠是一种二层网络解决方案,可以加速以太坊上的交易,假设交易默认有效,除非受到质疑。了解有关乐观卷叠的更多信息。", "oracle-term": "预言机", diff --git a/src/layouts/Docs.tsx b/src/layouts/Docs.tsx index a4e521886b9..c9abf47bf2e 100644 --- a/src/layouts/Docs.tsx +++ b/src/layouts/Docs.tsx @@ -1,12 +1,9 @@ -import { useRouter } from "next/router" import type { HTMLAttributes } from "react" -import { Badge } from "@chakra-ui/react" import { ChildOnlyProp } from "@/lib/types" import type { DocsFrontmatter, MdPageContent } from "@/lib/interfaces" import BannerNotification from "@/components/Banners/BannerNotification" -import { ButtonLink } from "@/components/Buttons" import CallToContribute from "@/components/CallToContribute" import Card from "@/components/Card" import Codeblock from "@/components/Codeblock" @@ -28,6 +25,7 @@ import SideNav from "@/components/SideNav" import SideNavMobile from "@/components/SideNavMobile" import TableOfContents from "@/components/TableOfContents" import Translation from "@/components/Translation" +import { ButtonLink } from "@/components/ui/buttons/Button" import { Divider } from "@/components/ui/divider" import InlineLink from "@/components/ui/Link" import { mdxTableComponents } from "@/components/ui/table" @@ -36,6 +34,8 @@ import YouTube from "@/components/YouTube" import { cn } from "@/lib/utils/cn" import { getEditPath } from "@/lib/utils/editPath" +import { usePathname } from "@/i18n/routing" + const baseHeadingClasses = "font-mono uppercase font-bold scroll-mt-40 break-words" @@ -81,7 +81,6 @@ export const docsComponents = { h4: H4, pre: Codeblock, ...mdxTableComponents, - Badge, ButtonLink, Card, CallToContribute, @@ -115,12 +114,12 @@ export const DocsLayout = ({ contentNotTranslated, }: DocsLayoutProps) => { const isPageIncomplete = !!frontmatter.incomplete - const { asPath: relativePath } = useRouter() - const absoluteEditPath = getEditPath(relativePath) + const pathname = usePathname() + const absoluteEditPath = getEditPath(pathname) return (
- + {isPageIncomplete && ( @@ -130,7 +129,7 @@ export const DocsLayout = ({ className="flex justify-between bg-background-highlight lg:pe-8" dir={contentNotTranslated ? "ltr" : "unset"} > - +

{frontmatter.title}

) => ( @@ -86,13 +87,14 @@ export const StaticLayout = ({ lastEditLocaleTimestamp, contentNotTranslated, }: StaticLayoutProps) => { - const { locale, asPath } = useRouter() + const locale = useLocale() + const pathname = usePathname() const absoluteEditPath = getEditPath(slug) return (
- + - {!asPath.includes("/whitepaper") && ( + {!pathname.includes("/whitepaper") && (

) => ( { - const { asPath: relativePath } = useRouter() - const absoluteEditPath = getEditPath(relativePath) + const pathname = usePathname() + const absoluteEditPath = getEditPath(pathname) return (

diff --git a/src/layouts/md/Roadmap.tsx b/src/layouts/md/Roadmap.tsx index 84e434033eb..9a38cdcf7ed 100644 --- a/src/layouts/md/Roadmap.tsx +++ b/src/layouts/md/Roadmap.tsx @@ -1,5 +1,3 @@ -import { useTranslation } from "next-i18next" - import type { ChildOnlyProp } from "@/lib/types" import type { MdPageContent, RoadmapFrontmatter } from "@/lib/interfaces" @@ -10,6 +8,7 @@ import RoadmapImageContent from "@/components/Roadmap/RoadmapImageContent" import { ContentLayout } from "../ContentLayout" +import { useTranslation } from "@/hooks/useTranslation" import RoadmapHubHeroImage from "@/public/images/heroes/roadmap-hub-hero.jpg" const CardGrid = (props: ChildOnlyProp) => ( diff --git a/src/layouts/md/Staking.tsx b/src/layouts/md/Staking.tsx index f6a85b14112..f5c6efeea43 100644 --- a/src/layouts/md/Staking.tsx +++ b/src/layouts/md/Staking.tsx @@ -1,5 +1,4 @@ import { HTMLAttributes } from "react" -import { useTranslation } from "next-i18next" import type { ChildOnlyProp } from "@/lib/types" import type { MdPageContent, StakingFrontmatter } from "@/lib/interfaces" @@ -26,6 +25,8 @@ import UpgradeStatus from "@/components/UpgradeStatus" import { ContentLayout } from "../ContentLayout" +import { useTranslation } from "@/hooks/useTranslation" + const Heading1 = (props: HTMLAttributes) => ( ) diff --git a/src/layouts/md/Translatathon.tsx b/src/layouts/md/Translatathon.tsx index a52ad42e7ce..24b6ba50eac 100644 --- a/src/layouts/md/Translatathon.tsx +++ b/src/layouts/md/Translatathon.tsx @@ -4,7 +4,7 @@ import type { MdPageContent, SharedFrontmatter } from "@/lib/interfaces" import { List as ButtonDropdownList } from "@/components/ButtonDropdown" import Card from "@/components/Card" import { ContentHero, ContentHeroProps } from "@/components/Hero" -import { TwImage as Image } from "@/components/Image" +import { Image } from "@/components/Image" import { ApplyNow } from "@/components/Translatathon/ApplyNow" import { APPLICATION_URL } from "@/components/Translatathon/constants" import { DatesAndTimeline } from "@/components/Translatathon/DatesAndTimeline" diff --git a/src/layouts/md/Upgrade.tsx b/src/layouts/md/Upgrade.tsx index d48f2261097..40128e528f2 100644 --- a/src/layouts/md/Upgrade.tsx +++ b/src/layouts/md/Upgrade.tsx @@ -1,5 +1,3 @@ -import { useTranslation } from "next-i18next" - import type { ChildOnlyProp } from "@/lib/types" import type { MdPageContent, UpgradeFrontmatter } from "@/lib/interfaces" @@ -14,6 +12,8 @@ import { getSummaryPoints } from "@/lib/utils/getSummaryPoints" import { ContentLayout } from "../ContentLayout" +import { useTranslation } from "@/hooks/useTranslation" + // Upgrade layout components export const upgradeComponents = { MergeArticleList, @@ -42,7 +42,7 @@ export const UpgradeLayout = ({ const dropdownLinks: ButtonDropdownList = { text: t("page-upgrades-upgrades-guide"), - ariaLabel: t("page-upgrades-upgrades-aria-label"), + ariaLabel: t("page-upgrades-index:page-upgrades-upgrades-aria-label"), items: [ { text: t("page-upgrades-upgrades-beacon-chain"), diff --git a/src/layouts/md/UseCases.tsx b/src/layouts/md/UseCases.tsx index 828459d71c8..665608498fe 100644 --- a/src/layouts/md/UseCases.tsx +++ b/src/layouts/md/UseCases.tsx @@ -1,6 +1,3 @@ -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" - import type { ChildOnlyProp } from "@/lib/types" import type { MdPageContent, UseCasesFrontmatter } from "@/lib/interfaces" @@ -8,7 +5,7 @@ import BannerNotification from "@/components/Banners/BannerNotification" import { List as ButtonDropdownList } from "@/components/ButtonDropdown" import Emoji from "@/components/Emoji" import { ContentHero } from "@/components/Hero" -import InlineLink from "@/components/Link" +import InlineLink from "@/components/ui/Link" import { List, ListItem } from "@/components/ui/list" import { getEditPath } from "@/lib/utils/editPath" @@ -16,6 +13,9 @@ import { getSummaryPoints } from "@/lib/utils/getSummaryPoints" import { ContentLayout } from "../ContentLayout" +import { useTranslation } from "@/hooks/useTranslation" +import { usePathname } from "@/i18n/routing" + // UseCases layout components export const useCasesComponents = { // Export empty object if none needed @@ -32,12 +32,12 @@ export const UseCasesLayout = ({ tocItems, contentNotTranslated, }: UseCasesLayoutProps) => { - const { asPath: relativePath } = useRouter() + const pathname = usePathname() const { t } = useTranslation("template-usecase") const summaryPoints = getSummaryPoints(frontmatter) - const absoluteEditPath = getEditPath(relativePath) + const absoluteEditPath = getEditPath(pathname) const dropdownLinks: ButtonDropdownList = { text: t("template-usecase:template-usecase-dropdown"), diff --git a/src/layouts/stories/BaseLayout.stories.tsx b/src/layouts/stories/BaseLayout.stories.tsx index 832795c4255..c0079c8248e 100644 --- a/src/layouts/stories/BaseLayout.stories.tsx +++ b/src/layouts/stories/BaseLayout.stories.tsx @@ -1,6 +1,7 @@ -import { Center } from "@chakra-ui/react" import type { Meta, StoryObj } from "@storybook/react" +import { Center } from "@/components/ui/flex" + import { langViewportModes } from "../../../.storybook/modes" import { BaseLayout as BaseLayoutComponent } from "../BaseLayout" @@ -14,6 +15,9 @@ const meta = { ...langViewportModes, }, }, + nextjs: { + appDirectory: true, + }, }, argTypes: { children: { @@ -34,7 +38,7 @@ export default meta export const BaseLayout: StoryObj = { args: { children: ( -
+
Content Here
), diff --git a/src/layouts/stories/ContentLayout.stories.tsx b/src/layouts/stories/ContentLayout.stories.tsx index 64789322754..44b16b08087 100644 --- a/src/layouts/stories/ContentLayout.stories.tsx +++ b/src/layouts/stories/ContentLayout.stories.tsx @@ -1,6 +1,7 @@ -import { Center } from "@chakra-ui/react" import type { Meta, StoryObj } from "@storybook/react" +import { Center } from "@/components/ui/flex" + import { langViewportModes } from "../../../.storybook/modes" import { ContentLayout as ContentLayoutComponent } from "../ContentLayout" @@ -29,7 +30,7 @@ export default meta export const ContentLayout: StoryObj = { args: { children: ( -
+
Content Here
), @@ -61,7 +62,7 @@ export const ContentLayout: StoryObj = { }, maxDepth: 2, heroSection: ( -
+
Hero section
), diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 83fc01c9863..4149b2465c9 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -6,7 +6,7 @@ import i18nConfig from "../../i18n.config.json" import type { CommunityBlog } from "./types" -export const OLD_CONTENT_DIR = "src/content" +export const OLD_CONTENT_DIR = "src/content" // For old git commit history -- do not remove export const CONTENT_DIR = "public/content" export const TRANSLATIONS_DIR = "public/content/translations" export const TRANSLATED_IMAGES_DIR = "/content/translations" @@ -19,7 +19,7 @@ export const NULL_VALUE = "—" export const DEFAULT_LOCALE = "en" export const FAKE_LOCALE = "default" // Sorted list of supported locales codes, defined in `i18n.config.json` -const BUILD_LOCALES = process.env.BUILD_LOCALES +const BUILD_LOCALES = process.env.NEXT_PUBLIC_BUILD_LOCALES export const LOCALES_CODES = BUILD_LOCALES ? BUILD_LOCALES.split(",") : i18nConfig.map(({ code }) => code) diff --git a/src/lib/types.ts b/src/lib/types.ts index f79699248e2..7557f139428 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -2,7 +2,6 @@ import type { Options } from "mdast-util-toc" import type { NextPage } from "next" import type { AppProps } from "next/app" import type { StaticImageData } from "next/image" -import type { SSRConfig } from "next-i18next" import type { ReactElement, ReactNode } from "react" import type { ColumnDef } from "@tanstack/react-table" @@ -28,7 +27,7 @@ import allQuestionData from "@/data/quizzes/questionBank" import { screens } from "./utils/screen" import { WALLETS_FILTERS_DEFAULT } from "./constants" -import { layoutMapping } from "@/pages/[...slug]" +import { layoutMapping } from "@/pages/[locale]/[...slug]" // Credit: https://stackoverflow.com/a/52331580 export type Unpacked = T extends (infer U)[] ? U : T @@ -55,8 +54,14 @@ export type Root = { lastDeployLocaleTimestamp: string } -export type BasePageProps = SSRConfig & - Pick +export type BasePageProps = Pick< + Root, + "contentNotTranslated" | "lastDeployLocaleTimestamp" +> + +export type Params = { + locale: string +} export type Frontmatter = RoadmapFrontmatter & UpgradeFrontmatter & diff --git a/src/lib/utils/editPath.ts b/src/lib/utils/editPath.ts index 5129016e4df..11863f1acc8 100644 --- a/src/lib/utils/editPath.ts +++ b/src/lib/utils/editPath.ts @@ -2,5 +2,10 @@ import { join } from "path" import { CONTENT_DIR, EDIT_CONTENT_URL } from "@/lib/constants" +import { cleanPath } from "./url" + export const getEditPath = (relativePath: string): string => - new URL(join(CONTENT_DIR, relativePath, "index.md"), EDIT_CONTENT_URL).href + new URL( + join(CONTENT_DIR, cleanPath(relativePath), "index.md"), + EDIT_CONTENT_URL + ).href diff --git a/src/lib/utils/md.ts b/src/lib/utils/md.ts index 7497e70a135..08dd074f9f8 100644 --- a/src/lib/utils/md.ts +++ b/src/lib/utils/md.ts @@ -16,308 +16,44 @@ import { CONTENT_DIR, DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" import { toPosixPath } from "./relativePath" -import { ITutorial } from "@/pages/developers/tutorials" +import { ITutorial } from "@/pages/[locale]/developers/tutorials" -function getCurrentDir() { +function getContentRoot() { return join(process.cwd(), CONTENT_DIR) } const getPostSlugs = (dir: string, files: string[] = []) => { - const currentDir = getCurrentDir() - const contentDir = join(currentDir, dir) - // Temporal list of content pages allowed to be compiled - // When a content page is migrated (and he components being used), should be added to this list - const temporalAllowedPages = [ - // Use cases (8/8) ✅ - "/dao", - "/decentralized-identity", - "/defi", - "/desci", - "/nft", - "/payments", - "/refi", - "/social-networks", - // Staking (4/4) ✅ - "/staking/pools", - "/staking/saas", - "/staking/solo", - "/staking/withdrawals", - // Roadmap (5/5) ✅ - "/roadmap", - "/roadmap/future-proofing", - "/roadmap/scaling", - "/roadmap/security", - "/roadmap/user-experience", - // Upgrade (2/2) ✅ - "/roadmap/beacon-chain", - "/roadmap/merge", - // Developer docs (0/95) - "/developers/docs/", - "/developers/docs/accounts", - "/developers/docs/apis/backend", - "/developers/docs/apis/javascript", - "/developers/docs/apis/json-rpc", - "/developers/docs/blocks", - "/developers/docs/bridges", - "/developers/docs/consensus-mechanisms", - "/developers/docs/consensus-mechanisms/poa", - "/developers/docs/consensus-mechanisms/pos", - "/developers/docs/consensus-mechanisms/pos/attack-and-defense", - "/developers/docs/consensus-mechanisms/pos/attestations", - "/developers/docs/consensus-mechanisms/pos/block-proposal", - "/developers/docs/consensus-mechanisms/pos/faqs", - "/developers/docs/consensus-mechanisms/pos/gasper", - "/developers/docs/consensus-mechanisms/pos/keys", - "/developers/docs/consensus-mechanisms/pos/pos-vs-pow", - "/developers/docs/consensus-mechanisms/pos/rewards-and-penalties", - "/developers/docs/consensus-mechanisms/pos/weak-subjectivity", - "/developers/docs/consensus-mechanisms/pow/", - "/developers/docs/consensus-mechanisms/pow/mining", - "/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms", - "/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/dagger-hashimoto", - "/developers/docs/consensus-mechanisms/pow/mining/mining-algorithms/ethash", - "/developers/docs/dapps", - "/developers/docs/data-and-analytics", - "/developers/docs/data-and-analytics/block-explorers", - "/developers/docs/data-availability", - "/developers/docs/data-availability/blockchain-data-storage-strategies", - "/developers/docs/data-structures-and-encoding", - "/developers/docs/data-structures-and-encoding/patricia-merkle-trie", - "/developers/docs/data-structures-and-encoding/rlp", - "/developers/docs/data-structures-and-encoding/ssz", - "/developers/docs/data-structures-and-encoding/web3-secret-storage", - "/developers/docs/design-and-ux", - "/developers/docs/design-and-ux/heuristics-for-web3", - "/developers/docs/design-and-ux/dex-design-best-practice", - "/developers/docs/development-networks", - "/developers/docs/ethereum-stack", - "/developers/docs/evm", - "/developers/docs/evm/opcodes", - "/developers/docs/frameworks", - "/developers/docs/gas", - "/developers/docs/ides", - "/developers/docs/intro-to-ether", - "/developers/docs/intro-to-ethereum", - "/developers/docs/mev", - "/developers/docs/networking-layer", - "/developers/docs/networking-layer/network-addresses", - "/developers/docs/networking-layer/portal-network", - "/developers/docs/networks", - "/developers/docs/nodes-and-clients", - "/developers/docs/nodes-and-clients/archive-nodes", - "/developers/docs/nodes-and-clients/bootnodes", - "/developers/docs/nodes-and-clients/client-diversity", - "/developers/docs/nodes-and-clients/light-clients", - "/developers/docs/nodes-and-clients/node-architecture", - "/developers/docs/nodes-and-clients/nodes-as-a-service", - "/developers/docs/nodes-and-clients/run-a-node", - "/developers/docs/oracles", - "/developers/docs/programming-languages", - "/developers/docs/programming-languages/dart", - "/developers/docs/programming-languages/delphi", - "/developers/docs/programming-languages/dot-net", - "/developers/docs/programming-languages/elixir", - "/developers/docs/programming-languages/golang", - "/developers/docs/programming-languages/java", - "/developers/docs/programming-languages/javascript", - "/developers/docs/programming-languages/python", - "/developers/docs/programming-languages/ruby", - "/developers/docs/programming-languages/rust", - "/developers/docs/scaling", - "/developers/docs/scaling/optimistic-rollups", - "/developers/docs/scaling/plasma", - "/developers/docs/scaling/sidechains", - "/developers/docs/scaling/state-channels", - "/developers/docs/scaling/validium", - "/developers/docs/scaling/zk-rollups", - "/developers/docs/smart-contracts", - "/developers/docs/smart-contracts/anatomy", - "/developers/docs/smart-contracts/compiling", - "/developers/docs/smart-contracts/composability", - "/developers/docs/smart-contracts/deploying", - "/developers/docs/smart-contracts/formal-verification", - "/developers/docs/smart-contracts/languages", - "/developers/docs/smart-contracts/libraries", - "/developers/docs/smart-contracts/security", - "/developers/docs/smart-contracts/testing", - "/developers/docs/smart-contracts/upgrading", - "/developers/docs/smart-contracts/verifying", - "/developers/docs/standards", - "/developers/docs/standards/tokens", - "/developers/docs/standards/tokens/erc-20", - "/developers/docs/standards/tokens/erc-223", - "/developers/docs/standards/tokens/erc-721", - "/developers/docs/standards/tokens/erc-777", - "/developers/docs/standards/tokens/erc-1155", - "/developers/docs/standards/tokens/erc-4626", - "/developers/docs/storage", - "/developers/docs/transactions", - "/developers/docs/web2-vs-web3", - // Developer tutorials (53/53) ✅ - "/developers/tutorials/a-developers-guide-to-ethereum-part-one", - "/developers/tutorials/all-you-can-cache", - "/developers/tutorials/calling-a-smart-contract-from-javascript", - "/developers/tutorials/create-and-deploy-a-defi-app", - "/developers/tutorials/deploying-your-first-smart-contract", - "/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet", - "/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit", - "/developers/tutorials/eip-1271-smart-contract-signatures", - "/developers/tutorials/erc-721-vyper-annotated-code", - "/developers/tutorials/erc20-annotated-code", - "/developers/tutorials/erc20-with-safety-rails", - "/developers/tutorials/getting-started-with-ethereum-development-using-alchemy", - "/developers/tutorials/guide-to-smart-contract-security-tools", - "/developers/tutorials/hello-world-smart-contract", - "/developers/tutorials/hello-world-smart-contract-fullstack", - "/developers/tutorials/how-to-implement-an-erc721-market", - "/developers/tutorials/how-to-mint-an-nft", - "/developers/tutorials/how-to-mock-solidity-contracts-for-testing", - "/developers/tutorials/how-to-use-echidna-to-test-smart-contracts", - "/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs", - "/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs", - "/developers/tutorials/how-to-use-tellor-as-your-oracle", - "/developers/tutorials/how-to-view-nft-in-metamask", - "/developers/tutorials/how-to-write-and-deploy-an-nft", - "/developers/tutorials/interact-with-other-contracts-from-solidity", - "/developers/tutorials/ipfs-decentralized-ui", - "/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app", - "/developers/tutorials/learn-foundational-ethereum-topics-with-sql", - "/developers/tutorials/logging-events-smart-contracts", - "/developers/tutorials/merkle-proofs-for-offline-data-integrity", - "/developers/tutorials/monitoring-geth-with-influxdb-and-grafana", - "/developers/tutorials/nft-minter", - "/developers/tutorials/optimism-std-bridge-annotated-code", - "/developers/tutorials/reverse-engineering-a-contract", - "/developers/tutorials/run-node-raspberry-pi", - "/developers/tutorials/scam-token-tricks", - "/developers/tutorials/secure-development-workflow", - "/developers/tutorials/send-token-ethersjs", - "/developers/tutorials/sending-transactions-using-web3-and-alchemy", - "/developers/tutorials/server-components", - "/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript", - "/developers/tutorials/short-abi", - "/developers/tutorials/smart-contract-security-guidelines", - "/developers/tutorials/testing-erc-20-tokens-with-waffle", - "/developers/tutorials/the-graph-fixing-web3-data-querying", - "/developers/tutorials/token-integration-checklist", - "/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract", - "/developers/tutorials/understand-the-erc-20-token-smart-contract", - "/developers/tutorials/uniswap-v2-annotated-code", - "/developers/tutorials/using-websockets", - "/developers/tutorials/waffle-dynamic-mocking-and-testing-calls", - "/developers/tutorials/waffle-say-hello-world-with-hardhat-and-ethers", - "/developers/tutorials/waffle-test-simple-smart-contract", - "/developers/tutorials/yellow-paper-evm", - "/developers/tutorials/creating-a-wagmi-ui-for-your-contract", - // Static (68/68) ✅ - "/about", - "/bridges", - "/community/code-of-conduct", - "/community/events", - "/community/get-involved", - "/community/grants", - "/community/language-resources", - "/community/online", - "/community/research", - "/community/support", - "/contributing", - "/contributing/adding-desci-projects", - "/contributing/adding-developer-tools", - "/contributing/adding-exchanges", - "/contributing/adding-glossary-terms", - "/contributing/adding-layer-2s", - "/contributing/adding-products", - "/contributing/adding-staking-products", - "/contributing/adding-wallets", - "/contributing/content-resources", - "/contributing/design", - "/contributing/design/adding-design-resources", - "/contributing/design-principles", - "/contributing/quizzes", - "/contributing/style-guide", - "/contributing/style-guide/content-standardization", - "/contributing/translation-program", - "/contributing/translation-program/content-buckets", - "/contributing/translation-program/faq", - "/contributing/translation-program/how-to-translate", - "/contributing/translation-program/mission-and-vision", - "/contributing/translation-program/playbook", - "/contributing/translation-program/resources", - "/contributing/translation-program/translatathon", - "/contributing/translation-program/translatathon/details", - "/contributing/translation-program/translatathon/translatathon-hubs", - "/contributing/translation-program/translatathon/terms-and-conditions", - "/contributing/translation-program/translators-guide", - "/cookie-policy", - "/eips", - "/energy-consumption", - "/enterprise", - "/enterprise/private-ethereum", - "/foundation", - "/glossary", - "/governance", - "/guides", - "/guides/how-to-create-an-ethereum-account", - "/guides/how-to-id-scam-tokens", - "/guides/how-to-revoke-token-access", - "/guides/how-to-swap-tokens", - "/guides/how-to-use-a-bridge", - "/guides/how-to-use-a-wallet", - "/history/", - "/privacy-policy", - "/roadmap/account-abstraction", - "/roadmap/danksharding", - "/roadmap/dencun", - "/roadmap/pectra", - "/roadmap/merge/issuance", - "/roadmap/pbs", - "/roadmap/secret-leader-election", - "/roadmap/single-slot-finality", - "/roadmap/statelessness", - "/roadmap/verkle-trees", - "/security", - "/smart-contracts", - "/staking/dvt", - - "/terms-of-use", - "/web3", - "/whitepaper", - "/wrapped-eth", - "/zero-knowledge-proofs", - ] + const contentRoot = getContentRoot() + const _dir = join(contentRoot, dir) // Get an array of all files and directories in the passed directory using `fs.readdirSync` - const fileList = fs.readdirSync(contentDir) + const dirContents = fs.readdirSync(_dir) // Create the full path of the file/directory by concatenating the passed directory and file/directory name - for (const file of fileList) { - const name = join(contentDir, file) + for (const fileOrDir of dirContents) { + // file = "about", "bridges".... "translations" (<-- skip that one)... + const path = join(_dir, fileOrDir) // Check if the current file/directory is a directory using fs.statSync - if (fs.statSync(name).isDirectory()) { + if (fs.statSync(path).isDirectory()) { + // Skip nested translations directory + if (fileOrDir === "translations") continue // If it is a directory, recursively call the `getPostSlugs` function with the // directory path and the files array - const nestedDir = join(dir, file) + const nestedDir = join(dir, fileOrDir) getPostSlugs(nestedDir, files) - } else { - const fileExtension = extname(name) + continue + } - if (fileExtension === ".md") { - // If it is a .md file (allowed content page), push the path to the files array - for (const page of temporalAllowedPages) { - const fullPagePath = join(currentDir, page) + // If the current file is not a markdown file, skip it + if (extname(path) !== ".md") continue - if (name.includes(fullPagePath)) { - files.push( - toPosixPath( - fullPagePath.replace(currentDir, "").replace("/index.md", "") - ) - ) - } - } - } - } + const sanitizedPath = toPosixPath( + path.replace(contentRoot, "").replace("/index.md", "") + ) + + files.push(sanitizedPath) } return files @@ -334,8 +70,8 @@ export const getContentBySlug = (slug: string) => { } } - const currentDir = getCurrentDir() - let fullPath = toPosixPath(join(currentDir, realSlug)) + const contentRoot = getContentRoot() + let fullPath = toPosixPath(join(contentRoot, realSlug)) let contentNotTranslated = false // If content is not translated, use english content fallback @@ -371,9 +107,9 @@ export const getContent = (dir: string) => { } export const getTutorialsData = (locale: string): ITutorial[] => { - const currentDir = getCurrentDir() + const contentRoot = getContentRoot() const fullPath = join( - currentDir, + contentRoot, locale !== "en" ? `translations/${locale!}` : "", "developers/tutorials" ) @@ -384,7 +120,7 @@ export const getTutorialsData = (locale: string): ITutorial[] => { tutorialData = languageTutorialFiles.map((dir) => { const filePath = join( - currentDir, + contentRoot, locale !== "en" ? `translations/${locale!}` : "", "developers/tutorials", dir, diff --git a/src/lib/utils/tutorial.ts b/src/lib/utils/tutorial.ts index 06303fd4ffa..c649e879561 100644 --- a/src/lib/utils/tutorial.ts +++ b/src/lib/utils/tutorial.ts @@ -2,7 +2,10 @@ import { Lang } from "@/lib/types" import { Skill } from "@/components/TutorialMetadata" -import { IExternalTutorial, ITutorial } from "@/pages/developers/tutorials" +import { + IExternalTutorial, + ITutorial, +} from "@/pages/[locale]/developers/tutorials" // Take all tutorials, and return a list of tutorials for a specific locale export const filterTutorialsByLang = ( diff --git a/src/lib/utils/url.ts b/src/lib/utils/url.ts index a9acae1eabe..2f332055bb3 100644 --- a/src/lib/utils/url.ts +++ b/src/lib/utils/url.ts @@ -1,4 +1,4 @@ -import { join } from "path" +import { extname, join } from "path" import { DEFAULT_LOCALE, @@ -21,6 +21,8 @@ export const isGlossary = (href: string): boolean => export const isPdf = (href: string): boolean => href.endsWith(".pdf") +export const isFile = (href: string): boolean => extname(href).length > 0 + export const sanitizeHitUrl = (url: string): string => url .replace(/^https?:\/\/[^/]+(?=\/)/, "") diff --git a/src/middleware.ts b/src/middleware.ts index 47b36dfe71c..8437cf57f9c 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,77 +1,10 @@ -import { NextRequest, NextResponse } from "next/server" +import createMiddleware from "next-intl/middleware" -import { DEFAULT_LOCALE, FAKE_LOCALE, LOCALES_CODES } from "./lib/constants" +import { routing } from "./i18n/routing" -const PUBLIC_FILE = /\.(.*)$/ - -function detectLocale(acceptLanguage: string | null) { - if (!acceptLanguage) { - return DEFAULT_LOCALE - } - - // it comes in the format of `en-US,en;q=0.9,de;q=0.8` - const locales = acceptLanguage.split(",") - - const locale = locales - .map((localeWeight) => localeWeight.split(";")[0].trim()) - .find((locale) => { - return LOCALES_CODES.includes(locale) - }) - - return locale -} +export default createMiddleware(routing) export const config = { - matcher: [ - "/", // explicit matcher for root route - /* - * Match all request paths except for the ones starting with: - * - _next/static (static files) - */ - "/((?!_next/static).*)", - ], -} - -const doubleLocaleRegex = new RegExp(`^/(${LOCALES_CODES.join("|")})/.*`, "i") - -// Middleware required to always display the locale prefix in the URL. It -// redirects to the default locale if the locale is not present in the URL -export async function middleware(req: NextRequest) { - const { pathname, locale, search } = req.nextUrl - - if ( - pathname.startsWith("/_next") || - pathname.includes("/api/") || - PUBLIC_FILE.test(pathname) - ) { - return - } - - /** - * If an URL has double langs in the URL it leads to 500 error, - * e.g.: /ja/en/eth/ - * - * It is a known bug: - * https://github.com/vercel/next.js/issues/52314 - * https://github.com/vercel/next.js/issues/52316 - */ - if (doubleLocaleRegex.test(pathname)) { - return NextResponse.redirect(new URL(`/${DEFAULT_LOCALE}/404`, req.url)) - } - - if (locale === FAKE_LOCALE) { - // Apparently, the built-in `localeDetection`from Next does not work when - // using the faked locale hack. So, we need to detect the locale manually - const localeDetected = detectLocale(req.headers.get("accept-language")) - const locale = localeDetected || DEFAULT_LOCALE - - const redirectUrl = new URL(`/${locale}${pathname}${search}`, req.url) - - // Add trailing slash if it's not present - if (!redirectUrl.pathname.endsWith("/")) { - redirectUrl.pathname = redirectUrl.pathname + "/" - } - - return NextResponse.redirect(redirectUrl, { status: 301 }) - } + // Skip all paths that should not be internationalized + matcher: ["/((?!api|_next|_vercel|.*\\..*).*)"], } diff --git a/src/pages/404.tsx b/src/pages/404.tsx index b233605ea76..8a90b43cf29 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -1,18 +1,24 @@ import type { GetStaticProps } from "next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" import { BasePageProps, Lang } from "@/lib/types" -import InlineLink from "@/components/Link" import MainArticle from "@/components/MainArticle" import Translation from "@/components/Translation" +import InlineLink from "@/components/ui/Link" import { existsNamespace } from "@/lib/utils/existsNamespace" import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" -export const getStaticProps = (async ({ locale }) => { +import { DEFAULT_LOCALE } from "@/lib/constants" + +import loadNamespaces from "@/i18n/loadNamespaces" + +export const getStaticProps = (async () => { + // TODO: generate 404 pages for each locale when we finish the app router migration + const locale = DEFAULT_LOCALE + const requiredNamespaces = getRequiredNamespacesForPage("/") // Want to check common namespace, so looking at requiredNamespaces[0] @@ -24,9 +30,11 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale!, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, diff --git a/src/pages/[...slug].tsx b/src/pages/[locale]/[...slug].tsx similarity index 92% rename from src/pages/[...slug].tsx rename to src/pages/[locale]/[...slug].tsx index a5e29f6f62f..eba8b57aa2e 100644 --- a/src/pages/[...slug].tsx +++ b/src/pages/[locale]/[...slug].tsx @@ -7,8 +7,6 @@ import type { GetStaticProps, InferGetStaticPropsType, } from "next/types" -import type { SSRConfig } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" import { MDXRemote, type MDXRemoteSerializeResult } from "next-mdx-remote" import { serialize } from "next-mdx-remote/serialize" import { getPlaiceholder } from "plaiceholder" @@ -34,11 +32,11 @@ import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" import { getContent, getContentBySlug } from "@/lib/utils/md" import { getLocaleTimestamp } from "@/lib/utils/time" import { remapTableOfContents } from "@/lib/utils/toc" -import { - filterRealLocales, - getRequiredNamespacesForPage, -} from "@/lib/utils/translations" +import { getRequiredNamespacesForPage } from "@/lib/utils/translations" + +import { LOCALES_CODES } from "@/lib/constants" +import loadNamespaces from "@/i18n/loadNamespaces" import { docsComponents, DocsLayout, @@ -64,6 +62,7 @@ import remarkInferToc from "@/lib/rehype/remarkInferToc" interface Params extends ParsedUrlQuery { slug: string[] + locale: string } export const layoutMapping = { @@ -88,17 +87,17 @@ const componentsMapping = { tutorial: tutorialsComponents, } as const -export const getStaticPaths = (({ locales }) => { +export const getStaticPaths = (() => { const contentFiles = getContent("/") // Generate page paths for each supported locale - const paths = filterRealLocales(locales).flatMap((locale) => + const paths = LOCALES_CODES.flatMap((locale) => contentFiles.map((file) => ({ params: { // Splitting nested paths to generate proper slug slug: file.slug.split("/").slice(1), + locale, }, - locale, })) ) @@ -108,11 +107,10 @@ export const getStaticPaths = (({ locales }) => { } }) satisfies GetStaticPaths -type Props = Omit[0], "children"> & - SSRConfig & { - mdxSource: MDXRemoteSerializeResult - gfissues: Awaited> - } +type Props = Omit[0], "children"> & { + mdxSource: MDXRemoteSerializeResult + gfissues: Awaited> +} const commitHistoryCache: CommitHistory = {} @@ -120,7 +118,7 @@ const loadData = dataLoader([["gfissues", fetchGFIs]]) export const getStaticProps = (async (context) => { const params = context.params! - const { locale } = context + const { locale } = params const markdown = getContentBySlug(`${locale}/${params.slug.join("/")}`) const frontmatter = markdown.frontmatter @@ -198,9 +196,11 @@ export const getStaticProps = (async (context) => { const [gfissues] = await loadData() + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, mdxSource, slug, frontmatter, diff --git a/src/pages/assets.tsx b/src/pages/[locale]/assets.tsx similarity index 96% rename from src/pages/assets.tsx rename to src/pages/[locale]/assets.tsx index f6e3b24d708..77c87985265 100644 --- a/src/pages/assets.tsx +++ b/src/pages/[locale]/assets.tsx @@ -1,13 +1,11 @@ import { HTMLAttributes } from "react" import type { GetStaticProps } from "next/types" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" -import type { BasePageProps, ChildOnlyProp, Lang } from "@/lib/types" +import type { BasePageProps, ChildOnlyProp, Lang, Params } from "@/lib/types" import AssetDownload from "@/components/AssetDownload" import FeedbackCard from "@/components/FeedbackCard" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import MainArticle from "@/components/MainArticle" import PageMetadata from "@/components/PageMetadata" import { Center, Flex } from "@/components/ui/flex" @@ -28,7 +26,11 @@ import { getLocaleTimestamp } from "@/lib/utils/time" // import leslieTheRhino from "@/public/images/upgrades/upgrade_rhino.png" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + import useColorModeValue from "@/hooks/useColorModeValue" +import { useTranslation } from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" import ethDiamondBlack from "@/public/images/assets/eth-diamond-black.png" import ethDiamondBlackGray from "@/public/images/assets/eth-diamond-black-gray.png" import ethDiamondBlackWhite from "@/public/images/assets/eth-diamond-black-white.jpg" @@ -96,7 +98,16 @@ const H3 = (props: ChildOnlyProp) => (

) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("assets") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -107,20 +118,21 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const AssetsPage = () => { // Ignore locale in the URL for SVG path in public directory to fix broken link // SVG path changes from /en/images => /images - const svgPathFromOrigin = - typeof window !== `undefined` ? window.location.origin : "" + const svgPathFromOrigin = "" const { t } = useTranslation("page-assets") const assetPageHeroImage = useColorModeValue( @@ -136,7 +148,7 @@ const AssetsPage = () => {
- { return b.score - a.score } -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("bug-bounty") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -240,17 +251,19 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const BugBountiesPage = () => { - const { pathname } = useRouter() + const pathname = usePathname() const { t } = useTranslation("page-bug-bounty") const consensusBountyHunters: Node[] = consensusData.sort(sortBountyHuntersFn) @@ -384,7 +397,7 @@ const BugBountiesPage = () => { description={t("page-upgrades-bug-bounty-meta-description")} /> {/* Uncomment for Bug Bounty Banner: */} - {/* */} + @@ -417,47 +430,47 @@ const BugBountiesPage = () => { {t("page-upgrades-bug-bounty-clients")} - + - + - + - + - + - - + - + - + - - + diff --git a/src/pages/community.tsx b/src/pages/[locale]/community.tsx similarity index 94% rename from src/pages/community.tsx rename to src/pages/[locale]/community.tsx index 4e345d0f1ad..cb40ef2a0e8 100644 --- a/src/pages/community.tsx +++ b/src/pages/[locale]/community.tsx @@ -1,9 +1,7 @@ import { BaseHTMLAttributes } from "react" import { GetStaticProps } from "next" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" -import { BasePageProps, ChildOnlyProp, Lang } from "@/lib/types" +import { BasePageProps, ChildOnlyProp, Lang, Params } from "@/lib/types" import { ICard, IGetInvolvedCard } from "@/lib/interfaces" import ActionCard from "@/components/ActionCard" @@ -12,7 +10,7 @@ import Card from "@/components/Card" import FeedbackCard from "@/components/FeedbackCard" import { HubHero } from "@/components/Hero" import type { HubHeroProps } from "@/components/Hero/HubHero" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import MainArticle from "@/components/MainArticle" import PageMetadata from "@/components/PageMetadata" import { ButtonLink, ButtonLinkProps } from "@/components/ui/buttons/Button" @@ -25,6 +23,10 @@ import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + +import { useTranslation } from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" // Static assets import developersEthBlockImg from "@/public/images/developers-eth-blocks.png" import dogeComputerImg from "@/public/images/doge-computer.png" @@ -38,7 +40,16 @@ import communityHeroImg from "@/public/images/heroes/community-hero.png" import upgradesCoreImg from "@/public/images/upgrades/core.png" import whatIsEthereumImg from "@/public/images/what-is-ethereum.png" -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("/community") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -49,14 +60,16 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const CardContainer = ({ children }: ChildOnlyProp) => { return {children} @@ -222,7 +235,7 @@ const CommunityPage = () => {

- { - {
- {
- ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const lastDeployDate = getLastDeployDate() const lastDeployLocaleTimestamp = getLocaleTimestamp( locale as Lang, @@ -67,17 +78,19 @@ export const getStaticProps = (async ({ locale }) => { const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const TranslatorAcknowledgements = () => { - const router = useRouter() + const pathname = usePathname() const { t } = useTranslation( "page-contributing-translation-program-acknowledgements" ) @@ -99,7 +112,7 @@ const TranslatorAcknowledgements = () => { /> - +

{t( "page-contributing-translation-program-acknowledgements-acknowledgement-page-title" @@ -141,7 +154,7 @@ const TranslatorAcknowledgements = () => {

{/* RIGHT COLUMN */}
- { {t("page-contributing-translation-program-acknowledgements-cert-3")} - + translator certificate diff --git a/src/pages/contributing/translation-program/contributors.tsx b/src/pages/[locale]/contributing/translation-program/contributors.tsx similarity index 82% rename from src/pages/contributing/translation-program/contributors.tsx rename to src/pages/[locale]/contributing/translation-program/contributors.tsx index 201102caeb6..aa33b7483b7 100644 --- a/src/pages/contributing/translation-program/contributors.tsx +++ b/src/pages/[locale]/contributing/translation-program/contributors.tsx @@ -1,10 +1,7 @@ import { BaseHTMLAttributes } from "react" -import { useRouter } from "next/router" import { GetStaticProps } from "next/types" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" -import { BasePageProps, CostLeaderboardData, Lang } from "@/lib/types" +import { BasePageProps, CostLeaderboardData, Lang, Params } from "@/lib/types" import Breadcrumbs from "@/components/Breadcrumbs" import FeedbackCard from "@/components/FeedbackCard" @@ -20,9 +17,24 @@ import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" -import allTimeData from "../../../data/translation-reports/alltime/alltime-data.json" +import allTimeData from "@/data/translation-reports/alltime/alltime-data.json" + +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + +import { useTranslation } from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" +import { usePathname } from "@/i18n/routing" + +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} -export const getStaticProps = (async ({ locale }) => { const lastDeployDate = getLastDeployDate() const lastDeployLocaleTimestamp = getLocaleTimestamp( locale as Lang, @@ -35,14 +47,16 @@ export const getStaticProps = (async ({ locale }) => { const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const Content = ({ ...props }: BaseHTMLAttributes) => ( @@ -59,7 +73,7 @@ const Contributors = () => { const { t } = useTranslation( "page-contributing-translation-program-contributors" ) - const router = useRouter() + const pathname = usePathname() const translators = (allTimeData as CostLeaderboardData[]) .map((item: CostLeaderboardData) => item.username) @@ -77,7 +91,7 @@ const Contributors = () => { /> - +

{t("page-contributing-translation-program-contributors-title")}

diff --git a/src/pages/dapps.tsx b/src/pages/[locale]/dapps.tsx similarity index 96% rename from src/pages/dapps.tsx rename to src/pages/[locale]/dapps.tsx index 1bd681a8dcd..64ab7270a6c 100644 --- a/src/pages/dapps.tsx +++ b/src/pages/[locale]/dapps.tsx @@ -8,10 +8,9 @@ import React, { } from "react" import { type GetStaticProps } from "next" import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" +import { useLocale } from "next-intl" -import type { BasePageProps, ChildOnlyProp, Lang } from "@/lib/types" +import type { BasePageProps, ChildOnlyProp, Lang, Params } from "@/lib/types" import BoxGrid from "@/components/BoxGrid" import Callout from "@/components/Callout" @@ -21,7 +20,7 @@ import DocLink from "@/components/DocLink" import Emoji from "@/components/Emoji" import FeedbackCard from "@/components/FeedbackCard" import GhostCard from "@/components/GhostCard" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import InfoBanner from "@/components/InfoBanner" import MainArticle from "@/components/MainArticle" import PageHero from "@/components/PageHero" @@ -44,6 +43,10 @@ import { trackCustomEvent } from "@/lib/utils/matomo" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + +import { useTranslation } from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" import aave from "@/public/images/dapps/aave.png" import ankr from "@/public/images/dapps/ankr.png" import api3 from "@/public/images/dapps/api3.png" @@ -126,38 +129,6 @@ const Content = (props: ChildOnlyProp) => (
) -const OptionContainer = (props: ChildOnlyProp) => ( - -) - -const Option = ( - props: Pick & { isActive: boolean } -) => { - return ( - ) })} - +
{/* Category-specific content */} {selectedCategory === CategoryType.FINANCE && ( @@ -1753,7 +1748,7 @@ const DappsPage = () => { - (
- - {title} +

{title}

{linkLabel}
) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("/developers") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -137,14 +147,16 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale!, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps interface IDevelopersPath { emoji: string @@ -330,7 +342,7 @@ const DevelopersPage = () => { - ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage( "/developers/learning-tools" ) @@ -130,14 +141,16 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale!, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const LearningToolsPage = () => { const { t } = useTranslation(["page-developers-learning-tools"]) @@ -480,9 +493,7 @@ const LearningToolsPage = () => { { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage( "/developers/local-environment" ) @@ -65,15 +75,17 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale!, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, frameworksList: frameworksListData, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const LocalEnvironmentPage = ({ frameworksList, @@ -87,20 +99,9 @@ const LocalEnvironmentPage = ({ description={t("page-local-environment-setup-meta-desc")} />
- +

- +


@@ -110,14 +111,9 @@ const LocalEnvironmentPage = ({ - +

- +

@@ -143,7 +139,7 @@ const LocalEnvironmentPage = ({
- { ) } -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage( "/developers/tutorials" ) @@ -96,15 +106,17 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale!, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, internalTutorials: getTutorialsData(locale!), lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps export interface IExternalTutorial { url: string @@ -147,7 +159,7 @@ const TutorialPage = ({ internalTutorials, contentNotTranslated, }: InferGetServerSidePropsType) => { - const { locale } = useRouter() + const locale = useLocale() const filteredTutorialsByLang = useMemo( () => filterTutorialsByLang( @@ -218,21 +230,9 @@ const TutorialPage = ({ "page-developers-tutorials:page-tutorials-meta-description" )} /> - +

- +

diff --git a/src/pages/eth.tsx b/src/pages/[locale]/eth.tsx similarity index 95% rename from src/pages/eth.tsx rename to src/pages/[locale]/eth.tsx index 7a132a61422..1a68b49db57 100644 --- a/src/pages/eth.tsx +++ b/src/pages/[locale]/eth.tsx @@ -1,9 +1,7 @@ import { GetStaticProps } from "next" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" import type { ComponentProps, HTMLAttributes } from "react" -import type { BasePageProps, ChildOnlyProp, Lang } from "@/lib/types" +import type { BasePageProps, ChildOnlyProp, Lang, Params } from "@/lib/types" import ActionCard from "@/components/ActionCard" import CalloutBanner from "@/components/CalloutBanner" @@ -13,7 +11,7 @@ import EthPriceCard from "@/components/EthPriceCard" import EthVideo from "@/components/EthVideo" import FeedbackCard from "@/components/FeedbackCard" import HorizontalCard from "@/components/HorizontalCard" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import InfoBanner from "@/components/InfoBanner" import MainArticle from "@/components/MainArticle" import PageMetadata from "@/components/PageMetadata" @@ -31,6 +29,10 @@ import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + +import { useTranslation } from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" import eth from "@/public/images/eth.png" import ethCat from "@/public/images/eth-gif-cat.png" import defi from "@/public/images/finance_transparent.png" @@ -171,7 +173,16 @@ const CentralActionCard = (props: ComponentProps) => ( ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("/eth") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -182,14 +193,16 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const EthPage = () => { const { t } = useTranslation("page-eth") @@ -306,7 +319,7 @@ const EthPage = () => { - ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("/gas") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -95,14 +106,16 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const GasPage = () => { const { t } = useTranslation("page-gas") @@ -184,7 +197,7 @@ const GasPage = () => {
- + A robot
@@ -276,12 +289,7 @@ const GasPage = () => { ))}
- +
diff --git a/src/pages/get-eth.tsx b/src/pages/[locale]/get-eth.tsx similarity index 95% rename from src/pages/get-eth.tsx rename to src/pages/[locale]/get-eth.tsx index 547c621bc24..14f64b997e0 100644 --- a/src/pages/get-eth.tsx +++ b/src/pages/[locale]/get-eth.tsx @@ -1,9 +1,7 @@ import type { GetStaticProps, InferGetStaticPropsType } from "next/types" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" import type { ReactNode } from "react" -import type { BasePageProps, ChildOnlyProp, Lang } from "@/lib/types" +import type { BasePageProps, ChildOnlyProp, Lang, Params } from "@/lib/types" import CalloutBanner from "@/components/CalloutBanner" import CardList, { @@ -13,7 +11,7 @@ import CentralizedExchanges from "@/components/CentralizedExchanges" import Emoji from "@/components/Emoji" import EthPriceCard from "@/components/EthPriceCard" import FeedbackCard from "@/components/FeedbackCard" -import { TwImage as Image } from "@/components/Image" +import { Image } from "@/components/Image" import MainArticle from "@/components/MainArticle" import PageMetadata from "@/components/PageMetadata" import Translation from "@/components/Translation" @@ -38,7 +36,11 @@ import { trackCustomEvent } from "@/lib/utils/matomo" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + import { useBreakpointValue } from "@/hooks/useBreakpointValue" +import { useTranslation } from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" import uniswap from "@/public/images/dapps/uni.png" import dapps from "@/public/images/doge-computer.png" import bancor from "@/public/images/exchanges/bancor.png" @@ -74,7 +76,16 @@ type Props = BasePageProps & { lastDataUpdateDate: string } -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("get-eth") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -89,15 +100,17 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, lastDataUpdateDate, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const GetEthPage = ({ lastDataUpdateDate, diff --git a/src/pages/index.tsx b/src/pages/[locale]/index.tsx similarity index 97% rename from src/pages/index.tsx rename to src/pages/[locale]/index.tsx index 5a8b56b639e..0b7b9523b1e 100644 --- a/src/pages/index.tsx +++ b/src/pages/[locale]/index.tsx @@ -1,6 +1,5 @@ import { Fragment, lazy, Suspense } from "react" import type { GetStaticProps, InferGetStaticPropsType } from "next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" import { FaDiscord, FaGithub } from "react-icons/fa6" import { IoMdCopy } from "react-icons/io" import { MdCheck } from "react-icons/md" @@ -10,12 +9,10 @@ import type { BasePageProps, CommunityBlog, Lang, + Params, RSSItem, } from "@/lib/types" -import SvgButtonLink, { - type SvgButtonLinkProps, -} from "@/components/Buttons/SvgButtonLink" import { ChevronNext } from "@/components/Chevron" import CodeModal from "@/components/CodeModal" import HomeHero from "@/components/Hero/HomeHero" @@ -25,11 +22,14 @@ import ValuesMarquee from "@/components/Homepage/ValuesMarquee" import AngleBrackets from "@/components/icons/angle-brackets.svg" import Calendar from "@/components/icons/calendar.svg" import CalendarAdd from "@/components/icons/calendar-add.svg" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import MainArticle from "@/components/MainArticle" import PageMetadata from "@/components/PageMetadata" import { TranslatathonBanner } from "@/components/Translatathon/TranslatathonBanner" import { Button, ButtonLink } from "@/components/ui/buttons/Button" +import SvgButtonLink, { + type SvgButtonLinkProps, +} from "@/components/ui/buttons/SvgButtonLink" import { Card, CardBanner, @@ -71,7 +71,9 @@ import { BLOG_FEEDS, BLOGS_WITHOUT_FEED, CALENDAR_DISPLAY_COUNT, + DEFAULT_LOCALE, GITHUB_REPO_URL, + LOCALES_CODES, RSS_DISPLAY_COUNT, } from "@/lib/constants" @@ -80,9 +82,10 @@ import { AccordionContent, AccordionItem, AccordionTrigger, -} from "../components/ui/accordion" +} from "../../components/ui/accordion" import { useClipboard } from "@/hooks/useClipboard" +import loadNamespaces from "@/i18n/loadNamespaces" import { fetchCommunityEvents } from "@/lib/api/calendarEvents" import { fetchEthPrice } from "@/lib/api/fetchEthPrice" import { fetchGrowThePie } from "@/lib/api/fetchGrowThePie" @@ -134,7 +137,16 @@ const loadData = dataLoader( REVALIDATE_TIME * 1000 ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const [ ethPrice, totalEthStaked, @@ -184,9 +196,11 @@ export const getStaticProps = (async ({ locale }) => { })) as CommunityBlog[] blogLinks.push(...BLOGS_WITHOUT_FEED) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, calendar, contentNotTranslated, lastDeployLocaleTimestamp, @@ -194,7 +208,7 @@ export const getStaticProps = (async ({ locale }) => { rssData: { rssItems, blogLinks }, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const HomePage = ({ calendar, @@ -335,7 +349,7 @@ const HomePage = ({ {/* Activity - The strongest ecosystem */}
- + @@ -361,7 +375,7 @@ const HomePage = ({ className="md:flex-row-reverse" > - + @@ -429,7 +443,7 @@ const HomePage = ({ {/* Builders - Blockchain's biggest builder community */}
- + @@ -479,7 +493,7 @@ const HomePage = ({
- {/* Top logo */}
- {/* Bottom right logo */}
- {/* Bottom left logo */}
- {/* Top logo */}
- {/* Bottom right logo */}
- {/* Bottom left logo */}
- {/* Top logo */}
- {/* Bottom right logo */}
- {/* Bottom left logo */}
- - + Ethereum
@@ -390,7 +423,7 @@ const Layer2Hub = ({
- {randomL2s.slice(0, 3).map((l2, idx) => { + {userRandomL2s.map((l2, idx) => { return (
-
-
- + Walking

Why do we need multiple networks on Ethereum?

diff --git a/src/pages/layer-2/learn.tsx b/src/pages/[locale]/layer-2/learn.tsx similarity index 93% rename from src/pages/layer-2/learn.tsx rename to src/pages/[locale]/layer-2/learn.tsx index 01b1bc5adaf..68bc29e94b2 100644 --- a/src/pages/layer-2/learn.tsx +++ b/src/pages/[locale]/layer-2/learn.tsx @@ -1,14 +1,11 @@ import { GetStaticProps } from "next" -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" -import type { BasePageProps, Lang } from "@/lib/types" +import type { BasePageProps, Lang, Params } from "@/lib/types" import Callout from "@/components/Callout" import Card from "@/components/Card" import { ContentHero, type ContentHeroProps } from "@/components/Hero" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import MainArticle from "@/components/MainArticle" import PageMetadata from "@/components/PageMetadata" import { StandaloneQuizWidget } from "@/components/Quiz/QuizWidget" @@ -20,6 +17,11 @@ import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + +import useTranslation from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" +import { usePathname } from "@/i18n/routing" import Callout2Image from "@/public/images/layer-2/learn-hero.png" import OptimisticRollupImage from "@/public/images/layer-2/optimistic_rollup.png" import RollupImage from "@/public/images/layer-2/rollup-2.png" @@ -28,7 +30,16 @@ import Callout1Image from "@/public/images/man-and-dog-playing.png" import DAOImage from "@/public/images/use-cases/dao-2.png" import WhatIsEthereumImage from "@/public/images/what-is-ethereum.png" -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const lastDeployDate = getLastDeployDate() const lastDeployLocaleTimestamp = getLocaleTimestamp( locale as Lang, @@ -39,18 +50,20 @@ export const getStaticProps = (async ({ locale }) => { const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const Layer2Learn = () => { const { t } = useTranslation("page-layer-2-learn") - const { pathname } = useRouter() + const pathname = usePathname() const heroProps: ContentHeroProps = { breadcrumbs: { slug: pathname, startDepth: 1 }, @@ -141,7 +154,7 @@ const Layer2Learn = () => {

- { className="flex w-full flex-col gap-16 px-8 py-9 md:flex-row" >
- +
@@ -247,7 +260,7 @@ const Layer2Learn = () => {

{t("page-layer-2-learn-how-does-layer-2-work-rollups-2")}

- + {""}
@@ -261,7 +274,7 @@ const Layer2Learn = () => { key={idx} className="flex w-full flex-col gap-4 rounded-sm border border-solid border-body-light bg-background-highlight p-6 md:w-[50%]" > - + {""}

{card.title}

{card.description}

{card.childSentence} diff --git a/src/pages/layer-2/networks.tsx b/src/pages/[locale]/layer-2/networks.tsx similarity index 91% rename from src/pages/layer-2/networks.tsx rename to src/pages/[locale]/layer-2/networks.tsx index 86da260d5da..5785f299309 100644 --- a/src/pages/layer-2/networks.tsx +++ b/src/pages/[locale]/layer-2/networks.tsx @@ -1,13 +1,12 @@ -import { useRouter } from "next/router" import type { GetStaticProps } from "next/types" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" -import type { BasePageProps, Lang } from "@/lib/types" +import type { BasePageProps, Lang, Params } from "@/lib/types" import Callout from "@/components/Callout" import { ContentHero, ContentHeroProps } from "@/components/Hero" import Layer2NetworksTable from "@/components/Layer2NetworksTable" import MainArticle from "@/components/MainArticle" +import NetworkMaturity from "@/components/NetworkMaturity" import PageMetadata from "@/components/PageMetadata" import { ButtonLink } from "@/components/ui/buttons/Button" @@ -21,8 +20,10 @@ import { getRequiredNamespacesForPage } from "@/lib/utils/translations" import { ethereumNetworkData, layer2Data } from "@/data/networks/networks" import { walletsData } from "@/data/wallets/wallet-data" -import { BASE_TIME_UNIT } from "@/lib/constants" +import { BASE_TIME_UNIT, DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" +import loadNamespaces from "@/i18n/loadNamespaces" +import { usePathname } from "@/i18n/routing" import { fetchEthereumMarketcap } from "@/lib/api/fetchEthereumMarketcap" import { fetchGrowThePie } from "@/lib/api/fetchGrowThePie" import { fetchGrowThePieBlockspace } from "@/lib/api/fetchGrowThePieBlockspace" @@ -45,7 +46,16 @@ const loadData = dataLoader( REVALIDATE_TIME * 1000 ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const [ ethereumMarketcapData, growThePieData, @@ -110,9 +120,11 @@ export const getStaticProps = (async ({ locale }) => { return maturityDiff }) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, locale, @@ -129,10 +141,10 @@ export const getStaticProps = (async ({ locale }) => { }, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const Layer2Networks = ({ layer2Data, locale, mainnetData }) => { - const { pathname } = useRouter() + const pathname = usePathname() const heroProps: ContentHeroProps = { breadcrumbs: { slug: pathname, startDepth: 1 }, @@ -183,6 +195,8 @@ const Layer2Networks = ({ layer2Data, locale, mainnetData }) => {
+ +
) => ( ) const ImageHeight200 = ({ src, alt }: ImageProps) => ( - + {alt} ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("/learn") - const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) + const contentNotTranslated = !existsNamespace(locale, requiredNamespaces[2]) const lastDeployDate = getLastDeployDate() const lastDeployLocaleTimestamp = getLocaleTimestamp( @@ -128,14 +145,16 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const LearnPage = () => { const { t } = useTranslation("page-learn") @@ -348,7 +367,7 @@ const LearnPage = () => {
- +
diff --git a/src/pages/quizzes.tsx b/src/pages/[locale]/quizzes.tsx similarity index 71% rename from src/pages/quizzes.tsx rename to src/pages/[locale]/quizzes.tsx index 5e690b30fb5..fbf90bfcdaa 100644 --- a/src/pages/quizzes.tsx +++ b/src/pages/[locale]/quizzes.tsx @@ -1,13 +1,9 @@ import { useMemo, useState } from "react" import { GetStaticProps, InferGetStaticPropsType, NextPage } from "next" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" import { FaGithub } from "react-icons/fa" -import { Box, Flex, Icon, Stack, Text } from "@chakra-ui/react" -import { BasePageProps, Lang, QuizKey, QuizStatus } from "@/lib/types" +import { BasePageProps, Lang, Params, QuizKey, QuizStatus } from "@/lib/types" -import { ButtonLink } from "@/components/Buttons" import FeedbackCard from "@/components/FeedbackCard" import { HubHero } from "@/components/Hero" import MainArticle from "@/components/MainArticle" @@ -17,6 +13,8 @@ import QuizzesList from "@/components/Quiz/QuizzesList" import QuizzesModal from "@/components/Quiz/QuizzesModal" import QuizzesStats from "@/components/Quiz/QuizzesStats" import { useLocalQuizData } from "@/components/Quiz/useLocalQuizData" +import { ButtonLink } from "@/components/ui/buttons/Button" +import { Flex, HStack, Stack } from "@/components/ui/flex" import { existsNamespace } from "@/lib/utils/existsNamespace" import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" @@ -26,9 +24,11 @@ import { getRequiredNamespacesForPage } from "@/lib/utils/translations" import { ethereumBasicsQuizzes, usingEthereumQuizzes } from "@/data/quizzes" -import { INITIAL_QUIZ } from "@/lib/constants" +import { DEFAULT_LOCALE, INITIAL_QUIZ, LOCALES_CODES } from "@/lib/constants" import { useDisclosure } from "@/hooks/useDisclosure" +import { useTranslation } from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" import HeroImage from "@/public/images/heroes/quizzes-hub-hero.png" const handleGHAdd = () => @@ -38,7 +38,16 @@ const handleGHAdd = () => eventName: "GH_add", }) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("/quizzes") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -49,14 +58,16 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const QuizzesHubPage: NextPage< InferGetStaticPropsType @@ -78,7 +89,7 @@ const QuizzesHubPage: NextPage< ) return ( - + - - - - +
+ + +
- - - - - {t("want-more-quizzes")} - - - - {t("contribute")} - - +
+ +
+

{t("want-more-quizzes")}

+ +

{t("contribute")}

+
- - + + {t("add-quiz")} - +
- +
- +
- - +
+
- - +
+
) } diff --git a/src/pages/roadmap/vision.tsx b/src/pages/[locale]/roadmap/vision.tsx similarity index 76% rename from src/pages/roadmap/vision.tsx rename to src/pages/[locale]/roadmap/vision.tsx index 84af95eaf85..b01cae17597 100644 --- a/src/pages/roadmap/vision.tsx +++ b/src/pages/[locale]/roadmap/vision.tsx @@ -1,90 +1,93 @@ import { GetStaticProps } from "next" -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" -import type { ComponentPropsWithRef } from "react" -import { - Box, - Flex, - type FlexProps, - Heading, - type HeadingProps, - List, - ListItem, - useToken, -} from "@chakra-ui/react" +import type { + ComponentProps, + ComponentPropsWithRef, + CSSProperties, +} from "react" -import type { BasePageProps, ChildOnlyProp, Lang } from "@/lib/types" +import type { BasePageProps, ChildOnlyProp, Lang, Params } from "@/lib/types" import Breadcrumbs from "@/components/Breadcrumbs" -import ButtonLink from "@/components/Buttons/ButtonLink" import Card from "@/components/Card" import Emoji from "@/components/Emoji" import FeedbackCard from "@/components/FeedbackCard" import InfoBanner from "@/components/InfoBanner" -import InlineLink from "@/components/Link" import MainArticle from "@/components/MainArticle" -import OldHeading from "@/components/OldHeading" -import Text from "@/components/OldText" import PageHero, { type ContentType as PageHeroContent, } from "@/components/PageHero" import PageMetadata from "@/components/PageMetadata" import Trilemma from "@/components/Trilemma" +import { ButtonLink } from "@/components/ui/buttons/Button" import { Divider } from "@/components/ui/divider" +import { Flex, type FlexProps, VStack } from "@/components/ui/flex" +import InlineLink from "@/components/ui/Link" +import { List, ListItem } from "@/components/ui/list" +import { cn } from "@/lib/utils/cn" import { existsNamespace } from "@/lib/utils/existsNamespace" import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" +import { screens } from "@/lib/utils/screen" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + +import useTranslation from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" +import { usePathname } from "@/i18n/routing" import oldship from "@/public/images/upgrades/oldship.png" +/** + * TODO: Consider replacing this with a global style for the `p` element + */ +const Text = (props: Omit, "className">) => ( +

+) + const Page = (props: ChildOnlyProp) => ( - + + + ) const PageContent = (props: ChildOnlyProp) => ( - + ) -const H2 = (props: HeadingProps) => ( - ) => ( +

) -const CenterH2 = (props: HeadingProps) =>

+const CenterH2 = (props: Omit, "className">) => ( +

+) -const H3 = (props: HeadingProps) => ( - , "className">) => ( +

) -const CardContainer = (props: FlexProps) => ( - +const CardContainer = ({ className, ...props }: FlexProps) => ( + ) const ProblemCardContainer = (props: ChildOnlyProp) => { - const containerMaxWidth = useToken("breakpoints", ["lg"]) - - return + return ( + + ) } const CentreCard = (props: ComponentPropsWithRef) => ( @@ -95,14 +98,26 @@ const CentreCard = (props: ComponentPropsWithRef) => ( ) const CentralContent = (props: ChildOnlyProp) => ( - +
) const TrilemmaContent = (props: ChildOnlyProp) => ( - +
) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("/roadmap/vision") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -113,18 +128,20 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const VisionPage = () => { const { t } = useTranslation(["page-roadmap-vision", "page-upgrades-index"]) - const { pathname } = useRouter() + const pathname = usePathname() const paths = [ { @@ -162,7 +179,7 @@ const VisionPage = () => { {t("page-roadmap-vision-upgrade-needs-desc")} {t("page-roadmap-vision-upgrade-needs-desc-2")} {t("page-roadmap-vision-upgrade-needs-desc-3")} - + {t("page-roadmap-vision-2022")} diff --git a/src/pages/run-a-node.tsx b/src/pages/[locale]/run-a-node.tsx similarity index 97% rename from src/pages/run-a-node.tsx rename to src/pages/[locale]/run-a-node.tsx index efa18aebd8c..d375ef613bc 100644 --- a/src/pages/run-a-node.tsx +++ b/src/pages/[locale]/run-a-node.tsx @@ -1,11 +1,9 @@ import { HTMLAttributes } from "react" import type { GetStaticProps } from "next/types" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" import type { ReactNode } from "react" import { FaDiscord } from "react-icons/fa" -import type { BasePageProps, ChildOnlyProp, Lang } from "@/lib/types" +import type { BasePageProps, ChildOnlyProp, Lang, Params } from "@/lib/types" import Emoji from "@/components/Emoji" import ExpandableCard from "@/components/ExpandableCard" @@ -21,7 +19,7 @@ import { SovereigntyGlyphIcon, VoteGlyphIcon, } from "@/components/icons/run-a-node" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import MainArticle from "@/components/MainArticle" import PageHero from "@/components/PageHero" import PageMetadata from "@/components/PageMetadata" @@ -38,6 +36,10 @@ import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + +import { useTranslation } from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" import { InfoGrid } from "@/layouts/md/Staking" import community from "@/public/images/enterprise-eth.png" import hackathon from "@/public/images/hackathon_transparent.png" @@ -209,7 +211,16 @@ type RunANodeCard = { alt: string } -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage("/run-a-node") const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) @@ -220,14 +231,16 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const RunANodePage = () => { const { t } = useTranslation("page-run-a-node") @@ -343,7 +356,7 @@ const RunANodePage = () => { {t("page-run-a-node-what-3-text")} - { )} > - { - { - ( REVALIDATE_TIME * 1000 ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const lastDeployDate = getLastDeployDate() const lastDeployLocaleTimestamp = getLocaleTimestamp( locale as Lang, @@ -174,16 +183,18 @@ export const getStaticProps = (async ({ locale }) => { marketsHasError = true } + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, markets, marketsHasError, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const Content = (props: BaseHTMLAttributes) => (
@@ -498,7 +509,7 @@ const StablecoinsPage = ({ markets, marketsHasError }) => {
- {
- ( ) const CardTitle = (props: ChildOnlyProp) => ( - +

) const Caption = (props: ChildOnlyProp) => ( @@ -142,7 +137,7 @@ const Caption = (props: ChildOnlyProp) => ( ) const Blockie = (props: { src: string }) => ( - { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const requiredNamespaces = getRequiredNamespacesForPage( "/staking/deposit-contract" ) @@ -176,17 +180,19 @@ export const getStaticProps = (async ({ locale }) => { lastDeployDate ) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const DepositContractPage = () => { - const { asPath } = useRouter() + const pathname = usePathname() const { t } = useTranslation("page-staking-deposit-contract") @@ -303,7 +309,7 @@ const DepositContractPage = () => { description={t("page-staking-deposit-contract-meta-desc")} /> - + {t("page-staking-deposit-contract-title")} {t("page-staking-deposit-contract-subtitle")}

{t("page-staking-deposit-contract-h2")}

diff --git a/src/pages/staking/index.tsx b/src/pages/[locale]/staking/index.tsx similarity index 97% rename from src/pages/staking/index.tsx rename to src/pages/[locale]/staking/index.tsx index 56febfc38c1..d54b0d2439a 100644 --- a/src/pages/staking/index.tsx +++ b/src/pages/[locale]/staking/index.tsx @@ -1,7 +1,5 @@ import { type HTMLAttributes, ReactNode } from "react" import { GetStaticProps, InferGetStaticPropsType } from "next" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" import type { BasePageProps, @@ -9,6 +7,7 @@ import type { EpochResponse, EthStoreResponse, Lang, + Params, StakingStatsData, } from "@/lib/types" @@ -41,8 +40,10 @@ import { getLastDeployDate } from "@/lib/utils/getLastDeployDate" import { getLocaleTimestamp } from "@/lib/utils/time" import { getRequiredNamespacesForPage } from "@/lib/utils/translations" -import { BASE_TIME_UNIT } from "@/lib/constants" +import { BASE_TIME_UNIT, DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" +import useTranslation from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" import rhino from "@/public/images/upgrades/upgrade_rhino.png" type BenefitsType = { @@ -156,7 +157,16 @@ const loadData = dataLoader( REVALIDATE_TIME * 1000 ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const lastDeployDate = getLastDeployDate() const lastDeployLocaleTimestamp = getLocaleTimestamp( locale as Lang, @@ -169,15 +179,17 @@ export const getStaticProps = (async ({ locale }) => { const [data] = await loadData() + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, data, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const StakingPage = ({ data, diff --git a/src/pages/wallets/find-wallet.tsx b/src/pages/[locale]/wallets/find-wallet.tsx similarity index 82% rename from src/pages/wallets/find-wallet.tsx rename to src/pages/[locale]/wallets/find-wallet.tsx index 771d730db3d..622b8ccc09d 100644 --- a/src/pages/wallets/find-wallet.tsx +++ b/src/pages/[locale]/wallets/find-wallet.tsx @@ -1,14 +1,17 @@ import { GetStaticProps, InferGetStaticPropsType } from "next" -import { useRouter } from "next/router" -import { useTranslation } from "next-i18next" -import { serverSideTranslations } from "next-i18next/serverSideTranslations" -import type { BasePageProps, ChildOnlyProp, Lang, Wallet } from "@/lib/types" +import type { + BasePageProps, + ChildOnlyProp, + Lang, + Params, + Wallet, +} from "@/lib/types" import BannerNotification from "@/components/Banners/BannerNotification" import Breadcrumbs from "@/components/Breadcrumbs" import FindWalletProductTable from "@/components/FindWalletProductTable" -import { TwImage } from "@/components/Image" +import { Image } from "@/components/Image" import MainArticle from "@/components/MainArticle" import PageMetadata from "@/components/PageMetadata" import InlineLink from "@/components/ui/Link" @@ -24,6 +27,11 @@ import { getSupportedLocaleWallets, } from "@/lib/utils/wallets" +import { DEFAULT_LOCALE, LOCALES_CODES } from "@/lib/constants" + +import { useTranslation } from "@/hooks/useTranslation" +import loadNamespaces from "@/i18n/loadNamespaces" +import { usePathname } from "@/i18n/routing" import HeroImage from "@/public/images/wallets/wallet-hero.png" const Subtitle = ({ children }: ChildOnlyProp) => ( @@ -36,7 +44,16 @@ type Props = BasePageProps & { wallets: Wallet[] } -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const lastDeployDate = getLastDeployDate() const lastDeployLocaleTimestamp = getLocaleTimestamp( locale as Lang, @@ -61,20 +78,22 @@ export const getStaticProps = (async ({ locale }) => { ), })) + const messages = await loadNamespaces(locale!, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, wallets, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const FindWalletPage = ({ wallets, }: InferGetStaticPropsType) => { - const { pathname } = useRouter() + const pathname = usePathname() const { t } = useTranslation("page-wallets-find-wallet") return ( @@ -109,7 +128,7 @@ const FindWalletPage = ({

- ) => ( /> ) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const lastDeployDate = getLastDeployDate() const lastDeployLocaleTimestamp = getLocaleTimestamp( locale as Lang, @@ -52,17 +63,19 @@ export const getStaticProps = (async ({ locale }) => { const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) + const messages = await loadNamespaces(locale!, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const WalletsPage = () => { - const { locale } = useRouter() + const locale = useLocale() const { t } = useTranslation("page-wallets") const heroContent = { @@ -331,7 +344,7 @@ const WalletsPage = () => { > {t("page-wallets-find-wallet-btn")} - ( ) const Image400 = ({ src }: Pick) => ( - + ) type Props = BasePageProps & { @@ -178,7 +181,16 @@ type Props = BasePageProps & { const loadData = dataLoader([["growThePieData", fetchGrowThePie]]) -export const getStaticProps = (async ({ locale }) => { +export async function getStaticPaths() { + return { + paths: LOCALES_CODES.map((locale) => ({ params: { locale } })), + fallback: false, + } +} + +export const getStaticProps = (async ({ params }) => { + const { locale = DEFAULT_LOCALE } = params || {} + const [data] = await loadData() const lastDeployDate = getLastDeployDate() @@ -191,22 +203,24 @@ export const getStaticProps = (async ({ locale }) => { const contentNotTranslated = !existsNamespace(locale!, requiredNamespaces[2]) + const messages = await loadNamespaces(locale, requiredNamespaces) + return { props: { - ...(await serverSideTranslations(locale!, requiredNamespaces)), + messages, contentNotTranslated, lastDeployLocaleTimestamp, data: data.txCount, }, } -}) satisfies GetStaticProps +}) satisfies GetStaticProps const WhatIsEthereumPage = ({ data, }: InferGetStaticPropsType) => { const { t } = useTranslation(["page-what-is-ethereum", "learn-quizzes"]) - const { locale } = useRouter() + const locale = useLocale() const localeForNumberFormat = getLocaleForNumberFormat(locale! as Lang) const formatNumber = ( @@ -331,7 +345,7 @@ const WhatIsEthereumPage = ({ - { + const router = useRouter() + useEffect(() => { if (!process.env.IS_PREVIEW_DEPLOY) { init({ @@ -26,18 +31,31 @@ const App = ({ Component, pageProps }: AppPropsWithLayout) => { const getLayout = Component.getLayout ?? ((page) => page) return ( - - - - {getLayout()} - - - + { + // Suppress errors by default, enable if needed to debug + // console.error(error) + }} + getMessageFallback={({ key }) => { + const keyOnly = key.split(".").pop() + return keyOnly || key + }} + > + + + + {getLayout()} + + + + ) } -export default appWithTranslation(App) +export default App diff --git a/src/pages/api/revalidate.ts b/src/pages/api/revalidate.ts index 1d1451dfd6a..d7d39309a00 100644 --- a/src/pages/api/revalidate.ts +++ b/src/pages/api/revalidate.ts @@ -10,7 +10,7 @@ export default async function handler( return res.status(401).json({ message: "Invalid secret" }) } - const BUILD_LOCALES = process.env.BUILD_LOCALES + const BUILD_LOCALES = process.env.NEXT_PUBLIC_BUILD_LOCALES // Supported locales defined in `i18n.config.json` const locales = BUILD_LOCALES ? BUILD_LOCALES.split(",") diff --git a/src/scripts/crowdin-import.ts b/src/scripts/crowdin-import.ts index fa8f7dbc70b..4e4914a5005 100644 --- a/src/scripts/crowdin-import.ts +++ b/src/scripts/crowdin-import.ts @@ -407,7 +407,7 @@ const langsSummary: string = summary.reduce( log("Empty buckets:", trackers.emptyBuckets) if (summary.length) { console.table(summary) - console.log("Langs to test:", `\nBUILD_LOCALES=en${langsSummary}`) + console.log("Langs to test:", `\nNEXT_PUBLIC_BUILD_LOCALES=en${langsSummary}`) console.log("🎉 Crowdin import complete.") } else { console.warn("Nothing imported, see instruction at top of crowdin-imports.ts") diff --git a/src/styled.d.ts b/src/styled.d.ts deleted file mode 100644 index 53b790d4761..00000000000 --- a/src/styled.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -// import original module declarations -import "@emotion/react" - -// and extend them! -declare module "@emotion/react" { - export interface Theme { - // TODO: to be defined better when we implement a UI lib - isDark: boolean - colors: unknown - fonts: { - monospace: string - } - fontSizes: { - xs: string - s: string - m: string - r: string - l: string - xl: string - } - breakpoints: { - xs: string - s: string - m: string - l: string - xl: string - } - variables: { - maxPageWidth: string - navHeight: string - navBannerHeightDesktop: string - navBannerHeightTablet: string - navBannerHeightMobile: string - navSubNavHeightDesktop: string - navSideNavHeightMobile: string - } - } -} diff --git a/src/styles/colors.stories.tsx b/src/styles/colors.stories.tsx new file mode 100644 index 00000000000..4af728227c7 --- /dev/null +++ b/src/styles/colors.stories.tsx @@ -0,0 +1,149 @@ +import { type ReactNode } from "react" +import capitalize from "lodash/capitalize" +import type { Meta, StoryObj } from "@storybook/react" + +import { HStack, Stack, VStack } from "@/components/ui/flex" + +import { cn } from "@/lib/utils/cn" + +const meta = { + title: "Design System / Colors", + parameters: { + // Do not create snapshots for any stories in the file. + chromatic: { disableSnapshot: true }, + }, +} satisfies Meta + +export default meta + +/** + * Get all CSS Variables in the document. + * + * Used to search CSS Variables and retrieve their values. + * + * NOTE: Function created with AI assistance + */ +const getCSSCustomPropIndex = () => { + const rootStyles = document.styleSheets + const variables = {} + + for (const sheet of rootStyles) { + for (const rule of sheet.cssRules) { + // Check for CSSStyleRule type as `selectorText` might not always be available + if (rule instanceof CSSStyleRule && rule.selectorText === ":root") { + for (const style of rule.style) { + if (style.startsWith("--")) { + variables[style] = rule.style.getPropertyValue(style).trim() + } + } + } + } + } + return variables as Record +} + +const cssVarsEntries = Object.entries(getCSSCustomPropIndex()) + +const primitiveColorKeys = ["gray", "purple"] as const +export const Primitives: StoryObj = { + render: () => { + return ( + + {primitiveColorKeys.map((color) => ( + + + {cssVarsEntries + .filter(([key]) => key.startsWith(`--${color}`)) + .map(([tokenKey, value]) => ( + +
+
+
+ + {value} + {tokenKey} + + + ))} + + + ))} + + ) + }, +} + +const ColorGroupWrapper = ({ + color, + children, +}: { + color: (typeof primitiveColorKeys)[number] + children: ReactNode +}) => ( +
+ {children} +
+) + +export const SemanticScheme: StoryObj = { + render: () => { + const tokenNames = [ + "primary", + "body", + "background", + "disabled", + "success", + "warning", + "error", + ] as const + + return ( + + {tokenNames.map((tokenName) => { + const variableObj = cssVarsEntries.filter(([key]) => + key.startsWith(`--${tokenName}`) + ) + + return ( + +

{capitalize(tokenName)}

+ + {variableObj.map((variable) => ( + + ))} + +
+ ) + })} +
+ ) + }, +} + +const SemanticColorBlock = ({ + variable: [varName, varValue], +}: { + variable: [string, string] +}) => ( + +
+ {varName} + +) diff --git a/src/styles/docsearch.css b/src/styles/docsearch.css index 05611fbea1c..e96791ab3cf 100644 --- a/src/styles/docsearch.css +++ b/src/styles/docsearch.css @@ -39,7 +39,7 @@ --docsearch-hit-height: fit-content; } -[data-theme="dark"] { +.dark { --docsearch-modal-background: theme(backgroundColor.background.DEFAULT); --docsearch-highlight-color: theme(colors.primary.hover); } diff --git a/src/styles/global.css b/src/styles/global.css index 8980eece024..2898047b069 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -50,7 +50,7 @@ ); } - [data-theme="dark"] { + .dark { /* Misc semantics: dark mode */ --tooltip-shadow: rgba(255, 255, 255, 0.24); --switch-background: rgba(255, 255, 255, 0.24); @@ -80,8 +80,12 @@ } @layer base { + * { + @apply border-border; + } + body { - @apply !bg-background font-body !text-body; + @apply bg-background font-body leading-base text-body; } a { diff --git a/src/styles/semantic-tokens.css b/src/styles/semantic-tokens.css index d9fc6459cc0..08716c5735b 100644 --- a/src/styles/semantic-tokens.css +++ b/src/styles/semantic-tokens.css @@ -129,7 +129,7 @@ } /* Dark mode token declarations */ - [data-theme="dark"] { + .dark { --body: var(--gray-100); --body-medium: var(--gray-400); --body-light: var(--gray-600); diff --git a/src/theme.ts b/src/theme.ts deleted file mode 100644 index eea69f281a6..00000000000 --- a/src/theme.ts +++ /dev/null @@ -1,395 +0,0 @@ -import { mix } from "polished" - -const white = "#ffffff" -const black = "#000000" -const primaryLight = "#1c1cff" -const primaryDark = "#ff7324" -const success = "#109e62" -const fail = "#b80000" -const turquoise = "#ccfcff" -const turquoiseDark = "#293233" -const yellow = "#fff8df" -const mint = "#e1fefa" -const mintDark = "#2d3332" -const codeBoxDark = "#2a2734" -const codeBoxLight = "#fafafa" - -// purple and orangeDark introduced for dark mode alts for homepage boxes -const purpleDark = "#212131" -const orangeDark = "#332821" -const pink = "#ffe5f9" -const pinkDark = "#332027" -const gridYellow = "#ffe78e" -const gridRed = "#ef7d7d" -const gridBlue = "#a7d0f4" -const gridPink = "#ffa1c3" - -const white500 = white -const white600 = mix(0.03, black, white) -const white700 = mix(0.1, black, white) -const white800 = mix(0.2, black, white) -const white900 = mix(0.3, black, white) - -const black50 = mix(0.5, white, black) -const black100 = mix(0.4, white, black) -const black200 = mix(0.3, white, black) -const black300 = mix(0.2, white, black) -const black400 = mix(0.1, white, black) -const black500 = black - -const primaryLight950 = mix(0.85, black, primaryLight) -const primaryLight900 = mix(0.8, black, primaryLight) -const primaryLight800 = mix(0.6, black, primaryLight) -const primaryLight700 = mix(0.4, black, primaryLight) -const primaryLight600 = mix(0.2, black, primaryLight) -const primaryLight500 = primaryLight -const primaryLight400 = mix(0.2, white, primaryLight) -const primaryLight300 = mix(0.4, white, primaryLight) -const primaryLight200 = mix(0.6, white, primaryLight) -const primaryLight100 = mix(0.8, white, primaryLight) -const primaryLight50 = mix(0.9, white, primaryLight) - -const primaryDark950 = mix(0.9, black, primaryDark) -const primaryDark900 = mix(0.8, black, primaryDark) -const primaryDark800 = mix(0.6, black, primaryDark) -const primaryDark700 = mix(0.4, black, primaryDark) -const primaryDark600 = mix(0.2, black, primaryDark) -const primaryDark500 = primaryDark -const primaryDark400 = mix(0.2, white, primaryDark) -const primaryDark300 = mix(0.4, white, primaryDark) -const primaryDark200 = mix(0.6, white, primaryDark) -const primaryDark100 = mix(0.8, white, primaryDark) - -const success900 = mix(0.8, black, success) -const success800 = mix(0.6, black, success) -const success700 = mix(0.4, black, success) -const success600 = mix(0.2, black, success) -const success500 = success -const success400 = mix(0.2, white, success) -const success300 = mix(0.4, white, success) -const success200 = mix(0.6, white, success) -const success100 = mix(0.8, white, success) - -const fail900 = mix(0.8, black, fail) -const fail800 = mix(0.6, black, fail) -const fail700 = mix(0.4, black, fail) -const fail600 = mix(0.2, black, fail) -const fail500 = fail -const fail400 = mix(0.2, white, fail) -const fail300 = mix(0.4, white, fail) -const fail200 = mix(0.6, white, fail) -const fail100 = mix(0.8, white, fail) - -const baseColors = { - white, - white500, - white600, - white700, - white800, - white900, - black, - black500, - black400, - black300, - black200, - black100, - black50, - boxShadow: "rgba(0,0,0,0.12)", - boxShadowHover: "rgba(0,0,0,0.24)", - secondary: "#b2b2b2", // TODO replace - success900, - success800, - success700, - success600, - success, - success500, - success400, - success300, - success200, - success100, - fail900, - fail800, - fail700, - fail600, - fail, - fail500, - fail400, - fail300, - fail200, - fail100, - tagBlue: primaryLight100, - tagOrange: primaryDark100, - tagGreen: success100, - tagRed: fail100, - tagTurquoise: turquoise, - tagGray: white700, - tagYellow: yellow, - tagMint: mint, - tagPink: pink, - warning: primaryDark100, - warningLink: primaryDark700, - warningLinkHover: primaryDark900, - lowBug: primaryDark100, - mediumBug: primaryDark300, - primaryLight300, - primaryDark300, - yellow, - gridYellow, - gridRed, - gridBlue, - gridGreen: success300, - gridOrange: primaryDark300, - gridPink, - gridPurple: primaryLight200, - infoBanner: primaryLight50, -} - -// TODO replace random variables w/ baseColor variables -const lightColors = { - buttonColor: white, - ghostCardBackground: white, - ghostCardGhost: white600, - secondaryButtonBackgroundActive: white700, - primary: primaryLight, - primary950: primaryLight950, - primary900: primaryLight900, - primary800: primaryLight800, - primary700: primaryLight700, - primary600: primaryLight600, - primary500: primaryLight500, - primary400: primaryLight400, - primary300: primaryLight300, - primary200: primaryLight200, - primary100: primaryLight100, - primaryHover: "rgba(28, 28, 225, 0.8)", - primaryActive: primaryLight600, - lightBorder: "#ececec", - searchBorder: "#7f7f7f", - searchBackground: white, - searchBackgroundEmpty: "#f2f2f2", - searchResultText: "#33363d", - searchResultBackground: "#f1f3f5", - selectHover: primaryLight100, - selectActive: primaryLight200, - dropdownBackground: white, - dropdownBackgroundHover: "#f2f2f2", - dropdownBorder: "#e5e5e5", - markBackground: "rgba(143,187,237,.1)", - markUnderline: "rgba(143,187,237,.5)", - modalBackground: "hsla(0, 0%, 69.8%, 0.9)", - text: "#333333", - text200: "#666666", - text300: "#4c4c4c", - textTableOfContents: "#7f7f7f", - background: white, - ednBackground: white600, - layer2ContentSecondary: white700, - border: white700, - tableBoxShadow: - "0 14px 66px rgba(0,0,0,.07), 0 10px 17px rgba(0,0,0,.03), 0 4px 7px rgba(0,0,0,.05)", - tableItemBoxShadow: "rgba(0, 0, 0, 0.1)", - tableBackgroundHover: "#f2f2f2", - preBackground: "#f2f2f2", - preBorder: "rgba(0,0,0,.05)", - homeDivider: "#a4a4f3", - displayDark: "none", - displayLight: "block", - grayBackground: "#fcfcfc", - cardGradient: - // Migrate to: "bg-gradient-to-r from-accent-a/10 to-accent-c/10" - "radial-gradient(46.28% 66.31% at 66.95% 58.35%, #e6e6f7 0%, #e7edfa 50%, #e9fbfa 100%)", - warning: primaryDark100, - warningLink: primaryDark700, - warningLinkHover: primaryDark900, - tagMint: mint, - mainnet: success200, - mainnetBorder: black50, - beaconchain: turquoise, - beaconchainBorder: black50, - shard: primaryDark100, - shardBorder: black50, - infoLink: primaryLight800, - infoLinkHover: primaryLight900, - cardBoxShadow: "4px 4px 0px 0px #d2d2f9", - homeBoxMint: mint, - homeBoxTurquoise: turquoise, - homeBoxOrange: primaryDark100, - homeBoxPurple: primaryLight50, - homeBoxPink: pink, - codeBackground: codeBoxLight, - rollupDevDocList: primaryLight50, - beta: "radial-gradient(25.56% 133.51% at 28.36% 45.54%, rgba(28, 28, 225, 0) 0%, rgba(28, 28, 225, 0.06) 100%)", - offBackground: "#f7f7f7", - stakingPillPlatform: "#cd9df3", - stakingPillUI: "#ebd27a", - stakingGold: "#be8d10", - stakingGoldFill: "#fef9ef", - stakingGreen: "#129e5b", - stakingGreenFill: "#f7faf1", - stakingBlue: "#0b83dc", - stakingBlueFill: "#f1fcf5", - stakingRed: "#a0524c", - stakingRedFill: "#f8fbf9", - feedbackGradient: - "linear-gradient(102.7deg, rgba(185, 185, 241, 0.2) 0%, rgba(84, 132, 234, 0.2) 51.56%, rgba(58, 142, 137, 0.2) 100%)", - bannerGridGradient: - "linear-gradient(90deg, rgba(127,127,213,0.2) 0%, rgba(132,145,221,0.2) 50%, rgba(145,234,228,0.2) 100%)", - sliderBg: "#F7F7F7", - sliderBorder: "#ECECEC", - sliderDot: "#A4A4A4", - sliderDotActive: "#1C1DFF", - sliderBtnBg: "#A4A4A4", - sliderBtnColor: white, - sliderBtnBgDisabled: "#E7E7E7", - sliderBtnColorDisabled: "#737373", -} - -// TODO replace random variables w/ baseColor variables -const darkColors = { - buttonColor: black300, - primaryHover: primaryDark400, - primaryActive: primaryDark200, - ghostCardBackground: black300, - ghostCardGhost: black50, - secondaryButtonBackgroundActive: black300, - primary: primaryDark, - primary950: primaryDark950, - primary900: primaryDark900, - primary800: primaryDark800, - primary700: primaryDark700, - primary600: primaryDark600, - primary500: primaryDark500, - primary400: primaryDark400, - primary300: primaryDark300, - primary200: primaryDark200, - primary100: primaryDark100, - lightBorder: "#404040", - searchBorder: "#b2b2b2", - searchBackground: "#4c4c4c", - searchBackgroundEmpty: "#333333", - searchResultText: "#f1f3f5", - searchResultBackground: "#33363d", - selectHover: primaryDark700, - selectActive: primaryDark600, - dropdownBackground: "#191919", - dropdownBackgroundHover: "#000000", - dropdownBorder: "#333333", - markBackground: "rgb(255, 115, 36, .1)", - markUnderline: "rgb(255, 115, 36, .5)", - modalBackground: "rgba(25,25,25,0.8)", - text: "#f2f2f2", - text200: "#b2b2b2", - text300: "#cccccc", - textTableOfContents: "hsla(0,0%,69.8%,.8)", - background: "#222222", - ednBackground: black400, - layer2ContentSecondary: black300, - border: black300, - tableBoxShadow: - "0 14px 66px hsla(0,0%,96.1%,.07), 0 10px 17px hsla(0,0%,96.1%,.03), 0 4px 7px hsla(0,0%,96.1%,.05)", - tableItemBoxShadow: "hsla(0,0%,100%,.1)", - tableBackgroundHover: "rgba(255,115,36,.013)", - preBackground: "#191919", - preBorder: "hsla(0,0%,100%,.05)", - homeDivider: "#ffc7a7", - displayDark: "block", - displayLight: "none", - grayBackground: "#272627", - warning: primaryDark100, - warningLink: primaryDark700, - warningLinkHover: primaryDark900, - tagMint: mint, - mainnet: "#222222", - mainnetBorder: success300, - beaconchain: "#222222", - beaconchainBorder: pink, - shard: "#222222", - shardBorder: primaryDark500, - infoLink: primaryLight800, - infoLinkHover: primaryLight900, - cardBoxShadow: "4px 4px 0px 0px #ffab7c", - homeBoxMint: mintDark, - homeBoxTurquoise: turquoiseDark, - homeBoxOrange: orangeDark, - homeBoxPurple: purpleDark, - homeBoxPink: pinkDark, - codeBackground: codeBoxDark, - rollupDevDocList: "#4c4c4c", - beta: "background: radial-gradient(25.56% 133.51% at 28.36% 45.54%, rgba(255, 143, 80, 0.72) 0%, rgba(255, 143, 80, 0.22) 100%)", - cardGradient: - // Migrate to: "dark:bg-gradient-to-tr dark:from-primary/20 dark:from-20% dark:via-accent-a/20 dark:via-60% dark:to-accent-c/20 dark:to-95%" - "linear-gradient(49.21deg, rgba(127, 127, 213, 0.2) 19.87%, rgba(134, 168, 231, 0.2) 58.46%, rgba(145, 234, 228, 0.2) 97.05% )", - offBackground: "#181818", - stakingPillPlatform: "#cd9df3", - stakingPillUI: "#ebd27a", - stakingGold: "#F2BB2F", - stakingGoldFill: "#373228", - stakingGreen: "#49DE96", - stakingGreenFill: "#30342b", - stakingBlue: "#A9D3F2", - stakingBlueFill: "#2b352f", - stakingRed: "#D6BBB9", - stakingRedFill: "#313432", - feedbackGradient: - "linear-gradient(83.46deg, #2C2C32 7.03%, #44404D 52.42%, #303038 98.77%)", - bannerGridGradient: - "linear-gradient(90deg, rgba(172, 182, 229, 0.08) 0%, rgba(134, 253, 232, 0.08) 100%)", - sliderBg: "#191919", - sliderBorder: "#404040", - sliderDot: "#A4A4A4", - sliderDotActive: "#FF7324", - sliderBtnBg: "#404040", - sliderBtnColor: white, - sliderBtnBgDisabled: "#404040", - sliderBtnColorDisabled: "#737373", -} - -const lightThemeColors = Object.assign({}, baseColors, lightColors) -const darkThemeColors = Object.assign({}, baseColors, darkColors) - -const theme = { - isDark: false, // Overwritten in Object.assign - colors: {}, // Overwritten in Object.assign - fonts: { - monospace: - '"SFMono-Regular", Consolas, "Roboto Mono", "Droid Sans Mono", "Liberation Mono", Menlo, Courier, monospace', - }, - fontSizes: { - // based on typical browser default font size of 16px - xs: "0.75rem", // 12px - s: "0.875rem", // 14px - m: "1rem", // 16px - r: "1.125rem", // 18px - l: "1.5rem", // 24px - xl: "2rem", // 32px - }, - breakpoints: { - xs: "320px", - s: "414px", - m: "768px", - l: "1024px", - xl: "1440px", // Used as the max-width - }, - variables: { - maxPageWidth: "1504px", // xl breakpoint (1440px) + 72px (2rem padding on each side) - navHeight: "4.75rem", - navBannerHeightDesktop: "134px", // 76px + 58px - navBannerHeightTablet: "159px", // 76px + 83px - navBannerHeightMobile: "184px", // 76px + 108px - navSubNavHeightDesktop: "134px", // 76px + 58px - navSideNavHeightMobile: "140px", // 76px + 64px - }, -} - -export const lightTheme = Object.assign( - {}, - theme, - { isDark: false }, - { colors: lightThemeColors } -) -export const darkTheme = Object.assign( - {}, - theme, - { isDark: true }, - { colors: darkThemeColors } -) diff --git a/tailwind.config.ts b/tailwind.config.ts index 2e1d469783d..c37ae34ff39 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -4,13 +4,8 @@ import plugin from "tailwindcss/plugin" import { screens } from "./src/lib/utils/screen" const config = { - // TODO: Move to "class" strategy after removing Chakra - darkMode: ["selector", '[data-theme="dark"]'], - content: [ - "./src/**/*.{ts,tsx}", - // TODO: remove after migration - "./tailwind/**/*.tsx", - ], + darkMode: ["selector"], + content: ["./src/**/*.{ts,tsx}"], prefix: "", theme: { extend: { diff --git a/tsconfig.json b/tsconfig.json index 0e0e5ce843e..1b936f73573 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,6 +21,6 @@ "@/storybook-utils": ["./.storybook/utils.ts"] } }, - "include": ["./src/**/*", "next-env.d.ts", "**/*.ts", "**/*.tsx", ".storybook/**/*", "tailwind/ui"], + "include": ["./src/**/*", "next-env.d.ts", "**/*.ts", "**/*.tsx", ".storybook/**/*"], "exclude": ["node_modules", "./public", "./src/intl"] } diff --git a/yarn.lock b/yarn.lock index 332198cde67..e05129da599 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2093,7 +2093,7 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.13", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== @@ -2187,825 +2187,6 @@ resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== -"@chakra-ui/accordion@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-2.3.1.tgz#a326509e286a5c4e8478de9bc2b4b05017039e6b" - integrity sha512-FSXRm8iClFyU+gVaXisOSEw0/4Q+qZbFRiuhIAkVU6Boj0FxAMrlo9a8AV5TuF77rgaHytCdHk0Ng+cyUijrag== - dependencies: - "@chakra-ui/descendant" "3.1.0" - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/transition" "2.1.0" - -"@chakra-ui/alert@2.2.2": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-2.2.2.tgz#aeba951d120c7c6e69d5f515a695ad6e4db43ffe" - integrity sha512-jHg4LYMRNOJH830ViLuicjb3F+v6iriE/2G5T+Sd0Hna04nukNJ1MxUmBPE+vI22me2dIflfelu2v9wdB6Pojw== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/spinner" "2.1.0" - -"@chakra-ui/anatomy@2.2.2": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/anatomy/-/anatomy-2.2.2.tgz#2d0e14cba2534d92077ca28abf8c183b6e27897b" - integrity sha512-MV6D4VLRIHr4PkW4zMyqfrNS1mPlCTiCXwvYGtDFQYr+xHFfonhAuf9WjsSc0nyp2m0OdkSLnzmVKkZFLo25Tg== - -"@chakra-ui/avatar@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-2.3.0.tgz#f018a2714d1e3ba5970bcf66558887925fdfccf4" - integrity sha512-8gKSyLfygnaotbJbDMHDiJoF38OHXUYVme4gGxZ1fLnQEdPVEaIWfH+NndIjOM0z8S+YEFnT9KyGMUtvPrBk3g== - dependencies: - "@chakra-ui/image" "2.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/breadcrumb@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-2.2.0.tgz#751bc48498f3c403f97b5d9aae528ebfd405ef48" - integrity sha512-4cWCG24flYBxjruRi4RJREWTGF74L/KzI2CognAW/d/zWR0CjiScuJhf37Am3LFbCySP6WSoyBOtTIoTA4yLEA== - dependencies: - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/breakpoint-utils@2.0.8": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.8.tgz#750d3712668b69f6e8917b45915cee0e08688eed" - integrity sha512-Pq32MlEX9fwb5j5xx8s18zJMARNHlQZH2VH1RZgfgRDpp7DcEgtRW5AInfN5CfqdHLO1dGxA7I3MqEuL5JnIsA== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/button@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/button/-/button-2.1.0.tgz#623ed32cc92fc8e52492923e9924791fc6f25447" - integrity sha512-95CplwlRKmmUXkdEp/21VkEWgnwcx2TOBG6NfYlsuLBDHSLlo5FKIiE2oSi4zXc4TLcopGcWPNcm/NDaSC5pvA== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/spinner" "2.1.0" - -"@chakra-ui/card@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/card/-/card-2.2.0.tgz#b5e59dc51c171fced76ea76bf26088803b8bc184" - integrity sha512-xUB/k5MURj4CtPAhdSoXZidUbm8j3hci9vnc+eZJVDqhDOShNlD6QeniQNRPRys4lWAQLCbFcrwL29C8naDi6g== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/checkbox@2.3.2": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-2.3.2.tgz#4ecb14a2f57b7470d1a58542ca4691c3b105bfa1" - integrity sha512-85g38JIXMEv6M+AcyIGLh7igNtfpAN6KGQFYxY9tBj0eWvWk4NKQxvqqyVta0bSAyIl1rixNIIezNpNWk2iO4g== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/visually-hidden" "2.2.0" - "@zag-js/focus-visible" "0.16.0" - -"@chakra-ui/cli@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/cli/-/cli-2.4.1.tgz#254a0f229a38c2ba235e2a7cc24c6c20deee8117" - integrity sha512-GZZuHUA1cXJWpmYNiVTLPihvY4VhIssRl+AXgw/0IbeodTMop3jWlIioPKLAQeXu5CwvRA6iESyGjnu1V8Zykg== - dependencies: - chokidar "^3.5.3" - cli-check-node "^1.3.4" - cli-handle-unhandled "^1.1.1" - cli-welcome "^2.2.2" - commander "^9.3.0" - esbuild "^0.17.18" - prettier "^2.8.8" - -"@chakra-ui/clickable@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/clickable/-/clickable-2.1.0.tgz#800fa8d10cf45a41fc50a3df32c679a3ce1921c3" - integrity sha512-flRA/ClPUGPYabu+/GLREZVZr9j2uyyazCAUHAdrTUEdDYCr31SVGhgh7dgKdtq23bOvAQJpIJjw/0Bs0WvbXw== - dependencies: - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/close-button@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/close-button/-/close-button-2.1.1.tgz#995b245c56eb41465a71d8667840c238618a7b66" - integrity sha512-gnpENKOanKexswSVpVz7ojZEALl2x5qjLYNqSQGbxz+aP9sOXPfUS56ebyBrre7T7exuWGiFeRwnM0oVeGPaiw== - dependencies: - "@chakra-ui/icon" "3.2.0" - -"@chakra-ui/color-mode@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/color-mode/-/color-mode-2.2.0.tgz#828d47234c74ba2fb4c5dd63a63331aead20b9f6" - integrity sha512-niTEA8PALtMWRI9wJ4LL0CSBDo8NBfLNp4GD6/0hstcm3IlbBHTVKxN6HwSaoNYfphDQLxCjT4yG+0BJA5tFpg== - dependencies: - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - -"@chakra-ui/control-box@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/control-box/-/control-box-2.1.0.tgz#0f4586797b3154c02463bc5c106782e70c88f04f" - integrity sha512-gVrRDyXFdMd8E7rulL0SKeoljkLQiPITFnsyMO8EFHNZ+AHt5wK4LIguYVEq88APqAGZGfHFWXr79RYrNiE3Mg== - -"@chakra-ui/counter@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/counter/-/counter-2.1.0.tgz#e413a2f1093a18f847bb7aa240117fde788a59e6" - integrity sha512-s6hZAEcWT5zzjNz2JIWUBzRubo9la/oof1W7EKZVVfPYHERnl5e16FmBC79Yfq8p09LQ+aqFKm/etYoJMMgghw== - dependencies: - "@chakra-ui/number-utils" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/css-reset@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-2.3.0.tgz#83e3160a9c2a12431cad0ee27ebfbf3aedc5c9c7" - integrity sha512-cQwwBy5O0jzvl0K7PLTLgp8ijqLPKyuEMiDXwYzl95seD3AoeuoCLyzZcJtVqaUZ573PiBdAbY/IlZcwDOItWg== - -"@chakra-ui/descendant@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-3.1.0.tgz#f3b80ed13ffc4bf1d615b3ed5541bd0905375cca" - integrity sha512-VxCIAir08g5w27klLyi7PVo8BxhW4tgU/lxQyujkmi4zx7hT9ZdrcQLAted/dAa+aSIZ14S1oV0Q9lGjsAdxUQ== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - -"@chakra-ui/dom-utils@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/dom-utils/-/dom-utils-2.1.0.tgz#d15df89e458ef19756db04c7cfd084eb552454f0" - integrity sha512-ZmF2qRa1QZ0CMLU8M1zCfmw29DmPNtfjR9iTo74U5FPr3i1aoAh7fbJ4qAlZ197Xw9eAW28tvzQuoVWeL5C7fQ== - -"@chakra-ui/editable@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-3.1.0.tgz#065783c2e3389c3bb9ab0582cb50d38e1dc00fa1" - integrity sha512-j2JLrUL9wgg4YA6jLlbU88370eCRyor7DZQD9lzpY95tSOXpTljeg3uF9eOmDnCs6fxp3zDWIfkgMm/ExhcGTg== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-focus-on-pointer-down" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/event-utils@2.0.8": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@chakra-ui/event-utils/-/event-utils-2.0.8.tgz#e6439ba200825a2f15d8f1973d267d1c00a6d1b4" - integrity sha512-IGM/yGUHS+8TOQrZGpAKOJl/xGBrmRYJrmbHfUE7zrG3PpQyXvbLDP1M+RggkCFVgHlJi2wpYIf0QtQlU0XZfw== - -"@chakra-ui/focus-lock@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/focus-lock/-/focus-lock-2.1.0.tgz#580e5450fe85356987b9a246abaff8333369c667" - integrity sha512-EmGx4PhWGjm4dpjRqM4Aa+rCWBxP+Rq8Uc/nAVnD4YVqkEhBkrPTpui2lnjsuxqNaZ24fIAZ10cF1hlpemte/w== - dependencies: - "@chakra-ui/dom-utils" "2.1.0" - react-focus-lock "^2.9.4" - -"@chakra-ui/form-control@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-2.2.0.tgz#69c771d6406ddac8ab357ae88446cc11827656a4" - integrity sha512-wehLC1t4fafCVJ2RvJQT2jyqsAwX7KymmiGqBu7nQoQz8ApTkGABWpo/QwDh3F/dBLrouHDoOvGmYTqft3Mirw== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/hooks@2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/hooks/-/hooks-2.2.1.tgz#b86ce5eeaaab877ddcb11a50842d1227306ace28" - integrity sha512-RQbTnzl6b1tBjbDPf9zGRo9rf/pQMholsOudTxjy4i9GfTfz6kgp5ValGjQm2z7ng6Z31N1cnjZ1AlSzQ//ZfQ== - dependencies: - "@chakra-ui/react-utils" "2.0.12" - "@chakra-ui/utils" "2.0.15" - compute-scroll-into-view "3.0.3" - copy-to-clipboard "3.3.3" - -"@chakra-ui/icon@3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/icon/-/icon-3.2.0.tgz#92b9454aa0d561b4994bcd6a1b3bb1fdd5c67bef" - integrity sha512-xxjGLvlX2Ys4H0iHrI16t74rG9EBcpFvJ3Y3B7KMQTrnW34Kf7Da/UC8J67Gtx85mTHW020ml85SVPKORWNNKQ== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/image@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/image/-/image-2.1.0.tgz#6c205f1ca148e3bf58345b0b5d4eb3d959eb9f87" - integrity sha512-bskumBYKLiLMySIWDGcz0+D9Th0jPvmX6xnRMs4o92tT3Od/bW26lahmV2a2Op2ItXeCmRMY+XxJH5Gy1i46VA== - dependencies: - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/input@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/input/-/input-2.1.2.tgz#0cad49ec372f8f21f2f4f1db365f34b9a708ff9d" - integrity sha512-GiBbb3EqAA8Ph43yGa6Mc+kUPjh4Spmxp1Pkelr8qtudpc3p2PJOOebLpd90mcqw8UePPa+l6YhhPtp6o0irhw== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/object-utils" "2.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/layout@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-2.3.1.tgz#0601c5eb91555d24a7015a7c9d4e01fed2698557" - integrity sha512-nXuZ6WRbq0WdgnRgLw+QuxWAHuhDtVX8ElWqcTK+cSMFg/52eVP47czYBE5F35YhnoW2XBwfNoNgZ7+e8Z01Rg== - dependencies: - "@chakra-ui/breakpoint-utils" "2.0.8" - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/object-utils" "2.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/lazy-utils@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@chakra-ui/lazy-utils/-/lazy-utils-2.0.5.tgz#363c3fa1d421362790b416ffa595acb835e1ae5b" - integrity sha512-UULqw7FBvcckQk2n3iPO56TMJvDsNv0FKZI6PlUNJVaGsPbsYxK/8IQ60vZgaTVPtVcjY6BE+y6zg8u9HOqpyg== - -"@chakra-ui/live-region@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/live-region/-/live-region-2.1.0.tgz#02b4b1d997075f19a7a9a87187e08c72e82ef0dd" - integrity sha512-ZOxFXwtaLIsXjqnszYYrVuswBhnIHHP+XIgK1vC6DePKtyK590Wg+0J0slDwThUAd4MSSIUa/nNX84x1GMphWw== - -"@chakra-ui/media-query@3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/media-query/-/media-query-3.3.0.tgz#40f9151dedb6a7af9df3be0474b59a799c92c619" - integrity sha512-IsTGgFLoICVoPRp9ykOgqmdMotJG0CnPsKvGQeSFOB/dZfIujdVb14TYxDU4+MURXry1MhJ7LzZhv+Ml7cr8/g== - dependencies: - "@chakra-ui/breakpoint-utils" "2.0.8" - "@chakra-ui/react-env" "3.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/menu@2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-2.2.1.tgz#7d9810d435f6b40fa72ed867a33b88a1ef75073f" - integrity sha512-lJS7XEObzJxsOwWQh7yfG4H8FzFPRP5hVPN/CL+JzytEINCSBvsCDHrYPQGp7jzpCi8vnTqQQGQe0f8dwnXd2g== - dependencies: - "@chakra-ui/clickable" "2.1.0" - "@chakra-ui/descendant" "3.1.0" - "@chakra-ui/lazy-utils" "2.0.5" - "@chakra-ui/popper" "3.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-animation-state" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-disclosure" "2.1.0" - "@chakra-ui/react-use-focus-effect" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-outside-click" "2.2.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/transition" "2.1.0" - -"@chakra-ui/modal@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-2.3.1.tgz#524dc32b6b4f545b54ae531dbf6c74e1052ee794" - integrity sha512-TQv1ZaiJMZN+rR9DK0snx/OPwmtaGH1HbZtlYt4W4s6CzyK541fxLRTjIXfEzIGpvNW+b6VFuFjbcR78p4DEoQ== - dependencies: - "@chakra-ui/close-button" "2.1.1" - "@chakra-ui/focus-lock" "2.1.0" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/transition" "2.1.0" - aria-hidden "^1.2.3" - react-remove-scroll "^2.5.6" - -"@chakra-ui/number-input@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-2.1.2.tgz#dda9095fba6a4b89212332db02831b94120da163" - integrity sha512-pfOdX02sqUN0qC2ysuvgVDiws7xZ20XDIlcNhva55Jgm095xjm8eVdIBfNm3SFbSUNxyXvLTW/YQanX74tKmuA== - dependencies: - "@chakra-ui/counter" "2.1.0" - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/react-use-event-listener" "2.1.0" - "@chakra-ui/react-use-interval" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/number-utils@2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@chakra-ui/number-utils/-/number-utils-2.0.7.tgz#aaee979ca2fb1923a0373a91619473811315db11" - integrity sha512-yOGxBjXNvLTBvQyhMDqGU0Oj26s91mbAlqKHiuw737AXHt0aPllOthVUqQMeaYLwLCjGMg0jtI7JReRzyi94Dg== - -"@chakra-ui/object-utils@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/object-utils/-/object-utils-2.1.0.tgz#a4ecf9cea92f1de09f5531f53ffdc41e0b19b6c3" - integrity sha512-tgIZOgLHaoti5PYGPTwK3t/cqtcycW0owaiOXoZOcpwwX/vlVb+H1jFsQyWiiwQVPt9RkoSLtxzXamx+aHH+bQ== - -"@chakra-ui/pin-input@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-2.1.0.tgz#61e6bbf909ec510634307b2861c4f1891a9f8d81" - integrity sha512-x4vBqLStDxJFMt+jdAHHS8jbh294O53CPQJoL4g228P513rHylV/uPscYUHrVJXRxsHfRztQO9k45jjTYaPRMw== - dependencies: - "@chakra-ui/descendant" "3.1.0" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/popover@2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-2.2.1.tgz#89cfd29817abcd204da570073c0f2b4d8072c3a3" - integrity sha512-K+2ai2dD0ljvJnlrzesCDT9mNzLifE3noGKZ3QwLqd/K34Ym1W/0aL1ERSynrcG78NKoXS54SdEzkhCZ4Gn/Zg== - dependencies: - "@chakra-ui/close-button" "2.1.1" - "@chakra-ui/lazy-utils" "2.0.5" - "@chakra-ui/popper" "3.1.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-animation-state" "2.1.0" - "@chakra-ui/react-use-disclosure" "2.1.0" - "@chakra-ui/react-use-focus-effect" "2.1.0" - "@chakra-ui/react-use-focus-on-pointer-down" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/popper@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/popper/-/popper-3.1.0.tgz#92a9180c6894763af3b22a6003f9a9d958fe2659" - integrity sha512-ciDdpdYbeFG7og6/6J8lkTFxsSvwTdMLFkpVylAF6VNC22jssiWfquj2eyD4rJnzkRFPvIWJq8hvbfhsm+AjSg== - dependencies: - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@popperjs/core" "^2.9.3" - -"@chakra-ui/portal@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-2.1.0.tgz#9e7f57424d7041738b6563cac80134561080bd27" - integrity sha512-9q9KWf6SArEcIq1gGofNcFPSWEyl+MfJjEUg/un1SMlQjaROOh3zYr+6JAwvcORiX7tyHosnmWC3d3wI2aPSQg== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - -"@chakra-ui/progress@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-2.2.0.tgz#67444ea9779631d7c8395b2c9c78e5634f994999" - integrity sha512-qUXuKbuhN60EzDD9mHR7B67D7p/ZqNS2Aze4Pbl1qGGZfulPW0PY8Rof32qDtttDQBkzQIzFGE8d9QpAemToIQ== - dependencies: - "@chakra-ui/react-context" "2.1.0" - -"@chakra-ui/provider@2.4.2": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/provider/-/provider-2.4.2.tgz#92cb10b6a7df0720e3fa62716dc7cd872ae3ea3d" - integrity sha512-w0Tef5ZCJK1mlJorcSjItCSbyvVuqpvyWdxZiVQmE6fvSJR83wZof42ux0+sfWD+I7rHSfj+f9nzhNaEWClysw== - dependencies: - "@chakra-ui/css-reset" "2.3.0" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/react-env" "3.1.0" - "@chakra-ui/system" "2.6.2" - "@chakra-ui/utils" "2.0.15" - -"@chakra-ui/radio@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-2.1.2.tgz#66db19c61a2e628aaf5e727027f7c3b4006ea898" - integrity sha512-n10M46wJrMGbonaghvSRnZ9ToTv/q76Szz284gv4QUWvyljQACcGrXIONUnQ3BIwbOfkRqSk7Xl/JgZtVfll+w== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@zag-js/focus-visible" "0.16.0" - -"@chakra-ui/react-children-utils@2.0.6": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-children-utils/-/react-children-utils-2.0.6.tgz#6c480c6a60678fcb75cb7d57107c7a79e5179b92" - integrity sha512-QVR2RC7QsOsbWwEnq9YduhpqSFnZGvjjGREV8ygKi8ADhXh93C8azLECCUVgRJF2Wc+So1fgxmjLcbZfY2VmBA== - -"@chakra-ui/react-context@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-context/-/react-context-2.1.0.tgz#4858be1d5ff1c8ac0a0ec088d93a3b7f1cbbff99" - integrity sha512-iahyStvzQ4AOwKwdPReLGfDesGG+vWJfEsn0X/NoGph/SkN+HXtv2sCfYFFR9k7bb+Kvc6YfpLlSuLvKMHi2+w== - -"@chakra-ui/react-env@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-env/-/react-env-3.1.0.tgz#7d3c1c05a501bb369524d9f3d38c9325eb16ab50" - integrity sha512-Vr96GV2LNBth3+IKzr/rq1IcnkXv+MLmwjQH6C8BRtn3sNskgDFD5vLkVXcEhagzZMCh8FR3V/bzZPojBOyNhw== - dependencies: - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - -"@chakra-ui/react-types@2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-types/-/react-types-2.0.7.tgz#799c166a44882b23059c8f510eac9bd5d0869ac4" - integrity sha512-12zv2qIZ8EHwiytggtGvo4iLT0APris7T0qaAWqzpUGS0cdUtR8W+V1BJ5Ocq+7tA6dzQ/7+w5hmXih61TuhWQ== - -"@chakra-ui/react-use-animation-state@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.1.0.tgz#eab661fbafd96804fe867b0df0c27e78feefe6e2" - integrity sha512-CFZkQU3gmDBwhqy0vC1ryf90BVHxVN8cTLpSyCpdmExUEtSEInSCGMydj2fvn7QXsz/za8JNdO2xxgJwxpLMtg== - dependencies: - "@chakra-ui/dom-utils" "2.1.0" - "@chakra-ui/react-use-event-listener" "2.1.0" - -"@chakra-ui/react-use-callback-ref@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.1.0.tgz#a508085f4d9e7d84d4ceffdf5f41745c9ac451d7" - integrity sha512-efnJrBtGDa4YaxDzDE90EnKD3Vkh5a1t3w7PhnRQmsphLy3g2UieasoKTlT2Hn118TwDjIv5ZjHJW6HbzXA9wQ== - -"@chakra-ui/react-use-controllable-state@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.1.0.tgz#8fb6fa2f45d0c04173582ae8297e604ffdb9c7d9" - integrity sha512-QR/8fKNokxZUs4PfxjXuwl0fj/d71WPrmLJvEpCTkHjnzu7LnYvzoe2wB867IdooQJL0G1zBxl0Dq+6W1P3jpg== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-disclosure@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.1.0.tgz#90093eaf45db1bea7a6851dd0ce5cdb3eb66f90a" - integrity sha512-Ax4pmxA9LBGMyEZJhhUZobg9C0t3qFE4jVF1tGBsrLDcdBeLR9fwOogIPY9Hf0/wqSlAryAimICbr5hkpa5GSw== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-event-listener@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.1.0.tgz#afea2645bd9b38f754fc2b8eb858f9bb22385ded" - integrity sha512-U5greryDLS8ISP69DKDsYcsXRtAdnTQT+jjIlRYZ49K/XhUR/AqVZCK5BkR1spTDmO9H8SPhgeNKI70ODuDU/Q== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-focus-effect@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.1.0.tgz#963fb790370dfadd51d12666ff2da60706f53a2a" - integrity sha512-xzVboNy7J64xveLcxTIJ3jv+lUJKDwRM7Szwn9tNzUIPD94O3qwjV7DDCUzN2490nSYDF4OBMt/wuDBtaR3kUQ== - dependencies: - "@chakra-ui/dom-utils" "2.1.0" - "@chakra-ui/react-use-event-listener" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - -"@chakra-ui/react-use-focus-on-pointer-down@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.1.0.tgz#2fbcf6bc7d06d97606747e231a908d5c387ca0cc" - integrity sha512-2jzrUZ+aiCG/cfanrolsnSMDykCAbv9EK/4iUyZno6BYb3vziucmvgKuoXbMPAzWNtwUwtuMhkby8rc61Ue+Lg== - dependencies: - "@chakra-ui/react-use-event-listener" "2.1.0" - -"@chakra-ui/react-use-interval@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-interval/-/react-use-interval-2.1.0.tgz#2602c097b3ab74b6644812e4f5efaad621218d98" - integrity sha512-8iWj+I/+A0J08pgEXP1J1flcvhLBHkk0ln7ZvGIyXiEyM6XagOTJpwNhiu+Bmk59t3HoV/VyvyJTa+44sEApuw== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-latest-ref@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-latest-ref/-/react-use-latest-ref-2.1.0.tgz#d1e926130102566ece1d39f8a48ed125e0c8441a" - integrity sha512-m0kxuIYqoYB0va9Z2aW4xP/5b7BzlDeWwyXCH6QpT2PpW3/281L3hLCm1G0eOUcdVlayqrQqOeD6Mglq+5/xoQ== - -"@chakra-ui/react-use-merge-refs@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.1.0.tgz#c0c233527abdbea9a1348269c192012205762314" - integrity sha512-lERa6AWF1cjEtWSGjxWTaSMvneccnAVH4V4ozh8SYiN9fSPZLlSG3kNxfNzdFvMEhM7dnP60vynF7WjGdTgQbQ== - -"@chakra-ui/react-use-outside-click@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.2.0.tgz#5570b772a255f6f02b69e967127397c1b5fa3d3c" - integrity sha512-PNX+s/JEaMneijbgAM4iFL+f3m1ga9+6QK0E5Yh4s8KZJQ/bLwZzdhMz8J/+mL+XEXQ5J0N8ivZN28B82N1kNw== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-pan-event@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.1.0.tgz#51c21bc3c0e9e73d1faef5ea4f7e3c3d071a2758" - integrity sha512-xmL2qOHiXqfcj0q7ZK5s9UjTh4Gz0/gL9jcWPA6GVf+A0Od5imEDa/Vz+533yQKWiNSm1QGrIj0eJAokc7O4fg== - dependencies: - "@chakra-ui/event-utils" "2.0.8" - "@chakra-ui/react-use-latest-ref" "2.1.0" - framesync "6.1.2" - -"@chakra-ui/react-use-previous@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-previous/-/react-use-previous-2.1.0.tgz#f6046e6f7398b1e8d7e66ff7ebb8d61c92a2d3d0" - integrity sha512-pjxGwue1hX8AFcmjZ2XfrQtIJgqbTF3Qs1Dy3d1krC77dEsiCUbQ9GzOBfDc8pfd60DrB5N2tg5JyHbypqh0Sg== - -"@chakra-ui/react-use-safe-layout-effect@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.1.0.tgz#3a95f0ba6fd5d2d0aa14919160f2c825f13e686f" - integrity sha512-Knbrrx/bcPwVS1TorFdzrK/zWA8yuU/eaXDkNj24IrKoRlQrSBFarcgAEzlCHtzuhufP3OULPkELTzz91b0tCw== - -"@chakra-ui/react-use-size@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-size/-/react-use-size-2.1.0.tgz#fcf3070eaade8b4a84af8ce5341c4d5ca0a42bec" - integrity sha512-tbLqrQhbnqOjzTaMlYytp7wY8BW1JpL78iG7Ru1DlV4EWGiAmXFGvtnEt9HftU0NJ0aJyjgymkxfVGI55/1Z4A== - dependencies: - "@zag-js/element-size" "0.10.5" - -"@chakra-ui/react-use-timeout@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-timeout/-/react-use-timeout-2.1.0.tgz#24415f54267d7241a3c1d36a5cae4d472834cef7" - integrity sha512-cFN0sobKMM9hXUhyCofx3/Mjlzah6ADaEl/AXl5Y+GawB5rgedgAcu2ErAgarEkwvsKdP6c68CKjQ9dmTQlJxQ== - dependencies: - "@chakra-ui/react-use-callback-ref" "2.1.0" - -"@chakra-ui/react-use-update-effect@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.1.0.tgz#5c57cd1f50c2a6a8119e0f57f69510723d69884b" - integrity sha512-ND4Q23tETaR2Qd3zwCKYOOS1dfssojPLJMLvUtUbW5M9uW1ejYWgGUobeAiOVfSplownG8QYMmHTP86p/v0lbA== - -"@chakra-ui/react-utils@2.0.12": - version "2.0.12" - resolved "https://registry.yarnpkg.com/@chakra-ui/react-utils/-/react-utils-2.0.12.tgz#d6b773b9a5b2e51dce61f51ac8a0e9a0f534f479" - integrity sha512-GbSfVb283+YA3kA8w8xWmzbjNWk14uhNpntnipHCftBibl0lxtQ9YqMFQLwuFOO0U2gYVocszqqDWX+XNKq9hw== - dependencies: - "@chakra-ui/utils" "2.0.15" - -"@chakra-ui/react@^2.8.0": - version "2.8.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-2.8.2.tgz#94d692fb35e4447748c5bfd73d8d38a746193c7d" - integrity sha512-Hn0moyxxyCDKuR9ywYpqgX8dvjqwu9ArwpIb9wHNYjnODETjLwazgNIliCVBRcJvysGRiV51U2/JtJVrpeCjUQ== - dependencies: - "@chakra-ui/accordion" "2.3.1" - "@chakra-ui/alert" "2.2.2" - "@chakra-ui/avatar" "2.3.0" - "@chakra-ui/breadcrumb" "2.2.0" - "@chakra-ui/button" "2.1.0" - "@chakra-ui/card" "2.2.0" - "@chakra-ui/checkbox" "2.3.2" - "@chakra-ui/close-button" "2.1.1" - "@chakra-ui/control-box" "2.1.0" - "@chakra-ui/counter" "2.1.0" - "@chakra-ui/css-reset" "2.3.0" - "@chakra-ui/editable" "3.1.0" - "@chakra-ui/focus-lock" "2.1.0" - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/hooks" "2.2.1" - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/image" "2.1.0" - "@chakra-ui/input" "2.1.2" - "@chakra-ui/layout" "2.3.1" - "@chakra-ui/live-region" "2.1.0" - "@chakra-ui/media-query" "3.3.0" - "@chakra-ui/menu" "2.2.1" - "@chakra-ui/modal" "2.3.1" - "@chakra-ui/number-input" "2.1.2" - "@chakra-ui/pin-input" "2.1.0" - "@chakra-ui/popover" "2.2.1" - "@chakra-ui/popper" "3.1.0" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/progress" "2.2.0" - "@chakra-ui/provider" "2.4.2" - "@chakra-ui/radio" "2.1.2" - "@chakra-ui/react-env" "3.1.0" - "@chakra-ui/select" "2.1.2" - "@chakra-ui/skeleton" "2.1.0" - "@chakra-ui/skip-nav" "2.1.0" - "@chakra-ui/slider" "2.1.0" - "@chakra-ui/spinner" "2.1.0" - "@chakra-ui/stat" "2.1.1" - "@chakra-ui/stepper" "2.3.1" - "@chakra-ui/styled-system" "2.9.2" - "@chakra-ui/switch" "2.1.2" - "@chakra-ui/system" "2.6.2" - "@chakra-ui/table" "2.1.0" - "@chakra-ui/tabs" "3.0.0" - "@chakra-ui/tag" "3.1.1" - "@chakra-ui/textarea" "2.1.2" - "@chakra-ui/theme" "3.3.1" - "@chakra-ui/theme-utils" "2.0.21" - "@chakra-ui/toast" "7.0.2" - "@chakra-ui/tooltip" "2.3.1" - "@chakra-ui/transition" "2.1.0" - "@chakra-ui/utils" "2.0.15" - "@chakra-ui/visually-hidden" "2.2.0" - -"@chakra-ui/select@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/select/-/select-2.1.2.tgz#f57d6cec0559373c32094fd4a5abd32855829264" - integrity sha512-ZwCb7LqKCVLJhru3DXvKXpZ7Pbu1TDZ7N0PdQ0Zj1oyVLJyrpef1u9HR5u0amOpqcH++Ugt0f5JSmirjNlctjA== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/shared-utils@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@chakra-ui/shared-utils/-/shared-utils-2.0.5.tgz#cb2b49705e113853647f1822142619570feba081" - integrity sha512-4/Wur0FqDov7Y0nCXl7HbHzCg4aq86h+SXdoUeuCMD3dSj7dpsVnStLYhng1vxvlbUnLpdF4oz5Myt3i/a7N3Q== - -"@chakra-ui/skeleton@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/skeleton/-/skeleton-2.1.0.tgz#e3b25dd3afa330029d6d63be0f7cb8d44ad25531" - integrity sha512-JNRuMPpdZGd6zFVKjVQ0iusu3tXAdI29n4ZENYwAJEMf/fN0l12sVeirOxkJ7oEL0yOx2AgEYFSKdbcAgfUsAQ== - dependencies: - "@chakra-ui/media-query" "3.3.0" - "@chakra-ui/react-use-previous" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/skip-nav@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/skip-nav/-/skip-nav-2.1.0.tgz#cac27eecc6eded1e83c8f0cf7445d727739cb325" - integrity sha512-Hk+FG+vadBSH0/7hwp9LJnLjkO0RPGnx7gBJWI4/SpoJf3e4tZlWYtwGj0toYY4aGKl93jVghuwGbDBEMoHDug== - -"@chakra-ui/slider@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-2.1.0.tgz#1caeed18761ba2a390777418cc9389ba25e39bce" - integrity sha512-lUOBcLMCnFZiA/s2NONXhELJh6sY5WtbRykPtclGfynqqOo47lwWJx+VP7xaeuhDOPcWSSecWc9Y1BfPOCz9cQ== - dependencies: - "@chakra-ui/number-utils" "2.0.7" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-callback-ref" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-latest-ref" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-pan-event" "2.1.0" - "@chakra-ui/react-use-size" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - -"@chakra-ui/spinner@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/spinner/-/spinner-2.1.0.tgz#aa24a3d692c6ac90714e0f0f82c76c12c78c8e60" - integrity sha512-hczbnoXt+MMv/d3gE+hjQhmkzLiKuoTo42YhUG7Bs9OSv2lg1fZHW1fGNRFP3wTi6OIbD044U1P9HK+AOgFH3g== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/stat@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-2.1.1.tgz#a204ba915795345996a16c79794d84826d7dcc2d" - integrity sha512-LDn0d/LXQNbAn2KaR3F1zivsZCewY4Jsy1qShmfBMKwn6rI8yVlbvu6SiA3OpHS0FhxbsZxQI6HefEoIgtqY6Q== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/stepper@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/stepper/-/stepper-2.3.1.tgz#a0a0b73e147f202ab4e51cae55dad45489cc89fd" - integrity sha512-ky77lZbW60zYkSXhYz7kbItUpAQfEdycT0Q4bkHLxfqbuiGMf8OmgZOQkOB9uM4v0zPwy2HXhe0vq4Dd0xa55Q== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/styled-system@2.9.2": - version "2.9.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-2.9.2.tgz#898ab63da560a4a014f7b05fa7767e8c76da6d2f" - integrity sha512-To/Z92oHpIE+4nk11uVMWqo2GGRS86coeMmjxtpnErmWRdLcp1WVCVRAvn+ZwpLiNR+reWFr2FFqJRsREuZdAg== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - csstype "^3.1.2" - lodash.mergewith "4.6.2" - -"@chakra-ui/switch@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-2.1.2.tgz#f7c6878d8126bfac8fa3b939079f1017c21b7479" - integrity sha512-pgmi/CC+E1v31FcnQhsSGjJnOE2OcND4cKPyTE+0F+bmGm48Q/b5UmKD9Y+CmZsrt/7V3h8KNczowupfuBfIHA== - dependencies: - "@chakra-ui/checkbox" "2.3.2" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/system@2.6.2": - version "2.6.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/system/-/system-2.6.2.tgz#528ec955bd6a7f74da46470ee8225b1e2c80a78b" - integrity sha512-EGtpoEjLrUu4W1fHD+a62XR+hzC5YfsWm+6lO0Kybcga3yYEij9beegO0jZgug27V+Rf7vns95VPVP6mFd/DEQ== - dependencies: - "@chakra-ui/color-mode" "2.2.0" - "@chakra-ui/object-utils" "2.1.0" - "@chakra-ui/react-utils" "2.0.12" - "@chakra-ui/styled-system" "2.9.2" - "@chakra-ui/theme-utils" "2.0.21" - "@chakra-ui/utils" "2.0.15" - react-fast-compare "3.2.2" - -"@chakra-ui/table@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/table/-/table-2.1.0.tgz#20dce14c5e4d70dc7c6c0e87cce9b05907ff8c50" - integrity sha512-o5OrjoHCh5uCLdiUb0Oc0vq9rIAeHSIRScc2ExTC9Qg/uVZl2ygLrjToCaKfaaKl1oQexIeAcZDKvPG8tVkHyQ== - dependencies: - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/tabs@3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-3.0.0.tgz#854c06880af26158d7c72881c4b5e0453f6c485d" - integrity sha512-6Mlclp8L9lqXmsGWF5q5gmemZXOiOYuh0SGT/7PgJVNPz3LXREXlXg2an4MBUD8W5oTkduCX+3KTMCwRrVrDYw== - dependencies: - "@chakra-ui/clickable" "2.1.0" - "@chakra-ui/descendant" "3.1.0" - "@chakra-ui/lazy-utils" "2.0.5" - "@chakra-ui/react-children-utils" "2.0.6" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-controllable-state" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/react-use-safe-layout-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/tag@3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-3.1.1.tgz#d05284b6549a84d3a08e57eec57df3ad0eebd882" - integrity sha512-Bdel79Dv86Hnge2PKOU+t8H28nm/7Y3cKd4Kfk9k3lOpUh4+nkSGe58dhRzht59lEqa4N9waCgQiBdkydjvBXQ== - dependencies: - "@chakra-ui/icon" "3.2.0" - "@chakra-ui/react-context" "2.1.0" - -"@chakra-ui/textarea@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-2.1.2.tgz#30f8af0e233cec2dee79d527450c6586e7122eff" - integrity sha512-ip7tvklVCZUb2fOHDb23qPy/Fr2mzDOGdkrpbNi50hDCiV4hFX02jdQJdi3ydHZUyVgZVBKPOJ+lT9i7sKA2wA== - dependencies: - "@chakra-ui/form-control" "2.2.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/theme-tools@2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/theme-tools/-/theme-tools-2.1.2.tgz#913be05879cd816c546993ccb9ff7615f85ff69f" - integrity sha512-Qdj8ajF9kxY4gLrq7gA+Azp8CtFHGO9tWMN2wfF9aQNgG9AuMhPrUzMq9AMQ0MXiYcgNq/FD3eegB43nHVmXVA== - dependencies: - "@chakra-ui/anatomy" "2.2.2" - "@chakra-ui/shared-utils" "2.0.5" - color2k "^2.0.2" - -"@chakra-ui/theme-utils@2.0.21": - version "2.0.21" - resolved "https://registry.yarnpkg.com/@chakra-ui/theme-utils/-/theme-utils-2.0.21.tgz#da7ed541a5241a8ed0384eb14f37fa9b998382cf" - integrity sha512-FjH5LJbT794r0+VSCXB3lT4aubI24bLLRWB+CuRKHijRvsOg717bRdUN/N1fEmEpFnRVrbewttWh/OQs0EWpWw== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/styled-system" "2.9.2" - "@chakra-ui/theme" "3.3.1" - lodash.mergewith "4.6.2" - -"@chakra-ui/theme@3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-3.3.1.tgz#75c6cd0b5c70c0aa955068274ee4780f299bd8a4" - integrity sha512-Hft/VaT8GYnItGCBbgWd75ICrIrIFrR7lVOhV/dQnqtfGqsVDlrztbSErvMkoPKt0UgAkd9/o44jmZ6X4U2nZQ== - dependencies: - "@chakra-ui/anatomy" "2.2.2" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/theme-tools" "2.1.2" - -"@chakra-ui/toast@7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-7.0.2.tgz#d1c396bbfced12e22b010899731fd8cc294d53ec" - integrity sha512-yvRP8jFKRs/YnkuE41BVTq9nB2v/KDRmje9u6dgDmE5+1bFt3bwjdf9gVbif4u5Ve7F7BGk5E093ARRVtvLvXA== - dependencies: - "@chakra-ui/alert" "2.2.2" - "@chakra-ui/close-button" "2.1.1" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/react-context" "2.1.0" - "@chakra-ui/react-use-timeout" "2.1.0" - "@chakra-ui/react-use-update-effect" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - "@chakra-ui/styled-system" "2.9.2" - "@chakra-ui/theme" "3.3.1" - -"@chakra-ui/tooltip@2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-2.3.1.tgz#29fb8508a37bb6b20ab8dbb32bca6cd59b098796" - integrity sha512-Rh39GBn/bL4kZpuEMPPRwYNnccRCL+w9OqamWHIB3Qboxs6h8cOyXfIdGxjo72lvhu1QI/a4KFqkM3St+WfC0A== - dependencies: - "@chakra-ui/dom-utils" "2.1.0" - "@chakra-ui/popper" "3.1.0" - "@chakra-ui/portal" "2.1.0" - "@chakra-ui/react-types" "2.0.7" - "@chakra-ui/react-use-disclosure" "2.1.0" - "@chakra-ui/react-use-event-listener" "2.1.0" - "@chakra-ui/react-use-merge-refs" "2.1.0" - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/transition@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-2.1.0.tgz#c8e95564f7ab356e78119780037bae5ad150c7b3" - integrity sha512-orkT6T/Dt+/+kVwJNy7zwJ+U2xAZ3EU7M3XCs45RBvUnZDr/u9vdmaM/3D/rOpmQJWgQBwKPJleUXrYWUagEDQ== - dependencies: - "@chakra-ui/shared-utils" "2.0.5" - -"@chakra-ui/utils@2.0.15": - version "2.0.15" - resolved "https://registry.yarnpkg.com/@chakra-ui/utils/-/utils-2.0.15.tgz#bd800b1cff30eb5a5e8c36fa039f49984b4c5e4a" - integrity sha512-El4+jL0WSaYYs+rJbuYFDbjmfCcfGDmRY95GO4xwzit6YAPZBLcR65rOEwLps+XWluZTy1xdMrusg/hW0c1aAA== - dependencies: - "@types/lodash.mergewith" "4.6.7" - css-box-model "1.2.1" - framesync "6.1.2" - lodash.mergewith "4.6.2" - -"@chakra-ui/visually-hidden@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-2.2.0.tgz#9b0ecef8f01263ab808ba3bda7b36a0d91b4d5c1" - integrity sha512-KmKDg01SrQ7VbTD3+cPWf/UfpF5MSwm3v7MWi0n5t8HnnadT13MF0MJCDSXbBWnzLv1ZKJ6zlyAOeARWX+DpjQ== - "@chromatic-com/storybook@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@chromatic-com/storybook/-/storybook-1.5.0.tgz#a1312b7fc8ac0df2d43c51e48014e024fd4b9561" @@ -3101,13 +2282,6 @@ dependencies: "@emotion/memoize" "0.7.4" -"@emotion/is-prop-valid@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" - integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== - dependencies: - "@emotion/memoize" "^0.8.1" - "@emotion/memoize@0.7.4": version "0.7.4" resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" @@ -3118,7 +2292,7 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== -"@emotion/react@^11.11.1", "@emotion/react@^11.8.1": +"@emotion/react@^11.8.1": version "11.11.3" resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.3.tgz#96b855dc40a2a55f52a72f518a41db4f69c31a25" integrity sha512-Cnn0kuq4DoONOMcnoVsTOR8E+AdnKFf//6kUWc4LCdnxj31pZWn7rIULd6Y7/Js1PiPHzn7SKCM9vB/jBni8eA== @@ -3148,18 +2322,6 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== -"@emotion/styled@^11.11.0": - version "11.11.0" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" - integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== - dependencies: - "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.11.0" - "@emotion/is-prop-valid" "^1.2.1" - "@emotion/serialize" "^1.1.2" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" - "@emotion/utils" "^1.2.1" - "@emotion/unitless@^0.8.1": version "0.8.1" resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" @@ -3185,221 +2347,111 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== -"@esbuild/android-arm64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" - integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== - "@esbuild/android-arm64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== -"@esbuild/android-arm@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" - integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== - "@esbuild/android-arm@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== -"@esbuild/android-x64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" - integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== - "@esbuild/android-x64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== -"@esbuild/darwin-arm64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" - integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== - "@esbuild/darwin-arm64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== -"@esbuild/darwin-x64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" - integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== - "@esbuild/darwin-x64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== -"@esbuild/freebsd-arm64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" - integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== - "@esbuild/freebsd-arm64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== -"@esbuild/freebsd-x64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" - integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== - "@esbuild/freebsd-x64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== -"@esbuild/linux-arm64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" - integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== - "@esbuild/linux-arm64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== -"@esbuild/linux-arm@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" - integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== - "@esbuild/linux-arm@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== -"@esbuild/linux-ia32@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" - integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== - "@esbuild/linux-ia32@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== -"@esbuild/linux-loong64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" - integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== - "@esbuild/linux-loong64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== -"@esbuild/linux-mips64el@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" - integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== - "@esbuild/linux-mips64el@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== -"@esbuild/linux-ppc64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" - integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== - "@esbuild/linux-ppc64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== -"@esbuild/linux-riscv64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" - integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== - "@esbuild/linux-riscv64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== -"@esbuild/linux-s390x@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" - integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== - "@esbuild/linux-s390x@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== -"@esbuild/linux-x64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" - integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== - "@esbuild/linux-x64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== -"@esbuild/netbsd-x64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" - integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== - "@esbuild/netbsd-x64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== -"@esbuild/openbsd-x64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" - integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== - "@esbuild/openbsd-x64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== -"@esbuild/sunos-x64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" - integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== - "@esbuild/sunos-x64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== -"@esbuild/win32-arm64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" - integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== - "@esbuild/win32-arm64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== -"@esbuild/win32-ia32@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" - integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== - "@esbuild/win32-ia32@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== -"@esbuild/win32-x64@0.17.19": - version "0.17.19" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" - integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== - "@esbuild/win32-x64@0.20.2": version "0.20.2" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" @@ -3487,6 +2539,54 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.5.tgz#105c37d9d9620ce69b7f692a20c821bf1ad2cbf9" integrity sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ== +"@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/fast-memoize" "2.2.6" + "@formatjs/intl-localematcher" "0.6.0" + decimal.js "10" + tslib "2" + +"@formatjs/fast-memoize@2.2.6", "@formatjs/fast-memoize@^2.2.0": + 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" + +"@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" "2.3.3" + "@formatjs/icu-skeleton-parser" "1.8.13" + tslib "2" + +"@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" "2.3.3" + tslib "2" + +"@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" + +"@formatjs/intl-localematcher@^0.5.4": + version "0.5.10" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.10.tgz#1e0bd3fc1332c1fe4540cfa28f07e9227b659a58" + integrity sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q== + dependencies: + tslib "2" + "@hookform/resolvers@^3.8.0": version "3.9.0" resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.9.0.tgz#cf540ac21c6c0cd24a40cf53d8e6d64391fb753d" @@ -3762,11 +2862,6 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.25.tgz#f077fdc0b5d0078d30893396ff4827a13f99e817" integrity sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ== -"@popperjs/core@^2.9.3": - version "2.11.8" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" - integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== - "@radix-ui/number@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.1.0.tgz#1e95610461a09cdf8bb05c152e76ca1278d5da46" @@ -5126,7 +4221,7 @@ fs-extra "^11.1.0" read-pkg-up "^7.0.1" -"@storybook/test@8.1.10", "@storybook/test@^8.0.10": +"@storybook/test@8.1.10": version "8.1.10" resolved "https://registry.yarnpkg.com/@storybook/test/-/test-8.1.10.tgz#ed05aaeaf96d00cc82947ac596b0456e21583a30" integrity sha512-uskw/xb/GkGLRTEKPao/5xUKxjP1X3DnDpE52xDF46ZmTvM+gPQbkex97qdG6Mfv37/0lhVhufAsV3g5+CrYKQ== @@ -5554,14 +4649,6 @@ dependencies: "@types/unist" "*" -"@types/hoist-non-react-statics@^3.3.1": - version "3.3.5" - 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== - dependencies: - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - "@types/html-minifier-terser@^6.0.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" @@ -5582,14 +4669,7 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/lodash.mergewith@4.6.7": - version "4.6.7" - resolved "https://registry.yarnpkg.com/@types/lodash.mergewith/-/lodash.mergewith-4.6.7.tgz#eaa65aa5872abdd282f271eae447b115b2757212" - integrity sha512-3m+lkO5CLRRYU0fhGRp7zbsGi6+BZj0uTVSwvcKU+nSlhjA9/QRNfuSGnD2mX6hQA7ZbmcCkzk5h4ZYGOtk14A== - dependencies: - "@types/lodash" "*" - -"@types/lodash@*", "@types/lodash@^4.14.167": +"@types/lodash@^4.14.167": version "4.14.202" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== @@ -6170,23 +5250,6 @@ "@types/emscripten" "^1.39.6" tslib "^1.13.0" -"@zag-js/dom-query@0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@zag-js/dom-query/-/dom-query-0.16.0.tgz#bca46bcd78f78c900064478646d95f9781ed098e" - integrity sha512-Oqhd6+biWyKnhKwFFuZrrf6lxBz2tX2pRQe6grUnYwO6HJ8BcbqZomy2lpOdr+3itlaUqx+Ywj5E5ZZDr/LBfQ== - -"@zag-js/element-size@0.10.5": - version "0.10.5" - resolved "https://registry.yarnpkg.com/@zag-js/element-size/-/element-size-0.10.5.tgz#a24bad2eeb7e2c8709e32be5336e158e1a1a174f" - integrity sha512-uQre5IidULANvVkNOBQ1tfgwTQcGl4hliPSe69Fct1VfYb2Fd0jdAcGzqQgPhfrXFpR62MxLPB7erxJ/ngtL8w== - -"@zag-js/focus-visible@0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@zag-js/focus-visible/-/focus-visible-0.16.0.tgz#c9e53e3dbab0f2649d04a489bb379f5800f4f069" - integrity sha512-a7U/HSopvQbrDU4GLerpqiMcHKEkQkNPeDZJWz38cw/6Upunh41GjHetq5TB84hxyCaDzJ6q2nEdNoBQfC0FKA== - dependencies: - "@zag-js/dom-query" "0.16.0" - abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -6410,7 +5473,7 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-hidden@^1.1.1, aria-hidden@^1.2.3: +aria-hidden@^1.1.1: version "1.2.3" resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954" integrity sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ== @@ -7245,19 +6308,6 @@ clean-css@^5.2.2: dependencies: source-map "~0.6.0" -clear-any-console@^1.16.0: - version "1.16.2" - resolved "https://registry.yarnpkg.com/clear-any-console/-/clear-any-console-1.16.2.tgz#0543bb068da00151bf77b7a01ebf05d611086bb9" - integrity sha512-OL/7wZpNy9x0GBSzz3poWja84Nr7iaH8aYNsJ5Uet2BVLj6Lm1zvWpZN/yH46Vv3ae7YfHmLLMmfHj911fshJg== - -cli-check-node@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/cli-check-node/-/cli-check-node-1.3.4.tgz#f48f5b088ce4ab2ff5630ae007461b4f12ee2bb7" - integrity sha512-iLGgQXm82iP8eH3R67qbOWs5qqUOLmNnMy5Lzl/RybcMh3y+H2zWU5POzuQ6oDUOdz4XWuxcFhP75szqd6frLg== - dependencies: - chalk "^3.0.0" - log-symbols "^3.0.0" - cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -7272,21 +6322,6 @@ cli-cursor@^4.0.0: dependencies: restore-cursor "^4.0.0" -cli-handle-error@^4.1.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/cli-handle-error/-/cli-handle-error-4.4.0.tgz#f65d7d66c3d648a063696b5c83f3b8cc850da25d" - integrity sha512-RyBCnKlc7xVr79cKb9RfBq+4fjwQeX8HKeNzIPnI/W+DWWIUUKh2ur576DpwJ3kZt2UGHlIAOF7N9txy+mgZsA== - dependencies: - chalk "^3.0.0" - log-symbols "^3.0.0" - -cli-handle-unhandled@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/cli-handle-unhandled/-/cli-handle-unhandled-1.1.1.tgz#8a62e244e29cc74ec3f89954a8e8871a4d81e7d8" - integrity sha512-Em91mJvU7VdgT2MxQpyY633vW1tDzRjPDbii6ZjEBHHLLh0xDoVkFt/wjvi9nSvJcz9rJmvtJSK8KL/hvF0Stg== - dependencies: - cli-handle-error "^4.1.0" - cli-spinners@^2.5.0: version "2.9.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" @@ -7309,15 +6344,6 @@ cli-truncate@^4.0.0: slice-ansi "^5.0.0" string-width "^7.0.0" -cli-welcome@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/cli-welcome/-/cli-welcome-2.2.2.tgz#a67c55e7826acbd8117266db73590e35b3611261" - integrity sha512-LgDGS0TW4nIf8v81wpuZzfOEDPcy68u0jKR0Fy5IaWftqdminI6FoDiMFt1mjPylqKGNv/wFsZ7fCs93IeDMIw== - dependencies: - chalk "^2.4.2" - clear-any-console "^1.16.0" - prettier "^2.0.5" - client-only@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" @@ -7401,11 +6427,6 @@ color-string@^1.9.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color2k@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/color2k/-/color2k-2.0.3.tgz#a771244f6b6285541c82aa65ff0a0c624046e533" - integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== - color@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" @@ -7456,11 +6477,6 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== -commander@^9.3.0: - version "9.5.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" - integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== - commander@~12.1.0: version "12.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" @@ -7496,11 +6512,6 @@ compression@^1.7.4: safe-buffer "5.1.2" vary "~1.1.2" -compute-scroll-into-view@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-3.0.3.tgz#c418900a5c56e2b04b885b54995df164535962b1" - integrity sha512-nadqwNxghAGTamwIqQSG433W6OADZx2vCo3UXHNrzTRHK/htu+7+L0zhjEoaeaQVNAi3YgqWDv8+tzf0hRfR+A== - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -7553,13 +6564,6 @@ cookie@0.6.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== -copy-to-clipboard@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" - integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== - dependencies: - toggle-selection "^1.0.6" - core-js-compat@^3.31.0, core-js-compat@^3.34.0: version "3.35.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.35.1.tgz#215247d7edb9e830efa4218ff719beb2803555e2" @@ -7579,11 +6583,6 @@ core-js-pure@^3.23.3: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.37.1.tgz#2b4b34281f54db06c9a9a5bd60105046900553bd" integrity sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA== -core-js@^3: - version "3.35.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.35.1.tgz#9c28f8b7ccee482796f8590cc8d15739eaaf980c" - integrity sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw== - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" @@ -7689,13 +6688,6 @@ crypto-random-string@^4.0.0: dependencies: type-fest "^1.0.1" -css-box-model@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1" - integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw== - dependencies: - tiny-invariant "^1.0.6" - css-loader@^6.7.1, css-loader@^6.7.3: version "6.11.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" @@ -7770,7 +6762,7 @@ csso@^5.0.5: dependencies: css-tree "~2.2.0" -csstype@^3.0.2, csstype@^3.1.2: +csstype@^3.0.2: version "3.1.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== @@ -7889,6 +6881,11 @@ decimal.js-light@^2.4.1: resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== +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.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" @@ -8572,34 +7569,6 @@ esbuild@^0.12.9: resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.29.tgz#be602db7c4dc78944a9dbde0d1ea19d36c1f882d" integrity sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g== -esbuild@^0.17.18: - version "0.17.19" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" - integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== - optionalDependencies: - "@esbuild/android-arm" "0.17.19" - "@esbuild/android-arm64" "0.17.19" - "@esbuild/android-x64" "0.17.19" - "@esbuild/darwin-arm64" "0.17.19" - "@esbuild/darwin-x64" "0.17.19" - "@esbuild/freebsd-arm64" "0.17.19" - "@esbuild/freebsd-x64" "0.17.19" - "@esbuild/linux-arm" "0.17.19" - "@esbuild/linux-arm64" "0.17.19" - "@esbuild/linux-ia32" "0.17.19" - "@esbuild/linux-loong64" "0.17.19" - "@esbuild/linux-mips64el" "0.17.19" - "@esbuild/linux-ppc64" "0.17.19" - "@esbuild/linux-riscv64" "0.17.19" - "@esbuild/linux-s390x" "0.17.19" - "@esbuild/linux-x64" "0.17.19" - "@esbuild/netbsd-x64" "0.17.19" - "@esbuild/openbsd-x64" "0.17.19" - "@esbuild/sunos-x64" "0.17.19" - "@esbuild/win32-arm64" "0.17.19" - "@esbuild/win32-ia32" "0.17.19" - "@esbuild/win32-x64" "0.17.19" - "esbuild@^0.18.0 || ^0.19.0 || ^0.20.0": version "0.20.2" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1" @@ -9265,13 +8234,6 @@ flow-parser@0.*: resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.227.0.tgz#e50b65be9dc6810438c975e816a68005fbcd5107" integrity sha512-nOygtGKcX/siZK/lFzpfdHEfOkfGcTW7rNroR1Zsz6T/JxSahPALXVt5qVHq/fgvMJuv096BTKbgxN3PzVBaDA== -focus-lock@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-1.0.0.tgz#2c50d8ce59d3d6608cda2672be9e65812459206c" - integrity sha512-a8Ge6cdKh9za/GZR/qtigTAk7SrGore56EFcoMshClsh7FLk1zwszc/ltuMfKhx56qeuyL/jWQ4J4axou0iJ9w== - dependencies: - tslib "^2.0.3" - follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" @@ -9338,13 +8300,6 @@ framer-motion@^10.13.0: optionalDependencies: "@emotion/is-prop-valid" "^0.8.2" -framesync@6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/framesync/-/framesync-6.1.2.tgz#755eff2fb5b8f3b4d2b266dd18121b300aefea27" - integrity sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g== - dependencies: - tslib "2.4.0" - fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -9863,7 +8818,7 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.3.1: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -9898,13 +8853,6 @@ html-minifier-terser@^6.0.2: relateurl "^0.2.7" terser "^5.10.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" - html-tags@^3.1.0: version "3.3.1" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" @@ -9975,18 +8923,6 @@ husky@^9.0.11: resolved "https://registry.yarnpkg.com/husky/-/husky-9.0.11.tgz#fc91df4c756050de41b3e478b2158b87c1e79af9" integrity sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw== -i18next-fs-backend@^2.1.5: - 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.6.0: - version "23.8.1" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.8.1.tgz#c9c6c0a2718177457192d3a867af5b35cd2f46fe" - integrity sha512-Yhe6oiJhigSh64ev7nVVywu7vHjuUG41MRmFKNwphbkadqTL1ozZFBQISflY7/ju+gL6I/SPfI1GgWQh1yYArA== - dependencies: - "@babel/runtime" "^7.23.2" - iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -10076,6 +9012,16 @@ internal-slot@^1.0.4, internal-slot@^1.0.5: resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== +intl-messageformat@^10.5.14: + 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" "2.3.3" + "@formatjs/fast-memoize" "2.2.6" + "@formatjs/icu-messageformat-parser" "2.11.1" + tslib "2" + invariant@^2.2.1, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -10777,11 +9723,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.mergewith@4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" - integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== - lodash.shuffle@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.shuffle/-/lodash.shuffle-4.2.0.tgz#145b5053cf875f6f5c2a33f48b6e9948c6ec7b4b" @@ -10802,13 +9743,6 @@ lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== - dependencies: - chalk "^2.4.2" - log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" @@ -11631,21 +10565,24 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" + integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== + neo-async@^2.5.0, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -next-i18next@^14.0.3: - version "14.0.3" - resolved "https://registry.yarnpkg.com/next-i18next/-/next-i18next-14.0.3.tgz#9c17e69483b3af4172b15454af2ef92c5f79be48" - integrity sha512-FtnjRMfhlamk8YyeyWqd+pndNL+3er83iMZnH4M4mhiGA93l0+vtBUvuObgOAMHDJGLLB2SS2xOOZq69oiJh7A== +next-intl@^3.26.3: + version "3.26.4" + resolved "https://registry.yarnpkg.com/next-intl/-/next-intl-3.26.4.tgz#7dcb4c15412c69f60df56636a9ed56ade82fb63c" + integrity sha512-/kFFR7WYJGisOR0xKoC930e6oTOOWf8rbHviQgte5zIn6OgJ6mKFvXI94RWAW3ksCZJCvE4zblIuYwHCSbbw7g== 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.5" + "@formatjs/intl-localematcher" "^0.5.4" + negotiator "^1.0.0" + use-intl "^3.26.4" next-mdx-remote@^3.0.8: version "3.0.8" @@ -12484,11 +11421,6 @@ prettier-plugin-tailwindcss@^0.6.5: resolved "https://registry.yarnpkg.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.5.tgz#e05202784a3f41889711ae38c75c5b8cad72f368" integrity sha512-axfeOArc/RiGHjOIy9HytehlC0ZLeMaqY09mm8YCkMzznKiDkwFzOpBvtuhuv3xG5qB73+Mj7OCe2j/L1ryfuQ== -prettier@^2.0.5, prettier@^2.8.8: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - prettier@^3.1.1: version "3.3.2" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.2.tgz#03ff86dc7c835f2d2559ee76876a3914cec4a90a" @@ -12742,13 +11674,6 @@ react-chartjs-2@^5.2.0: resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-5.2.0.tgz#43c1e3549071c00a1a083ecbd26c1ad34d385f5d" integrity sha512-98iN5aguJyVSxp5U3CblRLH67J8gkfyGNbiK3c+l1QI/G4irHMPQw44aEPmjVag+YKTyQ260NcF82GTQ3bdscA== -react-clientside-effect@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz#29f9b14e944a376b03fb650eed2a754dd128ea3a" - integrity sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg== - dependencies: - "@babel/runtime" "^7.12.13" - react-colorful@^5.1.2: version "5.6.1" resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b" @@ -12818,36 +11743,11 @@ react-emoji-render@^2.0.1: prop-types "^15.5.8" string-replace-to-array "^1.0.1" -react-fast-compare@3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" - integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== - -react-focus-lock@^2.9.4: - version "2.9.7" - resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.7.tgz#778358691b55db38a9954a989341048bd4065935" - integrity sha512-EfhX040SELLqnQ9JftqsmQCG49iByg8F5X5m19Er+n371OaETZ35dlNPZrLOOTlnnwD4c2Zv0KDgabDTc7dPHw== - dependencies: - "@babel/runtime" "^7.0.0" - focus-lock "^1.0.0" - prop-types "^15.6.2" - react-clientside-effect "^1.2.6" - use-callback-ref "^1.3.0" - use-sidecar "^1.1.2" - react-hook-form@^7.52.1: version "7.52.1" resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.52.1.tgz#ec2c96437b977f8b89ae2d541a70736c66284852" integrity sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg== -react-i18next@^13.3.1: - version "13.5.0" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-13.5.0.tgz#44198f747628267a115c565f0c736a50a76b1ab0" - integrity sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA== - dependencies: - "@babel/runtime" "^7.22.5" - html-parse-stringify "^3.0.1" - react-icons@^4.10.1: version "4.12.0" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.12.0.tgz#54806159a966961bfd5cdb26e492f4dafd6a8d78" @@ -12907,7 +11807,7 @@ react-remove-scroll@2.5.5: use-callback-ref "^1.3.0" use-sidecar "^1.1.2" -react-remove-scroll@2.5.7, react-remove-scroll@^2.5.6: +react-remove-scroll@2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz#15a1fd038e8497f65a695bf26a4a57970cac1ccb" integrity sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA== @@ -13838,18 +12738,17 @@ store2@^2.14.2: resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.4.tgz#81b313abaddade4dcd7570c5cc0e3264a8f7a242" integrity sha512-srTItn1GOvyvOycgxjAnPA63FZNwy0PTyUBFMHRM+hVFltAeoh0LmNBz9SZqUS9mMqGk8rfyWyXn3GH5ReJ8Zw== -storybook-i18n@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/storybook-i18n/-/storybook-i18n-3.0.1.tgz#9320f6e091deb006c6db2e4ce632cccff8429047" - integrity sha512-euCfw6ABqq8jSZ4fCaAIsNwk1FBIrSIr4kMP900bjUgO/mGgzZzXmrYmZaXs51mx9A2p87xo0OktPPZUuKYCTQ== - -storybook-react-i18next@3.1.1: +storybook-i18n@3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/storybook-react-i18next/-/storybook-react-i18next-3.1.1.tgz#f602b9aacca4a9b73e8d68c45fe6d73454b762e8" - integrity sha512-myMs1r2Ng4JFna3QiaY590VFTg6/gzRURwJGL95mPcS8bNA5g98Jn74Bs9lJKdltN7D+J01Z0boHM3lMQZB7nA== + resolved "https://registry.yarnpkg.com/storybook-i18n/-/storybook-i18n-3.1.1.tgz#d75f84d62682a76d58586534719a7f5042b82cb9" + integrity sha512-k1/lS+Rx6l5mJEYAHQWEgXuwU5IyWk7kjcJtm2FDIn1UqZwbEraGlrp/fEZKK2e/7+SXEQdKeCaTz7+63WTQxw== + +storybook-next-intl@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/storybook-next-intl/-/storybook-next-intl-1.2.5.tgz#0c710eb8ba592ff1a3df4f3983d864c21540c429" + integrity sha512-YiI6tBHFNF/dU/uVfaXX+tzpbe/MhLD9YMvbn4vdn/t0UQ7yOJl9AFNHhsqhP5FMmIIDrXSr/WCRbLeJCnKq0A== dependencies: - "@storybook/test" "^8.0.10" - storybook-i18n "^3.0.1" + storybook-i18n "3.1.1" storybook@8.1.10: version "8.1.10" @@ -14358,7 +13257,7 @@ timers-browserify@^2.0.12: dependencies: setimmediate "^1.0.4" -tiny-invariant@^1.0.6, tiny-invariant@^1.3.1: +tiny-invariant@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== @@ -14395,11 +13294,6 @@ tocbot@^4.20.1: resolved "https://registry.yarnpkg.com/tocbot/-/tocbot-4.25.0.tgz#bc38aea5ec8f076779bb39636f431b044129a237" integrity sha512-kE5wyCQJ40hqUaRVkyQ4z5+4juzYsv/eK+aqD97N62YH0TxFhzJvo22RUQQZdO3YnXAk42ZOfOpjVdy+Z0YokA== -toggle-selection@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" - integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== - toidentifier@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" @@ -14502,10 +13396,10 @@ tsconfig-paths@^4.0.0, tsconfig-paths@^4.1.2, tsconfig-paths@^4.2.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +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.13.0, tslib@^1.8.1: version "1.14.1" @@ -14907,6 +13801,14 @@ use-callback-ref@^1.3.0: dependencies: tslib "^2.0.0" +use-intl@^3.26.4: + version "3.26.4" + resolved "https://registry.yarnpkg.com/use-intl/-/use-intl-3.26.4.tgz#ec05127ea7f32fb0d3ac46614423d4c8d8576326" + integrity sha512-5DhN+YfsocNO7LiLpns7/pxRcMHA4DgBZQo5Z6uw3LvX9XIZyPAdRBdFPE2eBKTAwhY77k5eBhxqDtx8wzUaBg== + dependencies: + "@formatjs/fast-memoize" "^2.2.0" + intl-messageformat "^10.5.14" + use-isomorphic-layout-effect@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" @@ -15059,11 +13961,6 @@ vm-browserify@^1.1.2: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -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== - watchpack@^2.2.0, watchpack@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.1.tgz#29308f2cac150fa8e4c92f90e0ec954a9fed7fff"