(null)
+ const user = useAppSelector((state) => state.user)
+ const { data } = useSession()
+
+ useEffect(() => {
+ if (!data?.access) {
+ return
+ }
+
+ model_api.getImages(data?.access).then((res) => setBots(res))
+ }, [data?.access])
+
+ return (
+
+ Изображения
+
+ {bots ? (
+ bots.map((item, idx) => {
+ return (
+
+ )
+ })
+ ) : (
+
+ )}
+
+
+ )
+}
+
+export default Images
@@ -1,7 +1,47 @@
-import { ReferralPage } from '#/views/referral'
+import React, { useEffect } from 'react'
+import { useDispatch } from 'react-redux'
+import { Box } from '@mui/material'
+import CircularProgress from '@mui/material/CircularProgress'
+import { useRouter } from 'next/router'
+
+import { addReferral } from '@/src/entities/user-account/model/user-type-slice'
export async function getServerSideProps({ params }: { params: Promise<{ email: string }> }) {
- return { props: { email: (await params).email } }
+ const email = (await params).email
+
+ return {
+ props: {
+ email,
+ },
+ }
+}
+
+function ReferralRegister({ email }: { email: string }) {
+ const dispatch = useDispatch()
+ const { push } = useRouter()
+
+ useEffect(() => {
+ localStorage.setItem('referral', email)
+ dispatch(addReferral(email))
+ push('/register')
+ }, [])
+
+ return (
+
+
+
+ )
}
-export default ReferralPage
+export default ReferralRegister
@@ -1,3 +1,56 @@
-import { NotFoundPage } from '#/views/not-found'
+import React from 'react'
+import { Box, Typography } from '@mui/material'
+import Link from 'next/link'
+import { useRouter } from 'next/router'
-export default NotFoundPage
+import { Layout } from '@/src/main/layout'
+import { useAppSelector } from '@/src/main/store/store'
+
+const Custom404 = () => {
+ const theme = useAppSelector((state) => state.theme.theme)
+
+ const { push } = useRouter()
+
+ React.useEffect(() => {
+ setTimeout(() => push('/'), 7000)
+ }, [])
+
+ return (
+
+
+
+
+ Ошибка 404
+
+
+ К сожалению, такая страница не найдена 😢
+
+
+
+ Вернуться на главную
+
+
+
+
+
+ )
+}
+
+export default Custom404
@@ -1,6 +1,6 @@
-import React, { ReactElement, ReactNode } from 'react'
+import React from 'react'
import { Provider } from 'react-redux'
-import { StyledEngineProvider, ThemeProvider } from '@mui/material'
+import { StyledEngineProvider } from '@mui/material'
import axios from 'axios'
import * as https from 'https'
import type { AppProps } from 'next/app'
@@ -8,14 +8,12 @@ import { Raleway } from 'next/font/google'
import { SessionProvider } from 'next-auth/react'
import { appWithTranslation } from 'next-i18next'
-import { store } from '#/app/store/store'
+import { store } from '@/src/main/store/store'
import ErrorBoundary from './error-boundary'
-import '#/app/styles/globals.css'
-import '#/app/styles/styles-pages/system.scss'
-import { NextPage } from 'next'
-import { pingFangFont } from '#/shared/lib/constants/font/font'
+import '@/src/main/styles/globals.css'
+import '@/src/main/styles/styles-pages/system.scss'
axios.defaults.httpsAgent = new https.Agent({
rejectUnauthorized: false,
@@ -23,17 +21,7 @@ axios.defaults.httpsAgent = new https.Agent({
const inter = Raleway({ subsets: ['latin'] })
-export type NextPageWithLayout = NextPage
& {
- getLayout?: (page: ReactElement) => ReactNode
- dynamicProps?: DP
-}
-
-export interface AppPropsWithLayout extends AppProps {
- Component: NextPageWithLayout
-}
-
-function App({ Component, pageProps: { session, ...pageProps } }: AppPropsWithLayout) {
- const getLayout = Component.getLayout ?? ((page) => page)
+function App({ Component, pageProps: { session, ...pageProps } }: AppProps) {
return (
<>
@@ -47,9 +35,7 @@ function App({ Component, pageProps: { session, ...pageProps } }: AppPropsWithLa
-
- {getLayout()}
-
+
@@ -27,11 +27,7 @@ export default function Document() {
@@ -1,6 +1,581 @@
-import { AccountPage } from '#/views/account'
-import { getDefaultLayout } from '#/widgets/layouts'
+import * as React from 'react'
+import { useEffect, useMemo, useRef, useState } from 'react'
+import { Avatar, Box, Button, Stack, Tab, Tabs, Typography } from '@mui/material'
+import CircularProgress from '@mui/material/CircularProgress'
+import axios from 'axios'
+import Image from 'next/image'
+import { useRouter } from 'next/router'
+import { getServerSession } from 'next-auth'
+import { signOut, useSession } from 'next-auth/react'
-AccountPage.getLayout = getDefaultLayout({ titlePage: 'Аккаунт' })
+import { getUserBalance } from '@/src/entities/balance'
+import { getAllInfo, unfollowEmail } from '@/src/entities/user-account/model/user-type-slice'
+import { Layout } from '@/src/main/layout'
+import { useAppDispatch, useAppSelector } from '@/src/main/store/store'
+import styles2 from '@/src/main/styles/accountTabs.module.css'
+import styles from '@/src/main/styles/business.module.scss'
+import { ButtonUI, Input, Loader, Modal, Success, SwitchCustom, useShowData } from '@/src/shared'
+import { accountApi } from '@/src/shared/api/account-endpoints'
+import { API_URL } from '@/src/shared/lib/constants/constants'
+import { getAccessToken, getTypeDevice } from '@/src/shared/lib/helpers'
+import { IProps } from '@/src/shared/lib/types/entities'
+import { ScreenForInactive } from '@/src/widgets/business'
+import BusinessHost from '@/src/widgets/business-host/business-host'
+import { Info } from '@/src/widgets/business-info'
+import { Subscription } from '@/src/widgets/payment/model/payment'
+import { Referral } from '@/src/widgets/referral'
-export default AccountPage
+import { DownloadModal } from '../features/business-security-download/ui/download-modal'
+
+const scopes = [
+ { title: 'Настройки', scope: 'setting' },
+ { title: 'Управление оплатой', scope: 'subscribe' },
+ { title: 'Корпоративный аккаунт', scope: 'business' },
+ { title: 'Реферальная программа', scope: 'referral' },
+]
+
+export interface IPaymentsPlan {
+ uid: string
+ price: string
+ tokens_per_plan: string
+}
+
+interface IAccountProps extends IProps {
+ plans: IPaymentsPlan[] | null
+ redirect?: {
+ destination: string
+ permanent: boolean
+ }
+}
+
+export async function getServerSideProps(context: any): Promise<{ props: IAccountProps }> {
+ const device = getTypeDevice(context)
+
+ const token = (await getAccessToken(context.req)) || null
+
+ //@ts-ignore
+ const session = await getServerSession(context.req, context.res)
+
+ const plans = token ? await accountApi.getPaymentsPlans(token) : null
+
+ //@ts-ignore
+ if (!session) {
+ return {
+ //@ts-ignore
+ redirect: {
+ destination: '/',
+ permanent: false,
+ },
+ }
+ }
+ return {
+ props: {
+ device,
+ token,
+ plans,
+ },
+ }
+}
+
+const Account: React.FC = ({ device, token, plans }) => {
+ const {
+ email,
+ is_subscribed_to_emails,
+ account_type,
+ first_name,
+ last_name,
+ username,
+ profile_picture_link,
+ is_social,
+ status: userInfoLoaded,
+ referral_code,
+ } = useAppSelector((state) => state.user)
+
+ const { status, account_type: type } = useAppSelector((state) => state.user)
+
+ const [name, setName] = useState('')
+
+ const [lastName, setLastName] = useState('')
+
+ const fileInputRef = useRef(null)
+
+ const [loading, setLoading] = useState(false)
+
+ const { data } = useSession()
+ const handleDivClick = () => {
+ ;(fileInputRef.current! as any).click()
+ }
+
+ const dispatch = useAppDispatch()
+
+ const { error, showError, isError } = useShowData()
+
+ const handleFileChange = async (event: any) => {
+ const formData = new FormData()
+ formData.append('new_picture', event.target.files[0])
+
+ try {
+ setLoading(true)
+ await axios.put(API_URL + '/auth/reset-profile-pic', formData, {
+ headers: {
+ Authorization: `Bearer ${data?.access}`,
+ 'Content-Type': 'multipart/form-data',
+ },
+ })
+ dispatch(getAllInfo(data?.access))
+ showError('Изображение успешно загружено!')
+ setLoading(false)
+ } catch (e) {
+ setLoading(false)
+ showError('Ошибка загрузки изображения на сервере!', true)
+ }
+ }
+
+ const [currentPassword, setCurrentPassword] = React.useState('')
+
+ const [newPassword1, setNewPassword1] = React.useState('')
+
+ const [newPassword2, setNewPassword2] = React.useState('')
+
+ const [promocode, setPromocode] = React.useState('')
+
+ const [success, setSuccess] = React.useState('')
+
+ const [confirmDeleteModal, setConfirmDeleteModal] = useState(false)
+
+ const { push, query } = useRouter()
+
+ const [scope, setScope] = useState(query['scope'] || 'setting')
+
+ const [downloadModal, setDownloadModal] = useState(false)
+
+ const desktop = device === 'desktop'
+
+ const changeScope = async (scope: string) => {
+ setScope(scope)
+ await addQueryParams(scope)
+ }
+
+ async function addQueryParams(scope: string) {
+ await push({
+ pathname: '/account',
+ query: { scope },
+ })
+ }
+
+ useEffect(() => {
+ if (query['scope'] !== undefined && scope !== query['scope']) {
+ changeScope(query['scope'] as string)
+ }
+ }, [query])
+
+ useEffect(() => {
+ if (Object.keys(query).length === 0) addQueryParams('setting')
+ }, [])
+
+ const changePassword = async () => {
+ if (newPassword1 !== newPassword2) {
+ showError('Укажите одинаковые новы пароли!', true)
+ return
+ }
+ const status = await accountApi.changePassword(token, newPassword1, newPassword2, currentPassword)
+
+ if (status === 200) {
+ showError('Пароль успешно изменён!')
+ setNewPassword1('')
+ setNewPassword2('')
+ setCurrentPassword('')
+ setTimeout(() => setSuccess(''), 6000)
+ return
+ }
+
+ showError('К сожалению, произошла ошибка', true)
+ }
+
+ function body() {
+ if (type === 'regular') {
+ return (
+
+
+
+ )
+ }
+ if (type === 'business_account') {
+ return Информация о корп.аккаунте доступна только владельцу и администраторам.
+ }
+ if (type === 'business_host') {
+ return
+ }
+ if (type === 'business_admin') {
+ return
+ }
+ if (type === 'business_security') {
+ return (
+ <>
+
+
+
+
+ Раздел 1. Запросы сотрудников по моделям
+
+
+ {
+ setDownloadModal(true)
+ }}
+ sx={{ marginTop: '20px' }}
+ text={'Скачать'}
+ />
+
+
+ >
+ )
+ }
+ }
+
+ const isUserDataChange = useMemo(() => name !== first_name || last_name !== lastName, [name, lastName])
+
+ const promocodeActivate = async () => {
+ if (!promocode.trim()) {
+ showError('Введите корректный промокод', true)
+ return
+ }
+ let resStatus = 404
+ try {
+ const { status } = await axios.post(
+ API_URL + '/payments/promocode',
+ { code: promocode },
+ { headers: { Authorization: `Bearer ${token}` } }
+ )
+ resStatus = status
+ } catch (e) {}
+
+ if (resStatus === 200) {
+ showError('Промокод успешно активирован! Токены уже зачислены!')
+ dispatch(getUserBalance(data?.access))
+ return
+ }
+
+ if (resStatus === 403) {
+ showError('Промокод уже был активирован!', true)
+ return
+ }
+
+ if (resStatus === 404) {
+ showError('Промокод не найден!', true)
+ return
+ }
+ }
+
+ async function changeUserData() {
+ if (!isUserDataChange) {
+ showError('Вы не изменили данные', true)
+ return
+ }
+
+ try {
+ await axios.put(
+ API_URL + '/auth/user-data',
+ {
+ username: username,
+ email: email,
+ first_name: name,
+ last_name: lastName,
+ },
+ { headers: { Authorization: `Bearer ${token}` } }
+ )
+
+ showError('Данные успешно изменены!')
+ dispatch(getAllInfo(token))
+ } catch (e) {}
+ }
+
+ const deleteAccount = async () => {
+ try {
+ const { status } = await axios.delete(API_URL + '/auth/remove', {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ })
+
+ if (status === 200) await signOut()
+ } catch (err) {}
+ }
+
+ useEffect(() => {
+ setName(first_name)
+ setLastName(last_name)
+ }, [first_name, last_name])
+
+ return (
+
+
+
+
+ Ваш аккаунт
+
+ {scopes.map((el) => {
+ if (!desktop && el.scope === 'business') {
+ return null
+ }
+ if (el.scope === 'referral' && account_type !== 'regular') {
+ return null
+ }
+ return (
+ changeScope(el.scope)}
+ key={el.title}
+ className={scope === el.scope ? styles2.wrap_toggle_button_active : styles2.wrap_toggle_button}
+ value={el.scope}
+ label={el.title}
+ />
+ )
+ })}
+
+ {scope === 'setting' ? (
+ <>
+
+ Основные
+
+
+
+
+
+ {!loading || !(userInfoLoaded === 'succeeded') ? (
+
+ ) : (
+
+ )}
+
+
+ {''}
+
+
+
+
+
+ Имя
+ setName(e.target.value)}
+ fullWidth
+ />
+
+
+ Фамилия
+ setLastName(e.target.value)}
+ fullWidth
+ />
+
+
+
+ Email
+
+ {
+ await dispatch(unfollowEmail(token))
+ showError('Данные изменены!')
+ }}
+ />
+
+ Отписаться от рассылки
+
+
+
+
+
+
+ Никнейм
+
+
+
+ {/*referral_code.code.trim() && (
+
+ Ваша реферальная ссылка:
+
+
+ navigator.clipboard.writeText(referral_code.code.trim())}
+ className='text'
+ sx={{ color: '#8280FF !important', cursor: 'pointer' }}
+ >
+ {referral_code.code}
+
+
+
+) */}
+
+
+
+
+ Активация промокода
+ setPromocode(e.target.value)}
+ fullWidth
+ />
+
+
+ {!is_social && (
+
+ Изменить пароль
+
+
+ Текущий пароль
+ setCurrentPassword(e.target.value)}
+ fullWidth
+ />
+
+
+
+ Новый пароль
+ setNewPassword1(e.target.value)}
+ fullWidth
+ />
+
+
+ Подтвердить пароль
+ setNewPassword2(e.target.value)}
+ fullWidth
+ />
+
+
+
+
+
+ )}
+
+ Удаление аккаунта
+ Удаление аккаунта приведет к потере всех настроек
+ setConfirmDeleteModal(true)}
+ sx={{ marginTop: '20px' }}
+ text={'Удалить аккаунт'}
+ style={{
+ width: '100%',
+ backgroundColor: 'rgba(255, 35, 114, 0.10)',
+ color: '#FF2372',
+ }}
+ />
+
+
+ setConfirmDeleteModal(false)}>
+
+ Удаление аккаунта
+ Вы действительно хотите удалить ваш аккаунт?
+
+
+
+ >
+ ) : scope === 'business' ? (
+
+ {status == 'pending' || type === null ? (
+
+
+
+ ) : (
+ {body()}
+ )}
+
+ ) : scope === 'subscribe' ? (
+
+ ) : scope === 'referral' && account_type === 'regular' ? (
+
+ ) : (
+ <>>
+ )}
+
+
+
+
+
+ )
+}
+
+export default Account
@@ -1,6 +1,49 @@
-import { AdminPage } from '#/views/admin'
-import { getDefaultLayout } from '#/widgets/layouts'
+import React from 'react'
+import { Stack } from '@mui/material'
+import { getSession } from 'next-auth/react'
-AdminPage.getLayout = getDefaultLayout({ titlePage: 'Админка' })
+import { Layout } from '@/src/main/layout'
+import { useAppSelector } from '@/src/main/store/store'
+import { getAccessToken, getTypeDevice } from '@/src/shared/lib/helpers'
+import { IProps } from '@/src/shared/lib/types/entities'
+import { StatsField } from '@/src/widgets/stats-field'
-export default AdminPage
+export async function getServerSideProps(context: any): Promise<{ props: any }> {
+ const device = getTypeDevice(context)
+
+ const token = (await getAccessToken(context.req)) || null
+
+ const { req } = context
+ const session = await getSession({ req })
+
+ if (true) {
+ return {
+ //@ts-ignore
+ redirect: {
+ destination: '/',
+ permanent: false,
+ },
+ }
+ }
+
+ return {
+ props: {
+ device,
+ token,
+ },
+ }
+}
+
+const Admin: React.FC = ({ token, device }) => {
+ const theme = useAppSelector((state) => state.theme.theme)
+
+ return (
+
+
+
+
+
+ )
+}
+
+export default Admin
@@ -1,6 +1,219 @@
-import { ApiKeysPage } from '#/views/api-keys'
-import { getDefaultLayout } from '#/widgets/layouts'
+import React, { useEffect, useState } from 'react'
+import { Box, Stack, Table, TableBody, TableHead, TableRow, TextField, Typography } from '@mui/material'
+import Button from '@mui/material/Button'
+import TableCell from '@mui/material/TableCell'
+import axios from 'axios'
+import Image from 'next/image'
+import Link from 'next/link'
+import { useSession } from 'next-auth/react'
-ApiKeysPage.getLayout = getDefaultLayout({ device: 'desktop', titlePage: 'API-ключи' })
+import { getAll, ResponseAllInfo } from '@/src/entities/user-account/model/user-type-slice'
+import { ApiKeyModal } from '@/src/features/api-key-modal/api-key-modal'
+import { Layout } from '@/src/main/layout'
+import { useAppSelector } from '@/src/main/store/store'
+import { TooltipCustom } from '@/src/shared'
+import { accountApi } from '@/src/shared/api/account-endpoints'
+import { API_URL } from '@/src/shared/lib/constants'
+import styles from '@/src/shared/styles/api-keys.module.scss'
+import { InputStyleSmallDark, InputStyleSmallLight } from '@/src/shared/ui/input'
-export default ApiKeysPage
+const ApiKeys: React.FC = () => {
+ const [keys, setKeys] = useState | null>(null)
+ const [loading, setLoading] = useState(false)
+ const { data, status } = useSession()
+ const [modal, setModal] = useState(false)
+ const [userInfo, setUserInfo] = useState()
+ const [disabled, setDisabled] = React.useState(true)
+
+ useEffect(() => {
+ getAll(data?.access).then((res) => setUserInfo(res))
+ }, [data?.access])
+
+ useEffect(() => {
+ if (status === 'authenticated') {
+ setLoading(true)
+ accountApi.getApiKeys(data?.access).then((res) => {
+ setKeys(res)
+ setLoading(false)
+ })
+ }
+ }, [status])
+
+ React.useEffect(() => {
+ if (
+ userInfo?.account_type === 'business_security' ||
+ userInfo?.account_type === 'business_account' ||
+ status !== 'authenticated' ||
+ loading
+ ) {
+ setDisabled(true)
+ } else {
+ setDisabled(false)
+ }
+ }, [status, userInfo, loading])
+
+ const deleteKey = async (name: string) => {
+ if (keys === null || status !== 'authenticated') {
+ return
+ }
+
+ setLoading(true)
+ const result = await accountApi.deleteApiKey(name, data?.access)
+ if (result !== null && result === 200) {
+ accountApi.getApiKeys(data?.access).then((res) => {
+ setKeys(res)
+ setLoading(false)
+ })
+ }
+ setLoading(false)
+ }
+
+ return (
+ <>
+
+
+
+ API ключи
+
+
+
+
+ API-ключ — это инструмент, который идентифицирует пользователя или программу, запрашивающих доступ к API платформы.
+ С помощью ключа можно отслеживать, кто и когда пользуется API, рассчитывать оплату.
+
+
+
+
+
+ Документация
+
+
+
+
+
+ {keys && keys.length !== 0 ? (
+
+ Мои ключи
+
+
+
+ Имя
+ Ключ
+ Лимит токенов
+ Создан
+ Действителен до
+
+
+
+ {keys &&
+ keys.map((el) => {
+ return (
+
+ )
+ })}
+
+
+
+ ) : (
+
+
+ У вас пока нет ключей 😞
+ Создайте первый ключ
+
+
+ )}
+
+
+ >
+ )
+}
+
+const KeyRow = (props: any) => {
+ const [isCopy, setIsCopy] = useState(false)
+ const [limit, setLimit] = useState(props.limit)
+ const theme = useAppSelector((state) => state.theme.theme)
+ const { data: session } = useSession()
+
+ const copy = (text: string) => {
+ navigator.clipboard.writeText(text)
+ setIsCopy(true)
+ setTimeout(() => setIsCopy(false), 3000)
+ }
+
+ useEffect(() => {
+ let timeout = window.setTimeout(() => {
+ if (limit !== props.limit) {
+ axios.patch(
+ API_URL + '/public/api-key',
+ { token_limit: Number(limit), name: props.name },
+ { headers: { Authorization: `Bearer ${session?.access}` } }
+ )
+ }
+ }, 1000)
+ return () => window.clearTimeout(timeout)
+ }, [limit])
+
+ return (
+
+
+ {props.name}
+
+
+ {props.keyValue}
+
+
+ setLimit(e.target.value)}
+ sx={theme === 'light' ? { ...InputStyleSmallLight } : { ...InputStyleSmallDark }}
+ />
+
+
+ {props.created_at.split('T')[0]}
+
+
+ {props.expires_at !== null ? props.expires_at : 'Бессрочно'}
+
+
+
+ {isCopy ? (
+
+ ) : (
+
+ copy(props.keyValue)}
+ src={'/svg/copy.svg'}
+ width={20}
+ height={20}
+ style={{ cursor: 'pointer' }}
+ alt={'copy'}
+ />
+
+ )}
+ props.deleteKey(props.name)}
+ style={{ cursor: 'pointer' }}
+ src='/svg/main_menu/trash.svg'
+ width={20}
+ height={20}
+ alt='Удалить'
+ />
+
+
+
+ )
+}
+
+export default ApiKeys
@@ -1,6 +1,50 @@
-import AuthSocial from '#/views/auth-social/ui/auth-social'
-import { getDefaultLayout } from '#/widgets/layouts'
+import React, { useEffect } from 'react'
+import { Box } from '@mui/system'
+import axios from 'axios'
+import { useRouter } from 'next/router'
+import process from 'process'
-AuthSocial.getLayout = getDefaultLayout({ titlePage: 'Редирект' })
+import { Layout } from '@/src/main/layout'
+import { API_URL } from '@/src/shared/lib/constants'
+import { getTypeDevice } from '@/src/shared/lib/helpers'
+import { Device } from '@/src/shared/lib/types/entities'
+
+const client_secret = process.env.NEXT_PUBLIC_DJANGO_GOOGLE_APP_CLIENT_SECRET
+const client_id = process.env.NEXT_PUBLIC_DJANGO_GOOGLE_APP_CLIENT_ID
+
+export async function getServerSideProps(context: any): Promise<{ props: { device: Device } }> {
+ const device = getTypeDevice(context)
+
+ return {
+ props: {
+ device,
+ },
+ }
+}
+
+async function getTokenByAPIGoogle(token: string) {
+ const { data } = await axios.post(API_URL + '/auth/login-social/convert-token', {
+ grant_type: 'convert_token',
+ client_id: client_id,
+ client_secret: client_secret,
+ backend: 'google-oauth2',
+ token: token,
+ })
+
+ return data
+}
+
+const AuthSocial: React.FC<{ device: Device }> = ({ device }) => {
+ useEffect(() => {
+ const token = new URLSearchParams(window.location.href.replace('#', '&')).get('access_token') || ''
+ getTokenByAPIGoogle(token).then((res) => res)
+ }, [])
+
+ return (
+
+
+
+ )
+}
export default AuthSocial
@@ -1,6 +0,0 @@
-import { ChangePasswordPage } from '#/views/change-password'
-import { getLayout, LayoutWithoutSideMenu } from '#/widgets/layouts'
-
-ChangePasswordPage.getLayout = getLayout(LayoutWithoutSideMenu, { titlePage: 'Смена пароля' })
-
-export default ChangePasswordPage
@@ -1,23 +1,35 @@
-import React, { useRef, useState } from 'react'
+import React from 'react'
import { Box, Card, CardMedia, Stack, TextField, Typography } from '@mui/material'
import Button from '@mui/material/Button'
import axios from 'axios'
+import Head from 'next/head'
import Image from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/router'
-import { useAppSelector } from '#/app/store/store'
-import { API_URL } from '#/shared/lib/constants/constants'
-import { getDeviceType, getRandomImage } from '#/shared/lib/helpers'
-import { NextPageWithLayout } from '#/pages/_app'
-const ChangePassword: NextPageWithLayout = () => {
- const device = getDeviceType()
+import { Layout } from '@/src/main/layout'
+import { useAppSelector } from '@/src/main/store/store'
+import { getRandomImage } from '@/src/pages/login'
+import { API_URL } from '@/src/shared/lib/constants/constants'
+import { getTypeDevice } from '@/src/shared/lib/helpers'
+import { TDeviceProp } from '@/src/shared/lib/types/entities'
- const [password1, setPassword1] = useState('')
+export async function getServerSideProps(context: any): Promise<{ props: TDeviceProp }> {
+ const device = getTypeDevice(context)
- const [password2, setPassword2] = useState('')
+ return {
+ props: {
+ device,
+ },
+ }
+}
+
+const ChangePassword: React.FC = ({ device }) => {
+ const [password1, setPassword1] = React.useState('')
- const [isChange, setIsChange] = useState(false)
+ const [password2, setPassword2] = React.useState('')
+
+ const [isChange, setIsChange] = React.useState(false)
const { query, push } = useRouter()
@@ -42,12 +54,18 @@ const ChangePassword: NextPageWithLayout = () => {
const desktop = device === 'desktop'
- const refImage = useRef(getRandomImage())
+ const refImage = React.useRef(getRandomImage())
const theme = useAppSelector((state) => state.theme.theme)
return (
- <>
+
+
+ Восстановление аккаунта
+
+
+
+
{
{desktop && (
-
+
{