Web: Added payments page.
This commit is contained in:
parent
b6559781ea
commit
12a83327b0
3
packages/client/public/images/minus.react.svg
Normal file
3
packages/client/public/images/minus.react.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="17" height="2" viewBox="0 0 17 2" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16.5 6.99382e-07L16.5 2L0.5 2L0.5 0L16.5 6.99382e-07Z" fill="#333333"/>
|
||||
</svg>
|
After Width: | Height: | Size: 183 B |
3
packages/client/public/images/plus.react.svg
Normal file
3
packages/client/public/images/plus.react.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.5 0H7.5V7H0.5V9H7.5V16H9.5V9H16.5V7H9.5V0Z" fill="#333333"/>
|
||||
</svg>
|
After Width: | Height: | Size: 216 B |
20
packages/client/public/locales/en/Payments.json
Normal file
20
packages/client/public/locales/en/Payments.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"AddedManagers": "Managers added",
|
||||
"StorageSpace": "Storage space used",
|
||||
"TariffsPlans": "Tariffs plans",
|
||||
"SuitablePlan": "Choose the plan that suits your team",
|
||||
"PerUserMonth": "per manager/month",
|
||||
"HaveQuestions": "Have questions?",
|
||||
"ContactUs": "For sales questions, contact us at",
|
||||
"ManagersNumber": "Number of managers",
|
||||
"StartPrice": "From {{price}} per manager/month",
|
||||
"RenewSubscription": "Renew subscription to {{organizationName}} Business cloud",
|
||||
"ReActivate": "Re-activate business plan?",
|
||||
"Benefits": "Benefits",
|
||||
"BusinessTitle": "You are using Business plan",
|
||||
"StartupTitle": "You are using free Startup plan",
|
||||
"PriceCalculation": "Calculate your price",
|
||||
"UpgradeNow": "Upgrade now",
|
||||
"StartupSuggestion": "Do more with Business plan",
|
||||
"BusinessSuggestion": "Customize your Business plan"
|
||||
}
|
@ -60,7 +60,7 @@ import DialogsWrapper from "./components/dialogs/DialogsWrapper";
|
||||
// "/preparation-portal"
|
||||
// );
|
||||
|
||||
const Payments = React.lazy(() => import("./pages/Payments"));
|
||||
const Payments = React.lazy(() => import("./pages/TariffsPage"));
|
||||
const Error404 = React.lazy(() => import("client/Error404"));
|
||||
const Error401 = React.lazy(() => import("client/Error401"));
|
||||
const Files = React.lazy(() => import("./pages/Files")); //import("./components/pages/Home"));
|
||||
|
70
packages/client/src/pages/TariffsPage/BenefitsContainer.js
Normal file
70
packages/client/src/pages/TariffsPage/BenefitsContainer.js
Normal file
@ -0,0 +1,70 @@
|
||||
import React, { useState } from "react";
|
||||
import styled from "styled-components";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import Text from "@docspace/components/text";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { smallTablet } from "@docspace/components/utils/device";
|
||||
|
||||
const StyledBody = styled.div`
|
||||
border-radius: 12px;
|
||||
border: 1px solid #f8f9f9;
|
||||
max-width: 320px;
|
||||
|
||||
@media ${smallTablet} {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
padding: 24px;
|
||||
box-sizing: border-box;
|
||||
background: #f8f9f9;
|
||||
|
||||
p {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.tariff-benefits_text {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.tariff-benefits {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
align-items: baseline;
|
||||
p {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const BenefitsContainer = ({ t, availableTariffs }) => {
|
||||
return (
|
||||
<StyledBody>
|
||||
<Text
|
||||
fontSize={"16px"}
|
||||
fontWeight={"600"}
|
||||
className="tariff-benefits_text"
|
||||
noSelect
|
||||
>
|
||||
{t("Benefits")}
|
||||
</Text>
|
||||
{availableTariffs.map((item, index) => {
|
||||
return (
|
||||
<div className="tariff-benefits" key={index}>
|
||||
<Text noSelect>{"*" + item}</Text>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</StyledBody>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ auth, payments }) => {
|
||||
const { tariffsInfo } = payments;
|
||||
|
||||
const availableTariffs = [
|
||||
"Unlimited number of users",
|
||||
"Unlimited number of active rooms",
|
||||
"100 GB per manager add space on request",
|
||||
"Automatic backup & recovery",
|
||||
"Tracking user logins & actions",
|
||||
];
|
||||
return { tariffsInfo, availableTariffs };
|
||||
})(observer(BenefitsContainer));
|
42
packages/client/src/pages/TariffsPage/ContactContainer.js
Normal file
42
packages/client/src/pages/TariffsPage/ContactContainer.js
Normal file
@ -0,0 +1,42 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { withRouter } from "react-router";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import Text from "@docspace/components/text";
|
||||
import Link from "@docspace/components/link";
|
||||
|
||||
const StyledContactContainer = styled.div`
|
||||
display: flex;
|
||||
width: max-content;
|
||||
p {
|
||||
margin-right: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ContactContainer = ({ t, salesEmail, theme }) => {
|
||||
return (
|
||||
<StyledContactContainer>
|
||||
<Text noSelect fontWeight={600}>
|
||||
{t("ContactUs")}
|
||||
</Text>
|
||||
|
||||
<Link
|
||||
fontWeight={600}
|
||||
href={`mailto:${salesEmail}`}
|
||||
color={theme.client.payments.linkColor}
|
||||
>
|
||||
{salesEmail}
|
||||
</Link>
|
||||
</StyledContactContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ payments, auth }) => {
|
||||
const { salesEmail } = payments;
|
||||
return {
|
||||
salesEmail,
|
||||
theme: auth.settingsStore.theme,
|
||||
};
|
||||
})(withRouter(observer(ContactContainer)));
|
@ -0,0 +1,62 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import Text from "@docspace/components/text";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
const StyledCurrentTariffContainer = styled.div`
|
||||
display: flex;
|
||||
height: 40px;
|
||||
background: #f8f9f9;
|
||||
|
||||
margin-bottom: 24px;
|
||||
grid-template-columns: repeat(auto, minmax(150px, auto));
|
||||
|
||||
white-space: nowrap;
|
||||
grid-gap: 20px;
|
||||
|
||||
p {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const CurrentTariffContainer = ({ quota, style }) => {
|
||||
const { t } = useTranslation("Payments");
|
||||
|
||||
const { usersCount, maxUsersCount, storageSize, usedSize } = quota;
|
||||
|
||||
const convertedBytes = (bytes) => {
|
||||
const sizes = ["Bytes", "Kb", "Mb", "Gb", "Tb"]; //TODO: need to specify about translation
|
||||
if (bytes == 0) return "0 B";
|
||||
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
||||
|
||||
return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + " " + sizes[i];
|
||||
};
|
||||
|
||||
const storageSizeConverted = convertedBytes(storageSize);
|
||||
const usedSizeConverted = convertedBytes(usedSize);
|
||||
|
||||
return (
|
||||
<StyledCurrentTariffContainer style={style} className="current-tariff">
|
||||
<Text isBold noSelect>
|
||||
{t("AddedManagers")}:{" "}
|
||||
<Text as="span" isBold>
|
||||
{usersCount}/{maxUsersCount}
|
||||
</Text>
|
||||
</Text>
|
||||
<Text isBold noSelect>
|
||||
{t("StorageSpace")}:{" "}
|
||||
<Text as="span" isBold>
|
||||
{usedSizeConverted}/{storageSizeConverted}
|
||||
</Text>
|
||||
</Text>
|
||||
</StyledCurrentTariffContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ auth }) => {
|
||||
const { quota } = auth;
|
||||
|
||||
return { quota };
|
||||
})(observer(CurrentTariffContainer));
|
69
packages/client/src/pages/TariffsPage/PriceCalculation.js
Normal file
69
packages/client/src/pages/TariffsPage/PriceCalculation.js
Normal file
@ -0,0 +1,69 @@
|
||||
import React, { useState } from "react";
|
||||
import styled from "styled-components";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import Text from "@docspace/components/text";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import SelectUsersCountContainer from "./sub-components/SelectUsersCountContainer";
|
||||
import TotalTariffContainer from "./sub-components/TotalTariffContainer";
|
||||
import { smallTablet } from "@docspace/components/utils/device";
|
||||
|
||||
const StyledBody = styled.div`
|
||||
border-radius: 12px;
|
||||
border: 1px solid #d0d5da;
|
||||
max-width: 320px;
|
||||
|
||||
@media ${smallTablet} {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
padding: 24px;
|
||||
box-sizing: border-box;
|
||||
p {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
`;
|
||||
|
||||
const step = "1",
|
||||
minUsersCount = 1,
|
||||
maxUsersCount = 1000;
|
||||
|
||||
const PriceCalculation = ({ t, price }) => {
|
||||
const [usersCount, setUsersCount] = useState(minUsersCount);
|
||||
|
||||
const onSliderChange = (e) => {
|
||||
const count = parseFloat(e.target.value);
|
||||
count > minUsersCount ? setUsersCount(count) : setUsersCount(minUsersCount);
|
||||
};
|
||||
|
||||
const onPlusClick = () => {
|
||||
usersCount < maxUsersCount && setUsersCount(usersCount + 1);
|
||||
};
|
||||
|
||||
const onMinusClick = () => {
|
||||
usersCount > minUsersCount && setUsersCount(usersCount - 1);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledBody>
|
||||
<Text fontSize="16px" fontWeight={600} noSelect>
|
||||
{t("PriceCalculation")}
|
||||
</Text>
|
||||
<SelectUsersCountContainer
|
||||
maxUsersCount={maxUsersCount}
|
||||
step={step}
|
||||
usersCount={usersCount}
|
||||
onMinusClick={onMinusClick}
|
||||
onPlusClick={onPlusClick}
|
||||
onSliderChange={onSliderChange}
|
||||
/>
|
||||
<TotalTariffContainer t={t} usersCount={usersCount} price={price} />
|
||||
</StyledBody>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ auth, payments }) => {
|
||||
const { tariffsInfo } = payments;
|
||||
|
||||
return { tariffsInfo };
|
||||
})(observer(PriceCalculation));
|
127
packages/client/src/pages/TariffsPage/index.js
Normal file
127
packages/client/src/pages/TariffsPage/index.js
Normal file
@ -0,0 +1,127 @@
|
||||
import React, { useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
import { withRouter } from "react-router";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import PropTypes from "prop-types";
|
||||
import Section from "@docspace/common/components/Section";
|
||||
import Loader from "@docspace/components/loader";
|
||||
import { setDocumentTitle } from "@docspace/client/src/helpers/filesUtils";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import Text from "@docspace/components/text";
|
||||
import CurrentTariffContainer from "./CurrentTariffContainer";
|
||||
import PriceCalculation from "./PriceCalculation";
|
||||
import BenefitsContainer from "./BenefitsContainer";
|
||||
import { smallTablet } from "@docspace/components/utils/device";
|
||||
import ContactContainer from "./ContactContainer";
|
||||
|
||||
const StyledBody = styled.div`
|
||||
max-width: 660px;
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.payments-info_suggestion {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.payments-info_managers-price {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.payments-info {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(100px, 320px));
|
||||
grid-gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
@media ${smallTablet} {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
`;
|
||||
const TariffsPageWrapper = ({
|
||||
setQuota,
|
||||
quota,
|
||||
setTariffsInfo,
|
||||
tariffsInfo,
|
||||
organizationName,
|
||||
isStartup,
|
||||
price,
|
||||
}) => {
|
||||
const { t, ready } = useTranslation("Payments");
|
||||
|
||||
useEffect(() => {
|
||||
setDocumentTitle(t("TariffsPlans")); //TODO: need to specify
|
||||
}, [ready]);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
await Promise.all([setQuota(), setTariffsInfo()]);
|
||||
} catch (error) {
|
||||
toastr.error(error);
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<StyledBody>
|
||||
<Text noSelect fontSize="16px" isBold>
|
||||
{isStartup ? t("StartupTitle") : t("BusinessTitle")}
|
||||
</Text>
|
||||
<CurrentTariffContainer />
|
||||
<Text
|
||||
noSelect
|
||||
fontSize="16px"
|
||||
isBold
|
||||
className="payments-info_suggestion"
|
||||
>
|
||||
{isStartup ? t("StartupSuggestion") : t("BusinessSuggestion")}
|
||||
</Text>
|
||||
<Text
|
||||
noSelect
|
||||
fontWeight={600}
|
||||
fontSize={"14"}
|
||||
className="payments-info_managers-price"
|
||||
>
|
||||
<Trans t={t} i18nKey="StartPrice" ns="Payments">
|
||||
{{ price: price }}
|
||||
</Trans>
|
||||
</Text>
|
||||
<div className="payments-info">
|
||||
<PriceCalculation t={t} price={price} />
|
||||
<BenefitsContainer t={t} />
|
||||
</div>
|
||||
<ContactContainer t={t} />
|
||||
</StyledBody>
|
||||
);
|
||||
};
|
||||
|
||||
TariffsPageWrapper.propTypes = {
|
||||
isLoaded: PropTypes.bool,
|
||||
};
|
||||
|
||||
const TariffsPage = (props) => {
|
||||
return (
|
||||
<Section>
|
||||
<Section.SectionBody>
|
||||
<TariffsPageWrapper {...props} />
|
||||
</Section.SectionBody>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
export default inject(({ auth, payments }) => {
|
||||
const { setQuota, quota } = auth;
|
||||
const { organizationName } = auth.settingsStore;
|
||||
const { setTariffsInfo, tariffsInfo } = payments;
|
||||
|
||||
const isStartup = true;
|
||||
const price = "30";
|
||||
|
||||
return {
|
||||
setQuota,
|
||||
quota,
|
||||
organizationName,
|
||||
setTariffsInfo,
|
||||
tariffsInfo,
|
||||
isStartup,
|
||||
price,
|
||||
};
|
||||
})(withRouter(observer(TariffsPage)));
|
@ -0,0 +1,92 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Text from "@docspace/components/text";
|
||||
import Slider from "@docspace/components/slider";
|
||||
import PlusIcon from "../../../../public/images/plus.react.svg";
|
||||
import MinusIcon from "../../../../public/images/minus.react.svg";
|
||||
import { smallTablet } from "@docspace/components/utils/device";
|
||||
const StyledBody = styled.div`
|
||||
max-width: 272px;
|
||||
margin: 0 auto;
|
||||
|
||||
@media ${smallTablet} {
|
||||
max-width: 520px;
|
||||
}
|
||||
|
||||
.tariff-users {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 auto;
|
||||
width: max-content;
|
||||
.tariff-score,
|
||||
.circle {
|
||||
cursor: pointer;
|
||||
}
|
||||
.circle {
|
||||
background: #f3f4f4;
|
||||
display: flex;
|
||||
border: 1px solid #f3f4f4;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
justify-content: center;
|
||||
-ms-align-items: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.tariff-users_count {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
text-align: center;
|
||||
width: 102px;
|
||||
}
|
||||
|
||||
.tariff-users_text {
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
`;
|
||||
|
||||
const SelectUsersCountContainer = ({
|
||||
maxUsersCount,
|
||||
step,
|
||||
usersCount,
|
||||
onMinusClick,
|
||||
onPlusClick,
|
||||
onSliderChange,
|
||||
}) => {
|
||||
const { t } = useTranslation("Payments");
|
||||
|
||||
return (
|
||||
<StyledBody>
|
||||
<Text noSelect fontWeight={600} className="tariff-users_text">
|
||||
{t("ManagersNumber")}
|
||||
</Text>
|
||||
<div className="tariff-users">
|
||||
<div className="circle" onClick={onMinusClick}>
|
||||
<MinusIcon onClick={onMinusClick} className="tariff-score" />
|
||||
</div>
|
||||
<Text noSelect fontSize={"44px"} className="tariff-users_count" isBold>
|
||||
{usersCount}
|
||||
</Text>
|
||||
<div className="circle" onClick={onPlusClick}>
|
||||
<PlusIcon onClick={onPlusClick} className="tariff-score" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Slider
|
||||
type="range"
|
||||
min={"0"}
|
||||
max={maxUsersCount.toString()}
|
||||
step={step}
|
||||
withPouring
|
||||
value={usersCount}
|
||||
onChange={onSliderChange}
|
||||
colorPouring={"#20D21F"}
|
||||
/>
|
||||
</StyledBody>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectUsersCountContainer;
|
@ -0,0 +1,96 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
import { useTranslation, Trans } from "react-i18next";
|
||||
import Text from "@docspace/components/text";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import Button from "@docspace/components/button";
|
||||
import { smallTablet } from "@docspace/components/utils/device";
|
||||
|
||||
const StyledBody = styled.div`
|
||||
max-width: 272px;
|
||||
margin: 0 auto;
|
||||
|
||||
@media ${smallTablet} {
|
||||
max-width: 520px;
|
||||
}
|
||||
|
||||
.total-tariff_user {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #f3f4f4;
|
||||
|
||||
p:first-child {
|
||||
margin-right: 8px;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
.total-tariff_price {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.total-tariff_price-text {
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #eceef1;
|
||||
}
|
||||
.total-tariff_month-text {
|
||||
margin: auto 0;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const TotalTariffContainer = ({ t, usersCount, price }) => {
|
||||
useEffect(() => {}, []);
|
||||
|
||||
const totalPrice = price * usersCount;
|
||||
|
||||
return (
|
||||
<StyledBody>
|
||||
<div className="total-tariff_user">
|
||||
<Text fontSize="16px" textAlign="center" isBold noSelect>
|
||||
{price}
|
||||
</Text>
|
||||
<Text
|
||||
fontSize="11px"
|
||||
textAlign="center"
|
||||
fontWeight={600}
|
||||
color={"#A3A9AE"}
|
||||
noSelect
|
||||
>
|
||||
{t("PerUserMonth")}
|
||||
</Text>
|
||||
</div>
|
||||
<div className="total-tariff_price">
|
||||
<Text
|
||||
fontSize="48px"
|
||||
isBold
|
||||
textAlign={"center"}
|
||||
className="total-tariff_price-text"
|
||||
noSelect
|
||||
>
|
||||
{totalPrice}
|
||||
</Text>
|
||||
<Text
|
||||
fontSize="16px"
|
||||
isBold
|
||||
textAlign={"center"}
|
||||
className="total-tariff_month-text"
|
||||
noSelect
|
||||
>
|
||||
{"/month"}
|
||||
</Text>
|
||||
</div>
|
||||
<Button label={t("UpgradeNow")} size={"medium"} primary />
|
||||
</StyledBody>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({}) => {
|
||||
return {};
|
||||
})(observer(TotalTariffContainer));
|
@ -532,3 +532,10 @@ export function getMetadata() {
|
||||
export function getOforms(url) {
|
||||
return axios.get(url);
|
||||
}
|
||||
|
||||
export function getPortalQuota() {
|
||||
return request({
|
||||
method: "get",
|
||||
url: `/settings/quota`,
|
||||
});
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ class AuthStore {
|
||||
providers = [];
|
||||
isInit = false;
|
||||
|
||||
quota = {};
|
||||
|
||||
constructor() {
|
||||
this.userStore = new UserStore();
|
||||
|
||||
@ -284,6 +286,11 @@ class AuthStore {
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
setQuota = async () => {
|
||||
const res = await api.settings.getPortalQuota();
|
||||
if (res) this.quota = res;
|
||||
};
|
||||
}
|
||||
|
||||
export default new AuthStore();
|
||||
|
@ -2622,6 +2622,10 @@ const Base = {
|
||||
textColorError: red,
|
||||
},
|
||||
|
||||
payments: {
|
||||
linkColor: link,
|
||||
},
|
||||
|
||||
paymentsEnterprise: {
|
||||
background: grayLight,
|
||||
|
||||
|
@ -2632,6 +2632,10 @@ const Dark = {
|
||||
textColorError: red,
|
||||
},
|
||||
|
||||
payments: {
|
||||
linkColor: "#E06A1B",
|
||||
},
|
||||
|
||||
paymentsEnterprise: {
|
||||
background: black,
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user