diff --git a/packages/common-components/src/Icons/icons/External.icon.tsx b/packages/common-components/src/Icons/icons/External.icon.tsx new file mode 100644 index 0000000000..6e14881102 --- /dev/null +++ b/packages/common-components/src/Icons/icons/External.icon.tsx @@ -0,0 +1,7 @@ +import * as React from "react" +import createSvgIcon from "../createSvgIcon" +import { ReactComponent as ExternalSvg } from "../svgs/external.svg" + +export { ExternalSvg } + +export default createSvgIcon() diff --git a/packages/common-components/src/Icons/index.ts b/packages/common-components/src/Icons/index.ts index 53ed037c95..410cd3113b 100644 --- a/packages/common-components/src/Icons/index.ts +++ b/packages/common-components/src/Icons/index.ts @@ -31,6 +31,7 @@ export { default as EthereumLogoIcon, EthereumLogoSvg } from "./icons/EthereumLo export { default as ExclamationCircleIcon, ExclamationCircleSvg } from "./icons/ExclamationCircle.icon" export { default as ExclamationCircleInverseIcon, ExclamationCircleInverseSvg } from "./icons/ExclamationCircleInverse.icon" export { default as ExportIcon, ExportSvg } from "./icons/Export.icon" +export { default as ExternalIcon, ExternalSvg } from "./icons/External.icon" export { default as EyeClosedIcon, EyeClosedSvg } from "./icons/EyeClosed.icon" export { default as EyeIcon, EyeSvg } from "./icons/Eye.icon" export { default as EyeOpenIcon, EyeOpenSvg } from "./icons/EyeOpen.icon" diff --git a/packages/common-components/src/Icons/svgs/external.svg b/packages/common-components/src/Icons/svgs/external.svg new file mode 100644 index 0000000000..493a90748b --- /dev/null +++ b/packages/common-components/src/Icons/svgs/external.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/common-components/src/ToggleSwitch/FormikToggleSwitch.tsx b/packages/common-components/src/ToggleSwitch/FormikToggleSwitch.tsx new file mode 100644 index 0000000000..21fa4c4e5f --- /dev/null +++ b/packages/common-components/src/ToggleSwitch/FormikToggleSwitch.tsx @@ -0,0 +1,28 @@ +import { useField } from "formik" +import React from "react" +import { IToggleSwitch, ToggleSwitch } from "." + + +interface IFormikToggleSwitch extends IToggleSwitch { + name: string +} + +const FormikToggleSwitch = ({ injectedClasses, disabled, name, left, right, size }: IFormikToggleSwitch) => { + const [field, meta, helpers] = useField(name) + const handleChange = (value: any) => { + helpers.setValue(value) + } + + return +} + +export default FormikToggleSwitch diff --git a/packages/common-components/src/ToggleSwitch/ToggleSwitch.tsx b/packages/common-components/src/ToggleSwitch/ToggleSwitch.tsx new file mode 100644 index 0000000000..147272f1d1 --- /dev/null +++ b/packages/common-components/src/ToggleSwitch/ToggleSwitch.tsx @@ -0,0 +1,174 @@ +import { createStyles, ITheme, makeStyles } from "@chainsafe/common-theme" +import clsx from "clsx" +import React, { ReactNode, useCallback, useMemo, useState } from "react" +import { Typography } from "../Typography" + +interface IStyleProps { + size: number +} + +const SIZES = { + small: 14, + medium: 16, + large: 20 +} + +const PADDING = 2 + +const useStyles = makeStyles( + ({ animation, breakpoints, constants, overrides, palette }: ITheme) => + createStyles({ + root : { + padding: `${constants.generalUnit}px 0`, + display: "flex", + flexDirection: "row", + justifyContent: "flex-start", + alignItems: "center", + cursor: "pointer", + "&.disabled": { + cursor: "initial" + }, + [breakpoints.down("md")]: { + marginBottom: 0 + }, + ...overrides?.Tabs?.root + }, + label: { + marginRight: constants.generalUnit, + ...overrides?.ToggleSwitch?.label + }, + background: ({ size }: IStyleProps) => ({ + boxSizing: "border-box", + display: "block", + position: "relative", + backgroundColor: palette.additional.gray[6], + borderRadius: size, + padding: PADDING, + height: size, + width: `calc(${size * 2}px - ${PADDING * 2}px)`, + transitionDuration: `${animation.transform}ms`, + ...overrides?.ToggleSwitch?.background + }), + dot: ({ size }: IStyleProps) => ({ + display: "block", + position: "absolute", + borderRadius: "100%", + height: `calc(${size}px - ${PADDING * 2}px)`, + width: `calc(${size}px - ${PADDING * 2}px)`, + backgroundColor: palette.additional.gray[1], + transitionDuration: `${animation.transform}ms`, + top: "50%", + transform: "translateY(-50%)", + "&.left": { + left: PADDING + }, + "&.right": { + left: "50%" + }, + "&.error": { + backgroundColor: palette.error.main + }, + ...overrides?.ToggleSwitch?.dot + }) + }) +) + +interface ToggleSwitchInjectedClasses { + root?: string + label?: string + background?: string + dot?: string +} + +// Could allow for a slider to be made from this +interface IToggleOption { + value: any + label?: string | ReactNode | number +} + +interface IToggleSwitch { + left: IToggleOption + right: IToggleOption + onChange(value: any): void + injectedClasses?: ToggleSwitchInjectedClasses + size?: "large" | "medium" | "small" | number + error?: string + disabled?: boolean + value?: any + // name?: string +} + +const ToggleSwitch = ({ injectedClasses, disabled, left, right, onChange, value, size, error }: IToggleSwitch) => { + const resolvedSize = useMemo(() => { + switch (size) { + case "large": + return SIZES.large + case "medium": + return SIZES.medium + case "small": + return SIZES.small + case undefined: + return SIZES.medium + default: + return size + } + }, [size]) + const classes = useStyles({ size: resolvedSize }) + const [side, setSide] = useState<"left" | "right">(value && right.value === value ? "right" : "left") + + const onToggle = useCallback(() => { + if (disabled) return + if (side === "left") { + setSide("right") + onChange(right.value) + } else { + setSide("left") + onChange(left.value) + } + }, [left, right, side, onChange, disabled]) + + return
+ { + side === "left" && left.label && ( + + { left.label } + + ) + } + { + side === "right" && right.label && ( + + { right.label } + + ) + } +
+
+
+
+
+} + +export default ToggleSwitch +export { IToggleSwitch, IToggleOption, ToggleSwitchInjectedClasses } diff --git a/packages/common-components/src/ToggleSwitch/index.tsx b/packages/common-components/src/ToggleSwitch/index.tsx new file mode 100644 index 0000000000..0bd778f9e6 --- /dev/null +++ b/packages/common-components/src/ToggleSwitch/index.tsx @@ -0,0 +1,6 @@ +export { + default as ToggleSwitch, + IToggleOption, + IToggleSwitch, + ToggleSwitchInjectedClasses +} from "./ToggleSwitch" diff --git a/packages/common-components/src/index.ts b/packages/common-components/src/index.ts index a6d8a17044..561e07dde4 100644 --- a/packages/common-components/src/index.ts +++ b/packages/common-components/src/index.ts @@ -34,6 +34,7 @@ export * from "./Tabs" export * from "./TagsInput" export * from "./Toasts" export * from "./ToggleHiddenText" +export * from "./ToggleSwitch" export * from "./TextInput" export * from "./TreeView" export * from "./Typography" diff --git a/packages/common-components/src/stories/ToggleSwitch.stories.tsx b/packages/common-components/src/stories/ToggleSwitch.stories.tsx new file mode 100644 index 0000000000..fae5dd6ad4 --- /dev/null +++ b/packages/common-components/src/stories/ToggleSwitch.stories.tsx @@ -0,0 +1,41 @@ +import { action } from "@storybook/addon-actions" +import { boolean, select, withKnobs } from "@storybook/addon-knobs" +import React, { useState } from "react" +import { ToggleSwitch } from ".." +import { SizeOption } from "./types" + +export default { + title: "ToggleSwitch", + component: ToggleSwitch, + excludeStories: /.*Data$/, + decorators: [withKnobs] +} + +const sizeOptions: SizeOption[] = ["large", "medium", "small"] + +const actionsData = { + onChange: action("onChange") +} + +export const ToggleSwitchDemo = (): React.ReactNode => { + const [state, setState] = useState(false) + return ( + { + setState(value) + actionsData.onChange(value) + }} + disabled={boolean("Disabled", false)} + size={select("Size", sizeOptions, "medium")} + /> + ) +} diff --git a/packages/common-theme/src/Overrides/ToggleSwitch.ts b/packages/common-theme/src/Overrides/ToggleSwitch.ts new file mode 100644 index 0000000000..73c8f7a798 --- /dev/null +++ b/packages/common-theme/src/Overrides/ToggleSwitch.ts @@ -0,0 +1,6 @@ +export interface IToggleSwitchOverride { + root?: Record + label?: Record + background?: Record + dot?: Record +} diff --git a/packages/common-theme/src/Overrides/index.ts b/packages/common-theme/src/Overrides/index.ts index e56d61266b..68749a6e2d 100644 --- a/packages/common-theme/src/Overrides/index.ts +++ b/packages/common-theme/src/Overrides/index.ts @@ -25,6 +25,7 @@ import { IToastsOverride } from "./Toasts" import { ITypographyOverride } from "./Typography" import { ITagsInputOverride } from "./TagsInput" import { IToggleHiddenText } from "./ToggleHiddenText" +import { IToggleSwitchOverride } from "./ToggleSwitch" export interface IComponentOverrides { Avatar?: IAvatarOverride @@ -52,6 +53,7 @@ export interface IComponentOverrides { TextInput?: ITextInputOverride Toasts?: IToastsOverride ToggleHiddenText?: IToggleHiddenText + ToggleSwitch?: IToggleSwitchOverride Typography?: ITypographyOverride TagsInput?: ITagsInputOverride } diff --git a/packages/files-ui/src/Components/FilesRoutes.tsx b/packages/files-ui/src/Components/FilesRoutes.tsx index eae68e19f4..34e79afadb 100644 --- a/packages/files-ui/src/Components/FilesRoutes.tsx +++ b/packages/files-ui/src/Components/FilesRoutes.tsx @@ -9,7 +9,6 @@ import BinPage from "./Pages/BinPage" import { useThresholdKey } from "../Contexts/ThresholdKeyContext" import ShareFilesPage from "./Pages/SharedFilesPage" import SharedFoldersOverview from "./Modules/FileBrowsers/SharedFoldersOverview" -import PlansPage from "./Pages/PlansPage" import BillingHistory from "./Pages/BillingHistory" import { NonceResponsePermission } from "@chainsafe/files-api-client" import LinkSharingLanding from "./Pages/LinkSharingLanding" @@ -116,13 +115,6 @@ const FilesRoutes = () => { component={SettingsPage} redirectPath={ROUTE_LINKS.Landing} /> - + createStyles({ + root: { + }, + inner: { + borderRadius: `${constants.generalUnit / 2}px` + }, + slide: { + borderRadius: constants.generalUnit / 2, + padding: `0 ${constants.generalUnit * 3}px` + } + }) +) + +interface IChangeProductModal { + className?: string + close: () => void +} + +const ChangeProductModal = ({ className, close }: IChangeProductModal) => { + const classes = useStyles() + const { changeSubscription } = useBilling() + const [slide, setSlide] = useState<"select" | "confirm">("select") + + useEffect(() => { + if (slide !== "select") { + setSlide("select") + } + }, [slide]) + + return ( + + { + slide === "select" && { + // setSlide("confirm") + changeSubscription(newpriceId) + .then(() => close()) + .catch(console.error) + }} + /> + } + + ) +} + +export default ChangeProductModal \ No newline at end of file diff --git a/packages/files-ui/src/Components/Modules/Settings/Products/ChangeProductViews/SelectPlan.tsx b/packages/files-ui/src/Components/Modules/Settings/Products/ChangeProductViews/SelectPlan.tsx new file mode 100644 index 0000000000..86842560f3 --- /dev/null +++ b/packages/files-ui/src/Components/Modules/Settings/Products/ChangeProductViews/SelectPlan.tsx @@ -0,0 +1,270 @@ +import React, { useEffect, useMemo, useState } from "react" +import { makeStyles, createStyles } from "@chainsafe/common-theme" +import clsx from "clsx" +import { Button, ExternalSvg, Loading, ToggleSwitch, Typography } from "@chainsafe/common-components" +import { t, Trans } from "@lingui/macro" +import { CSFTheme } from "../../../../../Themes/types" +import { useBilling } from "../../../../../Contexts/BillingContext" +import { Product, ProductPriceRecurringInterval } from "@chainsafe/files-api-client" + +const useStyles = makeStyles(({ breakpoints, constants, palette, typography }: CSFTheme) => + createStyles({ + root: { + margin: `${constants.generalUnit * 2}px 0px` + }, + header: { + display: "flex", + flexDirection: "row", + alignItems: "center", + justifyContent: "space-between" + }, + label: { + ...typography.h5 + }, + panels: { + display: "flex", + flexDirection: "row", + flexWrap: "wrap", + justifyContent: "space-between", + margin: `${constants.generalUnit * 3.5}px 0` + }, + panel: { + display: "flex", + flexDirection: "column", + padding: `${constants.generalUnit}px ${constants.generalUnit * 3}px`, + width: `calc(33.3333% - ${constants.generalUnit * 2}px)`, + minHeight: 200, + cursor: "pointer", + border: `3px solid ${palette.additional.gray[4]}`, + borderRadius: constants.generalUnit, + marginBottom: constants.generalUnit, + "&.active": { + opacity: "1 !important", + backgroundColor: constants.changeProduct.currentBackground, + borderColor: constants.changeProduct.selectedColor + }, + [breakpoints.down("sm")]: { + width: `calc(50% - ${constants.generalUnit}px)` + } + }, + loader: { + margin: "0 auto" + }, + panelTop: { + height: "60%", + "& > header": { + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + marginBottom: constants.generalUnit + } + }, + tag: { + display: "block", + padding: `0 ${constants.generalUnit}px`, + borderRadius: `${constants.generalUnit * 2}px`, + height: 20, + "&.current": { + backgroundColor: palette.primary.main, + color: constants.changeProduct.currentTag.text + }, + "&.popular": { + backgroundColor: palette.additional.gold[5] + } + }, + panelBottom: { + height: "40%" + }, + link: { + display: "flex", + justifyContent: "flex-start", + alignItems: "center", + "& svg": { + marginLeft: constants.generalUnit, + stroke: palette.additional.gray[10], + width: constants.generalUnit * 2, + height: constants.generalUnit * 2 + } + }, + buttons: { + display: "flex", + flexDirection: "row", + alignItems: "center", + justifyContent: "flex-end", + "& > *": { + marginLeft: constants.generalUnit + } + }, + bottomSection: { + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center" + } + }) +) + +interface ISelectPlan { + className?: string + close: () => void + next: (newPriceId: string) => void +} + +const SelectPlan = ({ close, className, next }: ISelectPlan) => { + const classes = useStyles() + const { getAvailablePlans, currentSubscription } = useBilling() + const [selectedPlan, setSelectedPlan] = useState(currentSubscription?.product.id) + const [plans, setPlans] = useState() + const [interval, setInterval] = useState("month") + + useEffect(() => { + if(!plans) { + getAvailablePlans() + .then((plans) => setPlans(plans)) + .catch(console.error) + } + }) + + const selectedPrice = useMemo(() => { + return plans?.find(plan => plan.id === selectedPlan)?.prices.find(price => price.recurring.interval === interval)?.id + }, [selectedPlan, plans, interval]) + + const translatedPrice = useMemo(() => { + switch (interval) { + case "day": + return t`per day` + case "week": + return t`per week` + case "month": + return t`per month` + case "year": + return t`per year` + } + }, [interval]) + + return ( +
+
+ + + Switch Plans + + +
+ setInterval(value)} + size="medium" + /> +
+
+
+ {!plans && } + {plans && plans.map((plan) => ( +
setSelectedPlan(plan.id) } + key={`plan-${plan.id}`} + > +
+
+ + {plan.name} + + {plan.id === currentSubscription?.product.id && ( + + + Current + + + )} +
+ + { + plan.description + } + +
+
+ {plan.prices + .filter(price => price.recurring.interval === interval) + .map(price => ( + + {price.unit_amount === 0 ? t`Free` : `${price.unit_amount} ${price.currency} ${translatedPrice}`} + + ))} +
+
+ )) + } +
+
+ + + + Not sure what to pick? Learn more about our plans + + + + +
+ + +
+
+
+ ) +} + +export default SelectPlan \ No newline at end of file diff --git a/packages/files-ui/src/Components/Modules/Settings/SubscriptionTab/CurrentProduct.tsx b/packages/files-ui/src/Components/Modules/Settings/SubscriptionTab/CurrentProduct.tsx index ead2f3e880..9529631d5f 100644 --- a/packages/files-ui/src/Components/Modules/Settings/SubscriptionTab/CurrentProduct.tsx +++ b/packages/files-ui/src/Components/Modules/Settings/SubscriptionTab/CurrentProduct.tsx @@ -1,18 +1,17 @@ -import React from "react" +import React, { useState } from "react" import { Button, formatBytes, - Link, Loading, ProgressBar, Typography } from "@chainsafe/common-components" import { makeStyles, ITheme, createStyles } from "@chainsafe/common-theme" -import { ROUTE_LINKS } from "../../../FilesRoutes" import { useFiles } from "../../../../Contexts/FilesContext" import { t, Trans } from "@lingui/macro" import clsx from "clsx" import { useBilling } from "../../../../Contexts/BillingContext" +import ChangeProductModal from "../Products/ChangeProductModal" const useStyles = makeStyles(({ breakpoints, constants }: ITheme) => createStyles({ @@ -62,6 +61,7 @@ const CurrentProduct = ({ className }: ICurrentProduct) => { const classes = useStyles() const { storageSummary } = useFiles() const { currentSubscription } = useBilling() + const [isChangeProductModalVisible, setChangeProductModalVisible] = useState(false) return (
{ />
- setChangeProductModalVisible(true)} > - - + Change Plan +
+ { + isChangeProductModalVisible && ( setChangeProductModalVisible(false)} + />) + } } diff --git a/packages/files-ui/src/Components/Pages/PlansPage.tsx b/packages/files-ui/src/Components/Pages/PlansPage.tsx deleted file mode 100644 index f24f740b83..0000000000 --- a/packages/files-ui/src/Components/Pages/PlansPage.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from "react" -import Products from "../Modules/Settings/Products/Products" - -const PlansPage = () => { - return -} - -export default PlansPage diff --git a/packages/files-ui/src/Contexts/BillingContext.tsx b/packages/files-ui/src/Contexts/BillingContext.tsx index 8e683680ae..7cd1adbef9 100644 --- a/packages/files-ui/src/Contexts/BillingContext.tsx +++ b/packages/files-ui/src/Contexts/BillingContext.tsx @@ -1,7 +1,7 @@ import * as React from "react" import { useFilesApi } from "./FilesApiContext" import { ReactNode, useEffect, useState } from "react" -import { Card, CurrentSubscription } from "@chainsafe/files-api-client" +import { Card, CurrentSubscription, Product } from "@chainsafe/files-api-client" import { useCallback } from "react" import { t } from "@lingui/macro" @@ -13,7 +13,9 @@ interface IBillingContext { defaultCard: Card | undefined refreshDefaultCard: () => void currentSubscription: CurrentSubscription | undefined + changeSubscription: (newPriceId: string) => Promise fetchCurrentSubscription: () => void + getAvailablePlans: () => Promise } const ProductMapping: {[key: string]: { @@ -78,13 +80,39 @@ const BillingProvider = ({ children }: BillingContextProps) => { } }, [isLoggedIn, fetchCurrentSubscription, currentSubscription]) + const getAvailablePlans = useCallback(() => { + return filesApiClient.getAllProducts() + .then((products) => { + return products.map(product => { + product.name = ProductMapping[product.id].name + product.description = ProductMapping[product.id].description + return product + }) + }) + .catch((error: any) => { + console.error(error) + return [] + }) + }, [filesApiClient]) + + const changeSubscription = useCallback((newPriceId: string) => { + if (!currentSubscription?.id) return Promise.resolve() + return filesApiClient.updateSubscription(currentSubscription.id, { + price_id: newPriceId + }) + .then(() => true) + .catch(console.error) + }, [filesApiClient, currentSubscription]) + return ( {children} diff --git a/packages/files-ui/src/Themes/Constants.ts b/packages/files-ui/src/Themes/Constants.ts index bbb0dcc7ff..5ca6a1e648 100644 --- a/packages/files-ui/src/Themes/Constants.ts +++ b/packages/files-ui/src/Themes/Constants.ts @@ -176,4 +176,11 @@ export interface CsfColors extends IConstants { cookieBanner: { backgroundColor: string } + changeProduct: { + currentBackground: string + selectedColor: string + currentTag: { + text: string + } + } } \ No newline at end of file diff --git a/packages/files-ui/src/Themes/DarkTheme.ts b/packages/files-ui/src/Themes/DarkTheme.ts index 30ddf80969..e3595b853b 100644 --- a/packages/files-ui/src/Themes/DarkTheme.ts +++ b/packages/files-ui/src/Themes/DarkTheme.ts @@ -487,6 +487,13 @@ export const darkTheme = createTheme({ }, cookieBanner: { backgroundColor: "var(--gray9)" + }, + changeProduct: { + currentBackground: "initial", + selectedColor: "var(--csf-primary)", + currentTag: { + text: "var(--gray10)" + } } } as CsfColors) }, diff --git a/packages/files-ui/src/Themes/LightTheme.ts b/packages/files-ui/src/Themes/LightTheme.ts index d410224daf..24c30df245 100644 --- a/packages/files-ui/src/Themes/LightTheme.ts +++ b/packages/files-ui/src/Themes/LightTheme.ts @@ -174,6 +174,13 @@ export const lightTheme = createTheme({ }, cookieBanner: { backgroundColor: "var(--csf-primary)" + }, + changeProduct: { + currentBackground: "#ECEFFF", + selectedColor: "var(--csf-primary)", + currentTag: { + text: "var(--gray1)" + } } } as CsfColors) }, diff --git a/packages/files-ui/src/locales/de/messages.po b/packages/files-ui/src/locales/de/messages.po index 247c27f07d..e9aa28ce22 100644 --- a/packages/files-ui/src/locales/de/messages.po +++ b/packages/files-ui/src/locales/de/messages.po @@ -73,6 +73,9 @@ msgstr "Sicherungsgeheimsatz" msgid "Backup secret phrase does not match user account, please double-check and try again." msgstr "Der Sicherungsgeheimsatz stimmt nicht mit dem Benutzerkonto überein, bitte überprüfen Sie dies und versuchen Sie es erneut." +msgid "Billed Annually" +msgstr "" + msgid "Billed Monthly" msgstr "" @@ -208,6 +211,9 @@ msgstr "" msgid "Credit card saved" msgstr "" +msgid "Current" +msgstr "" + msgid "Dark Theme" msgstr "Dunkles Farbschema" @@ -343,6 +349,9 @@ msgstr "Aus Sicherheitsgründen werden wir Sie bei jeder Anmeldung nach einer de msgid "Forget this browser" msgstr "Diesen Browser vergessen" +msgid "Free" +msgstr "" + msgid "Free plan" msgstr "" @@ -505,6 +514,9 @@ msgstr "Nein danke" msgid "No user found for this query." msgstr "" +msgid "Not sure what to pick? Learn more about our plans" +msgstr "" + msgid "Number of copies (Replication Factor)" msgstr "Anzahl der Kopien (Replikationsfaktor)" @@ -676,6 +688,9 @@ msgstr "" msgid "Select an existing shared folder or your home" msgstr "" +msgid "Select this plan" +msgstr "" + msgid "Send another email" msgstr "Andere E-Mail senden" @@ -772,6 +787,9 @@ msgstr "" msgid "Subscription Plan" msgstr "" +msgid "Switch Plans" +msgstr "" + msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." msgstr "" @@ -988,6 +1006,18 @@ msgstr "ich" msgid "on" msgstr "am" +msgid "per day" +msgstr "" + +msgid "per month" +msgstr "" + +msgid "per week" +msgstr "" + +msgid "per year" +msgstr "" + msgid "read rights" msgstr "" diff --git a/packages/files-ui/src/locales/en/messages.po b/packages/files-ui/src/locales/en/messages.po index 7c1c163a1f..87d0367081 100644 --- a/packages/files-ui/src/locales/en/messages.po +++ b/packages/files-ui/src/locales/en/messages.po @@ -73,6 +73,9 @@ msgstr "Backup secret phrase" msgid "Backup secret phrase does not match user account, please double-check and try again." msgstr "Backup secret phrase does not match user account, please double-check and try again." +msgid "Billed Annually" +msgstr "Billed Annually" + msgid "Billed Monthly" msgstr "Billed Monthly" @@ -208,6 +211,9 @@ msgstr "Create your public username in <0>Settings!" msgid "Credit card saved" msgstr "Credit card saved" +msgid "Current" +msgstr "Current" + msgid "Dark Theme" msgstr "Dark Theme" @@ -346,6 +352,9 @@ msgstr "For security reasons, each time you sign in we’ll ask you for one of t msgid "Forget this browser" msgstr "Forget this browser" +msgid "Free" +msgstr "Free" + msgid "Free plan" msgstr "Free plan" @@ -508,6 +517,9 @@ msgstr "No thanks" msgid "No user found for this query." msgstr "No user found for this query." +msgid "Not sure what to pick? Learn more about our plans" +msgstr "Not sure what to pick? Learn more about our plans" + msgid "Number of copies (Replication Factor)" msgstr "Number of copies (Replication Factor)" @@ -679,6 +691,9 @@ msgstr "Select a wallet" msgid "Select an existing shared folder or your home" msgstr "Select an existing shared folder or your home" +msgid "Select this plan" +msgstr "Select this plan" + msgid "Send another email" msgstr "Send another email" @@ -775,6 +790,9 @@ msgstr "Stored by miner" msgid "Subscription Plan" msgstr "Subscription Plan" +msgid "Switch Plans" +msgstr "Switch Plans" + msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." msgstr "System maintenance is scheduled to start at {0}. The system will be unavailable." @@ -991,6 +1009,18 @@ msgstr "me" msgid "on" msgstr "on" +msgid "per day" +msgstr "per day" + +msgid "per month" +msgstr "per month" + +msgid "per week" +msgstr "per week" + +msgid "per year" +msgstr "per year" + msgid "read rights" msgstr "read rights" diff --git a/packages/files-ui/src/locales/es/messages.po b/packages/files-ui/src/locales/es/messages.po index a8c415a1da..ae198a6697 100644 --- a/packages/files-ui/src/locales/es/messages.po +++ b/packages/files-ui/src/locales/es/messages.po @@ -74,6 +74,9 @@ msgstr "" msgid "Backup secret phrase does not match user account, please double-check and try again." msgstr "" +msgid "Billed Annually" +msgstr "" + msgid "Billed Monthly" msgstr "" @@ -209,6 +212,9 @@ msgstr "" msgid "Credit card saved" msgstr "" +msgid "Current" +msgstr "" + msgid "Dark Theme" msgstr "Tema oscuro" @@ -347,6 +353,9 @@ msgstr "Por motivos de seguridad, cada vez que inicie sesión le pediremos uno d msgid "Forget this browser" msgstr "Olvida este navegador" +msgid "Free" +msgstr "" + msgid "Free plan" msgstr "" @@ -509,6 +518,9 @@ msgstr "No gracias" msgid "No user found for this query." msgstr "" +msgid "Not sure what to pick? Learn more about our plans" +msgstr "" + msgid "Number of copies (Replication Factor)" msgstr "Número de copias (factor de replicación)" @@ -680,6 +692,9 @@ msgstr "Seleccione una billetera" msgid "Select an existing shared folder or your home" msgstr "" +msgid "Select this plan" +msgstr "" + msgid "Send another email" msgstr "" @@ -776,6 +791,9 @@ msgstr "Almacenado por el minero" msgid "Subscription Plan" msgstr "" +msgid "Switch Plans" +msgstr "" + msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." msgstr "" @@ -992,6 +1010,18 @@ msgstr "" msgid "on" msgstr "en" +msgid "per day" +msgstr "" + +msgid "per month" +msgstr "" + +msgid "per week" +msgstr "" + +msgid "per year" +msgstr "" + msgid "read rights" msgstr "" diff --git a/packages/files-ui/src/locales/fr/messages.po b/packages/files-ui/src/locales/fr/messages.po index c93560d099..71d2681c90 100644 --- a/packages/files-ui/src/locales/fr/messages.po +++ b/packages/files-ui/src/locales/fr/messages.po @@ -74,6 +74,9 @@ msgstr "Phrase secrète de sauvegarde" msgid "Backup secret phrase does not match user account, please double-check and try again." msgstr "La phrase secrète de sauvegarde est incorrecte, merci de vérifier et réessayer." +msgid "Billed Annually" +msgstr "" + msgid "Billed Monthly" msgstr "" @@ -209,6 +212,9 @@ msgstr "Créez votre nom d'utilisateur public dans <0>Paramètres !" msgid "Credit card saved" msgstr "" +msgid "Current" +msgstr "" + msgid "Dark Theme" msgstr "Thème sombre" @@ -347,6 +353,9 @@ msgstr "Pour des raisons de sécurité, chaque fois que vous vous connectez, nou msgid "Forget this browser" msgstr "Oublier ce navigateur" +msgid "Free" +msgstr "" + msgid "Free plan" msgstr "" @@ -509,6 +518,9 @@ msgstr "Non merci" msgid "No user found for this query." msgstr "Aucun utilisateur n'a été trouvé pour cette requête." +msgid "Not sure what to pick? Learn more about our plans" +msgstr "" + msgid "Number of copies (Replication Factor)" msgstr "Nombre de copies (facteur de réplication)" @@ -680,6 +692,9 @@ msgstr "Sélectionner un wallet" msgid "Select an existing shared folder or your home" msgstr "Sélectionnez un dossier partagé existant ou votre page d'accueil" +msgid "Select this plan" +msgstr "" + msgid "Send another email" msgstr "Envoyer un nouveau courriel" @@ -776,6 +791,9 @@ msgstr "Sauvegardé par le mineur" msgid "Subscription Plan" msgstr "" +msgid "Switch Plans" +msgstr "" + msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." msgstr "Une maintenance du système est prévue pour démarrer à {0}. Le système sera indisponible." @@ -992,6 +1010,18 @@ msgstr "moi" msgid "on" msgstr "le" +msgid "per day" +msgstr "" + +msgid "per month" +msgstr "" + +msgid "per week" +msgstr "" + +msgid "per year" +msgstr "" + msgid "read rights" msgstr "droits de lecture" diff --git a/packages/files-ui/src/locales/no/messages.po b/packages/files-ui/src/locales/no/messages.po index e41b1f574c..181aa2fac7 100644 --- a/packages/files-ui/src/locales/no/messages.po +++ b/packages/files-ui/src/locales/no/messages.po @@ -73,6 +73,9 @@ msgstr "" msgid "Backup secret phrase does not match user account, please double-check and try again." msgstr "" +msgid "Billed Annually" +msgstr "" + msgid "Billed Monthly" msgstr "" @@ -208,6 +211,9 @@ msgstr "" msgid "Credit card saved" msgstr "" +msgid "Current" +msgstr "" + msgid "Dark Theme" msgstr "Mørk drakt" @@ -343,6 +349,9 @@ msgstr "" msgid "Forget this browser" msgstr "" +msgid "Free" +msgstr "" + msgid "Free plan" msgstr "" @@ -505,6 +514,9 @@ msgstr "Nei takk" msgid "No user found for this query." msgstr "" +msgid "Not sure what to pick? Learn more about our plans" +msgstr "" + msgid "Number of copies (Replication Factor)" msgstr "" @@ -676,6 +688,9 @@ msgstr "" msgid "Select an existing shared folder or your home" msgstr "" +msgid "Select this plan" +msgstr "" + msgid "Send another email" msgstr "Send en ny e-post" @@ -772,6 +787,9 @@ msgstr "" msgid "Subscription Plan" msgstr "" +msgid "Switch Plans" +msgstr "" + msgid "System maintenance is scheduled to start at {0}. The system will be unavailable." msgstr "" @@ -988,6 +1006,18 @@ msgstr "" msgid "on" msgstr "" +msgid "per day" +msgstr "" + +msgid "per month" +msgstr "" + +msgid "per week" +msgstr "" + +msgid "per year" +msgstr "" + msgid "read rights" msgstr "" diff --git a/yarn.lock b/yarn.lock index 820f705ea9..53bd35cc85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1934,6 +1934,15 @@ "@redocly/openapi-core" "^1.0.0-beta.58" redoc-cli "^0.12.3" +"@chainsafe/files-api-client@^1.18.18": + version "1.18.18" + resolved "https://registry.yarnpkg.com/@chainsafe/files-api-client/-/files-api-client-1.18.18.tgz#1fc8e7fe2a657d95a8aec8e1e7d69b0c1e2a9a38" + integrity sha512-MkMsEUebgsY/7RtWQU3WMcVKa0xuj9nq/6V87P5YiQ3B7cxqOyFZsmsU3u2dVS15crBWXcEiey0LUUDrvbVNOg== + dependencies: + "@redocly/openapi-cli" "^1.0.0-beta.58" + "@redocly/openapi-core" "^1.0.0-beta.58" + redoc-cli "^0.12.3" + "@chainsafe/web3-context@1.1.4": version "1.1.4" resolved "https://registry.yarnpkg.com/@chainsafe/web3-context/-/web3-context-1.1.4.tgz#ce0f140af8ccf93af1a189fbdbd6f018b9bf5fb7"