@@ -19,8 +19,6 @@ import { getApiUrl } from '#/shared/lib/constants' import { useDeviceType } from '#/shared/lib/hooks/use-device-type' import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' -import styles from './register-email-form.module.scss' - interface IRegisterEmailFormProps { successLogin: () => void } @@ -143,7 +141,14 @@ export const RegisterEmailForm: React.FC = ({ successLo InputProps={{ endAdornment: ( -
showPassword((x) => !x)} className={styles.passwordToggle}> +
showPassword((x) => !x)} + style={{ + cursor: 'pointer', + display: 'flex', + alignItems: 'center', + }} + > {passwordShowed ? ( ) : ( @@ -206,13 +211,21 @@ export const RegisterEmailForm: React.FC = ({ successLo {loading ? ( - + ) : ( )} -

+

Регистрируясь, вы соглашаетесь с условиями  - + Политики обработки персональных данных  и  - + Публичной офертой

@@ -252,7 +265,13 @@ export const RegisterEmailForm: React.FC = ({ successLo }} > Есть аккаунт?{' '} - + Войти @@ -1,72 +0,0 @@ -import { Box, LinearProgress, linearProgressClasses, Stack, styled, Typography } from '@mui/material' - -import { commaSeparated } from '#/shared' -import { formatPlanPrice } from '#/shared/lib/helpers/format-plan-price' -import { declineToken } from '#/shared/lib/helpers/get-token' - -import styles from '../subscription.module.scss' - -const BorderLinearProgress = styled(LinearProgress)(() => ({ - height: 18, - borderRadius: 6, - [`&.${linearProgressClasses.colorPrimary}`]: { - backgroundColor: '#EFF0F2', - }, - [`& .${linearProgressClasses.bar}`]: { - borderRadius: 6, - backgroundColor: '#8280FF', - }, -})) - -interface CurrentPlanAndBalanceLegacyProps { - balance: number - planTokenLimit: string - planPrice: string - isIndividual: boolean -} - -export const CurrentPlanAndBalanceLegacy = ({ - balance, - planTokenLimit, - planPrice, - isIndividual, -}: CurrentPlanAndBalanceLegacyProps) => { - const formatterdPlanPrice = formatPlanPrice(planPrice, isIndividual) - const planTokenLimitNumber = Number(planTokenLimit) - const percentage = planTokenLimitNumber > 0 ? Math.min(100, Math.max(0, (balance / planTokenLimitNumber) * 100)) : 0 - - return ( - - - - Последняя оплата - - - - {commaSeparated(Math.round(Number(planTokenLimit)))} токенов - - - {formatterdPlanPrice} - - - - - Мой баланс - - {declineToken(balance.toString())} - {Math.round(percentage)} % - - - - - ) -} @@ -1,93 +0,0 @@ -import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown' -import { Box, MenuItem, Select, SelectChangeEvent, Stack, Typography } from '@mui/material' - -import { IFeatures } from '../../api' -import { categoryIconMap } from '../../lib/category-icon-map' -import { formatFeatureValue } from '../../lib/format-feature-value' - -import styles from '../subscription.module.scss' - -interface FeaturesSectionLegacyProps { - currentTokenLimitUID: string - onCurrentTokenLimitUIDChange: (limit: string) => void - features: IFeatures[] | null - tokenLimits: Array<{ value: string; label: string }> -} - -export const FeaturesSectionLegacy = ({ - currentTokenLimitUID, - onCurrentTokenLimitUIDChange, - features, - tokenLimits, -}: FeaturesSectionLegacyProps) => { - return ( - - - - - - - {features?.map((featureGroup, idx) => ( - - - {categoryIconMap[featureGroup.name] && ( - {categoryIconMap[featureGroup.name]} - )} - {featureGroup.name} - - - - {featureGroup.features.map((feature, featureIdx) => { - let { number, unit, more } = formatFeatureValue(feature.quantity, feature.measurement_unit) - - return ( - - {feature.name} - - - {number == '-' ? ( - - ) : ( - <> - {' '} - {more} {number} - {unit} - - )} - - - - ) - })} - - - ))} - - - - Для каждой отдельной модели указано примерное количество генераций, как если бы вы пользовались{' '} - только ей.
- Количество генераций может варьироваться в зависимости от используемых параметров каждой конкретной модели. -
-
- ) -} @@ -1,101 +0,0 @@ -import React from 'react' -import { Box } from '@mui/material' -import Router from 'next/router' -import { useSession } from 'next-auth/react' - -import LightningSvg from '#/assets/svg/lightning.svg?react' -import { accountApi } from '#/shared/api/account-endpoints' -import { commaSeparated } from '#/shared/lib/helpers' -import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' -import { IFeatures, IOffer, formatFeatureValue } from '#/views/subscription' - -import styles from '../offer.module.scss' - -interface IOfferLegacyProps extends IOffer { - device: 'desktop' | 'mobile' - isCurrentSubscription?: boolean - index?: number -} - -const OfferLegacy: React.FC = ({ uid, tokens_per_plan, price, grouped_features, isCurrentSubscription, index }) => { - const { data } = useSession() - const { showMessage } = useShowDataStore() - - const unitMap: Record = { - Изображения: 'изображений', - 'Чат-боты': 'страниц текста', - Видео: 'видео', - Аудио: 'аудиозаписей', - } - - const formatFeatures = (groupedFeatures: IFeatures[] | undefined): string[] => { - if (!groupedFeatures || !Array.isArray(groupedFeatures)) { - return [] - } - - return groupedFeatures.flatMap((group) => { - if (!group?.features || !Array.isArray(group.features)) { - return [] - } - - const limit = group.name === 'Изображения' ? 2 : 1 - const featuresToShow = group.features.slice(0, limit) - - return featuresToShow - .filter((feature) => feature.quantity !== 0) - .map((feature) => { - const groupName = unitMap[group.name] || group.name - const { number, more } = formatFeatureValue(feature.quantity, feature.measurement_unit) - return `${more ? more + ' ' : ''}${number} ${groupName} в ${feature.name}` - }) - }) - } - - const formattedFeatures = formatFeatures(grouped_features) - - const pay = async (planUid: string) => { - try { - const urlForPay = await accountApi.payProduct(data!.access, planUid) - if (urlForPay) await Router.push(urlForPay) - } catch (err) { - const message = err instanceof Error ? err.message : 'Ошибка оплаты' - showMessage(message) - } - } - - return ( - - - - - - {commaSeparated(Math.round(Number(tokens_per_plan)))} токенов - - - - -
    - {formattedFeatures.map((feature, idx) => ( -
  • - {feature} -
  • - ))} -
-
- -

{commaSeparated(parseInt(price) ?? 0)} ₽

- { - e.stopPropagation() - pay(uid) - }} - > - Оплатить - -
-
- ) -} - -export default OfferLegacy @@ -1,32 +0,0 @@ -import { Box } from '@mui/material' - -import { IOffer } from '../../api' - -import OfferLegacy from './offer-legacy' - -import styles from '../subscription.module.scss' - -interface PlansSectionLegacyProps { - offers: IOffer[] | null - currentOfferUID: string -} - -export const PlansSectionLegacy = ({ offers, currentOfferUID: _currentOfferUID }: PlansSectionLegacyProps) => { - return ( - - - {offers?.map((offer, idx) => { - return ( - - ) - })} - - - ) -} @@ -1,84 +0,0 @@ -import { useEffect, useState } from 'react' -import { Box, Typography } from '@mui/material' -import { useSession } from 'next-auth/react' - -import { useAppSelector } from '#/app/store/store' -import { commaSeparated } from '#/shared' -import { accountApi } from '#/shared/api/account-endpoints' -import { balanceSelector } from '#/shared/lib/selectors' - -import { IFeatures, IOffer } from '../../api' - -import { FaqSection } from '../faq-section' -import { CurrentPlanAndBalanceLegacy } from './current-plan-and-balance-legacy' -import { FeaturesSectionLegacy } from './features-section-legacy' -import { PlansSectionLegacy } from './plans-section-legacy' - -import styles from '../subscription.module.scss' - -export const SubscriptionLegacyPage = () => { - const [offers, setOffers] = useState(null) - const [currentTokenLimitUID, setCurrentTokenLimitUID] = useState('') - const [tokenLimits, setTokenLimits] = useState>([]) - const [currentFeatures, setCurrentFeatures] = useState([]) - const { - uid: paymentPlanUid, - tokens_per_plan: planTokenLimit, - price: planPrice, - individual: isIndividual, - } = useAppSelector((state) => state.user.payment_plan.plan) - const balance = useAppSelector(balanceSelector) - const { data } = useSession() - - useEffect(() => { - if (data?.access) { - accountApi.getPaymentsPlans(data?.access).then((res) => { - if (res) { - setOffers(res) - setCurrentTokenLimitUID(res[0].uid) - setTokenLimits( - res.map((offer) => ({ - value: offer.uid, - label: `${commaSeparated(Math.round(Number(offer.tokens_per_plan)))} токенов`, - })) - ) - } - }) - } - }, [data?.access]) - - useEffect(() => { - if (offers && currentTokenLimitUID) { - const foundOffer = offers.find((offer) => offer.uid === currentTokenLimitUID) - if (foundOffer) { - setCurrentFeatures(foundOffer.grouped_features) - } - } - }, [currentTokenLimitUID, offers]) - - return ( - - - Оплата - - - - - - - - - - - ) -} @@ -5,7 +5,7 @@ import { useShowDataStore } from '#/shared/lib/hooks/use-show-data' import styles from './individual-subscription-notice.module.scss' -export const IndividualSubscriptionNotice = ({ contactEmail = 't.bikbov@air.fail' }: { contactEmail?: string }) => { +export const IndividualSubscriptionNotice = ({ contactEmail = 'help@air.fail' }: { contactEmail?: string }) => { const { showMessage } = useShowDataStore() const copyEmail = useCallback(async () => { @@ -1,19 +1,9 @@ import { NextPageWithLayout } from '#/pages/_app' -import { useFeatureFlag } from '#/shared/lib/hooks/use-feature-flag' - -import { SubscriptionLegacyPage } from './legacy/subscription-legacy' import { SubscriptionRecurrentPage } from './subscription-recurrent' -const RECURRENT_PAYMENTS_FLAG = 'recurrent-payments-enabled' const SubscriptionPage: NextPageWithLayout = () => { - const recurrentPaymentsEnabled = useFeatureFlag(RECURRENT_PAYMENTS_FLAG) - - if (recurrentPaymentsEnabled) { return - } - - return } export default SubscriptionPage