(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
+export default ImageModelsPage
\ No newline at end of file
@@ -4,7 +4,7 @@ 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'
+import { addReferral } from '#/entities/user-account/model/user-type-slice'
export async function getServerSideProps({ params }: { params: Promise<{ email: string }> }) {
const email = (await params).email
@@ -3,8 +3,8 @@ import { Box, Typography } from '@mui/material'
import Link from 'next/link'
import { useRouter } from 'next/router'
-import { Layout } from '@/src/main/layout'
-import { useAppSelector } from '@/src/main/store/store'
+import { Layout } from '#/app/layout'
+import { useAppSelector } from '#/app/store/store'
const Custom404 = () => {
const theme = useAppSelector((state) => state.theme.theme)
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { ReactElement, ReactNode } from 'react'
import { Provider } from 'react-redux'
import { StyledEngineProvider } from '@mui/material'
import axios from 'axios'
@@ -8,12 +8,13 @@ import { Raleway } from 'next/font/google'
import { SessionProvider } from 'next-auth/react'
import { appWithTranslation } from 'next-i18next'
-import { store } from '@/src/main/store/store'
+import { store } from '#/app/store/store'
import ErrorBoundary from './error-boundary'
-import '@/src/main/styles/globals.css'
-import '@/src/main/styles/styles-pages/system.scss'
+import '#/app/styles/globals.css'
+import '#/app/styles/styles-pages/system.scss'
+import { NextPage } from 'next'
axios.defaults.httpsAgent = new https.Agent({
rejectUnauthorized: false,
@@ -21,7 +22,17 @@ axios.defaults.httpsAgent = new https.Agent({
const inter = Raleway({ subsets: ['latin'] })
-function App({ Component, pageProps: { session, ...pageProps } }: AppProps) {
+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)
return (
<>
@@ -35,7 +46,7 @@ function App({ Component, pageProps: { session, ...pageProps } }: AppProps) {
-
+ {getLayout()}
@@ -27,7 +27,11 @@ export default function Document() {
@@ -8,22 +8,22 @@ import { useRouter } from 'next/router'
import { getServerSession } from 'next-auth'
import { signOut, useSession } from 'next-auth/react'
-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'
+import { getUserBalance } from '#/entities/balance'
+import { getAllInfo, unfollowEmail } from '#/entities/user-account/model/user-type-slice'
+import { Layout } from '#/app/layout'
+import { useAppDispatch, useAppSelector } from '#/app/store/store'
+import styles2 from '#/app/styles/accountTabs.module.css'
+import styles from '#/app/styles/business.module.scss'
+import { ButtonUI, Input, Loader, Modal, Success, SwitchCustom, useShowData } from '#/shared'
+import { accountApi } from '#/shared/api/account-endpoints'
+import { API_URL } from '#/shared/lib/constants/constants'
+import { getAccessToken, getTypeDevice } from '#/shared/lib/helpers'
+import { IProps } from '#/shared/lib/types/entities'
+import { ScreenForInactive } from '#/widgets/business'
+import BusinessHost from '#/widgets/business-host/business-host'
+import { Info } from '#/widgets/business-info'
+import { Subscription } from '#/widgets/payment/model/payment'
+import { Referral } from '#/widgets/referral'
import { DownloadModal } from '../features/business-security-download/ui/download-modal'
@@ -201,7 +201,11 @@ const Account: React.FC = ({ device, token, plans }) => {
)
}
if (type === 'business_account') {
- return Информация о корп.аккаунте доступна только владельцу и администраторам.
+ return (
+
+ Информация о корп.аккаунте доступна только владельцу и администраторам.
+
+ )
}
if (type === 'business_host') {
return
@@ -354,7 +358,11 @@ const Account: React.FC = ({ device, token, plans }) => {
disableRipple
onClick={() => changeScope(el.scope)}
key={el.title}
- className={scope === el.scope ? styles2.wrap_toggle_button_active : styles2.wrap_toggle_button}
+ className={
+ scope === el.scope
+ ? styles2.wrap_toggle_button_active
+ : styles2.wrap_toggle_button
+ }
value={el.scope}
label={el.title}
/>
@@ -367,7 +375,13 @@ const Account: React.FC = ({ device, token, plans }) => {
Основные
-
+
= ({ device, token, plans }) => {
}}
>
{!loading || !(userInfoLoaded === 'succeeded') ? (
-
+
) : (
)}
@@ -412,7 +431,9 @@ const Account: React.FC = ({ device, token, plans }) => {
/>
- Фамилия
+
+ Фамилия
+
= ({ device, token, plans }) => {
/>
-
- Email
-
+
+
+ Email
+
+
{
@@ -445,10 +476,16 @@ const Account: React.FC = ({ device, token, plans }) => {
- Никнейм
+
+ Никнейм
+
-
+
{/*referral_code.code.trim() && (
Ваша реферальная ссылка:
@@ -484,7 +521,9 @@ const Account: React.FC = ({ device, token, plans }) => {
Изменить пароль
- Текущий пароль
+
+ Текущий пароль
+
= ({ device, token, plans }) => {
fullWidth
/>
-
+
- Новый пароль
+
+ Новый пароль
+
= ({ device, token, plans }) => {
/>
- Подтвердить пароль
+
+ Подтвердить пароль
+
= ({ device, token, plans }) => {
)}
Удаление аккаунта
- Удаление аккаунта приведет к потере всех настроек
+
+ Удаление аккаунта приведет к потере всех настроек
+
setConfirmDeleteModal(true)}
@@ -540,8 +592,15 @@ const Account: React.FC = ({ device, token, plans }) => {
setConfirmDeleteModal(false)}>
Удаление аккаунта
- Вы действительно хотите удалить ваш аккаунт?
-
@@ -2,11 +2,11 @@ import React from 'react'
import { Stack } from '@mui/material'
import { getSession } from 'next-auth/react'
-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'
+import { Layout } from '#/app/layout'
+import { useAppSelector } from '#/app/store/store'
+import { getAccessToken, getTypeDevice } from '#/shared/lib/helpers'
+import { IProps } from '#/shared/lib/types/entities'
+import { StatsField } from '#/widgets/stats-field'
export async function getServerSideProps(context: any): Promise<{ props: any }> {
const device = getTypeDevice(context)
@@ -39,7 +39,12 @@ const Admin: React.FC = ({ token, device }) => {
return (
-
+
@@ -7,15 +7,15 @@ import Image from 'next/image'
import Link from 'next/link'
import { useSession } from 'next-auth/react'
-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'
+import { getAll, ResponseAllInfo } from '#/entities/user-account/model/user-type-slice'
+import { ApiKeyModal } from '#/features/api-key-modal/api-key-modal'
+import { Layout } from '#/app/layout'
+import { useAppSelector } from '#/app/store/store'
+import { TooltipCustom } from '#/shared'
+import { accountApi } from '#/shared/api/account-endpoints'
+import { API_URL } from '#/shared/lib/constants'
+import styles from '#/shared/styles/api-keys.module.scss'
+import { InputStyleSmallDark, InputStyleSmallLight } from '#/shared/ui/input'
const ApiKeys: React.FC = () => {
const [keys, setKeys] = useState | null>(null)
@@ -78,15 +78,27 @@ const ApiKeys: React.FC = () => {
- API-ключ — это инструмент, который идентифицирует пользователя или программу, запрашивающих доступ к API платформы.
- С помощью ключа можно отслеживать, кто и когда пользуется API, рассчитывать оплату.
+ API-ключ — это инструмент, который идентифицирует пользователя или программу,
+ запрашивающих доступ к API платформы. С помощью ключа можно отслеживать, кто и когда
+ пользуется API, рассчитывать оплату.
- setModal(true)} disabled={disabled} className='btn-classic' sx={{ width: '130px' }}>
+ setModal(true)}
+ disabled={disabled}
+ className='btn-classic'
+ sx={{ width: '130px' }}
+ >
Создать ключ
-
+
Документация
@@ -98,7 +110,13 @@ const ApiKeys: React.FC = () => {
Мои ключи
-
+
Имя
Ключ
Лимит токенов
@@ -125,7 +143,13 @@ const ApiKeys: React.FC = () => {
) : (
-
+
У вас пока нет ключей 😞
Создайте первый ключ
@@ -4,10 +4,10 @@ import axios from 'axios'
import { useRouter } from 'next/router'
import process from 'process'
-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'
+import { Layout } from '#/app/layout'
+import { API_URL } from '#/shared/lib/constants'
+import { getTypeDevice } from '#/shared/lib/helpers'
+import { Device } from '#/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
@@ -7,12 +7,12 @@ import Image from 'next/image'
import Link from 'next/link'
import { useRouter } from 'next/router'
-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'
+import { Layout } from '#/app/layout'
+import { useAppSelector } from '#/app/store/store'
+import { getRandomImage } from '#/pages/login'
+import { API_URL } from '#/shared/lib/constants/constants'
+import { getTypeDevice } from '#/shared/lib/helpers'
+import { TDeviceProp } from '#/shared/lib/types/entities'
export async function getServerSideProps(context: any): Promise<{ props: TDeviceProp }> {
const device = getTypeDevice(context)
@@ -90,7 +90,10 @@ const ChangePassword: React.FC = ({ device }) => {
{desktop && (
-
+
{
const UA = context.req.headers['user-agent']
@@ -1,88 +1,7 @@
-import * as React from 'react'
-import { useMemo } from 'react'
-import { useCookies } from 'react-cookie'
-import { Box, Stack, Typography } from '@mui/material'
-import { serialize } from 'cookie'
-import { GetServerSidePropsContext } from 'next'
-import { useRouter } from 'next/router'
-import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
+import { MainPage } from '#/views/index'
+import { getDefaultLayout } from '#/widgets/layouts'
-import { Layout } from '@/src/main/layout'
-import { useAppSelector } from '@/src/main/store/store'
-import styles from '@/src/main/styles/styles-pages/index-styles.module.scss'
-import { ReferralBlock } from '@/src/shared'
-import { getTypeDevice } from '@/src/shared/lib/helpers'
-import { getCurrentTimeAndGreeting } from '@/src/shared/lib/helpers/getCurrentDateForMainScreen'
-import { TelegramBlock } from '@/src/shared/ui/telegram-block'
-import { DemoInfo } from '../shared/ui/demo-info'
-import { SocialMedia } from '../shared/ui/social-media-block'
-import { Statistics } from '../widgets/stats/stats'
+MainPage.getLayout = getDefaultLayout({ titlePage: 'AIR' })
-export async function getServerSideProps(context: GetServerSidePropsContext): Promise<{ props: any }> {
- const deviceType = getTypeDevice(context)
-
- const { res, query } = context
-
- const allCookies = Object.entries(query).map((key, value) => serialize(key.toString(), value.toString()))
-
- res.setHeader('Set-Cookie', allCookies)
- res.setHeader('Set-Cookie', '111')
- return {
- props: {
- ...(await serverSideTranslations((context as any).locale, ['common'])),
- deviceType,
- },
- }
-}
-
-export const Main: React.FC = ({ deviceType }) => {
- const { first_name, account_type } = useAppSelector((state) => state.user)
-
- const [, setCookie] = useCookies()
-
- const { query, push } = useRouter()
-
- React.useEffect(() => {
- Object.entries(query).forEach(([key, value]) => setCookie(key, value))
- }, [])
-
- const [greeting, time] = useMemo(() => getCurrentTimeAndGreeting(first_name), [first_name])
-
- return (
-
-
-
- {time}
- {greeting}
-
-
-
- {/**/}
-
- {account_type === 'regular' && }
-
-
- Полезная статья
-
-
- {' '}
- Что такое токен ?
-
-
- Токен — это цифровая валюта для оплаты ИИ-продуктов и услуг. Юзеры используют эту валюту, чтобы
- получить либо доступ к нейросетям, либо результат генерации — текст, картинку и т.д. Еще токенами
- называют единицы текста, на которых обучается нейросеть. Например, в предложении «Я люблю шоколад»
- слова «Я», «люблю» и «шоколад» могут быть токенами.
-
-
-
-
-
-
-
-
- )
-}
-
-export default Main
+export default MainPage
@@ -11,16 +11,16 @@ import Router from 'next/router'
import Script from 'next/script'
import { signIn } from 'next-auth/react'
-import { authTelegram } from '@/src/features/auth-telegram'
-import { PasswordOptions } from '@/src/features/register-by-email/lib/constants'
-import { IEmailForms } from '@/src/features/register-by-email/model/types'
-import { Layout } from '@/src/main/layout'
-import { useAppSelector } from '@/src/main/store/store'
-import { emailOptions, Error } from '@/src/shared'
-import { getTypeDevice } from '@/src/shared/lib/helpers'
-import { useShowData } from '@/src/shared/lib/hooks'
-import { TDeviceProp } from '@/src/shared/lib/types/entities'
-import { InputStyleDark, InputStyleLight } from '@/src/shared/ui/input'
+import { authTelegram } from '#/features/auth-telegram'
+import { PasswordOptions } from '#/features/register-by-email/lib/constants'
+import { IEmailForms } from '#/features/register-by-email/model/types'
+import { Layout } from '#/app/layout'
+import { useAppSelector } from '#/app/store/store'
+import { emailOptions, Error } from '#/shared'
+import { getTypeDevice } from '#/shared/lib/helpers'
+import { useShowData } from '#/shared/lib/hooks'
+import { TDeviceProp } from '#/shared/lib/types/entities'
+import { InputStyleDark, InputStyleLight } from '#/shared/ui/input'
export async function getServerSideProps(context: any): Promise<{ props: TDeviceProp }> {
const device = getTypeDevice(context)
@@ -116,7 +116,15 @@ const Login: React.FC = ({ device }) => {
backgroundColor: theme === 'light' ? 'white' : '#303035',
}}
>
- {!desktop && }
+ {!desktop && (
+
+ )}
= ({ device }) => {
},
}}
>
-
+
Войти с Яндекс ID
или email
@@ -286,10 +300,20 @@ const Login: React.FC = ({ device }) => {
justifyContent: 'center',
}}
>
-
+
)}
-
+
= ({ device }) => {
{desktop && (
-
-
+
+
{
const UA = context.req.headers['user-agent']
@@ -67,7 +67,15 @@ const Register: React.FC = ({ device }) => {
backgroundColor: theme === 'light' ? 'white' : '#303035',
}}
>
- {!desktop && }
+ {!desktop && (
+
+ )}
= ({ device }) => {
Вы успешно зарегистрированы.
- Мы отправили письмо для верификации на ваш email. В случае отсутствия, проверьте папку Спам.
+ Мы отправили письмо для верификации на ваш email. В случае отсутствия,
+ проверьте папку Спам.
- Если вы регистрировались с корпоративной почты и письмо-подтверждение вам не пришло, рекомендуем
- зарегистрироваться с личной почты
+ Если вы регистрировались с корпоративной почты и письмо-подтверждение вам
+ не пришло, рекомендуем зарегистрироваться с личной почты
) : (
@@ -150,7 +159,9 @@ const Register: React.FC = ({ device }) => {
/>
Войти с Яндекс ID
- или email
+
+ или email
+
>
)}
@@ -159,8 +170,22 @@ const Register: React.FC = ({ device }) => {
{desktop && (
-
-
+
+
{
Спасибо!
- Ваше сообщение направлено нашим специалистам. Ответ придет на почту, указанную при регистрации
+ Ваше сообщение направлено нашим специалистам. Ответ придет на почту, указанную при
+ регистрации
) : (
@@ -169,7 +170,12 @@ const ReportsMobile = () => {
height: 25,
}}
/>
-
+
>
),
@@ -187,7 +193,9 @@ const ReportsMobile = () => {
/>
{file && (
- Добавлено 1 изображение: {file.name}
+
+ Добавлено 1 изображение: {file.name}
+
setFile(undefined)}
sx={{
@@ -200,7 +208,13 @@ const ReportsMobile = () => {
/>
)}
-
+
{
const device = getTypeDevice(context)
@@ -64,7 +64,10 @@ const Reset: React.FC = ({ device }) => {
>
{desktop && (
-
+
= ({ device }) => {
alignItems: 'center',
}}
>
-
+
Забыли пароль?
- Введите адрес электронной почты, которую вы использовали для регистрации в сервисе
+ Введите адрес электронной почты, которую вы использовали для регистрации в
+ сервисе
Email
- set_Email(event.target.value)} type={'email'} fullWidth />
+ set_Email(event.target.value)}
+ type={'email'}
+ fullWidth
+ />
= ({ device }) => {
-
+
Восстановить аккаунт
@@ -1,10 +1,10 @@
import React from 'react'
import { Box } from '@mui/material'
-import { Layout } from '@/src/main/layout'
-import { getTypeDevice } from '@/src/shared/lib/helpers'
-import { Device } from '@/src/shared/lib/types/entities'
-import { WhisperWidget } from '@/src/widgets/whisper'
+import { Layout } from '#/app/layout'
+import { getTypeDevice } from '#/shared/lib/helpers'
+import { Device } from '#/shared/lib/types/entities'
+import { WhisperWidget } from '#/widgets/whisper'
export async function getServerSideProps(context: any): Promise<{ props: { device: Device } }> {
const device = getTypeDevice(context)
@@ -1,7 +1,7 @@
import axios from 'axios'
-import { IModel, IShortModel } from '@/src/shared/api/models/models'
-import { API_URL } from '@/src/shared/lib/constants'
+import { IModel, IShortModel } from '#/shared/api/models/models'
+import { API_URL } from '#/shared/lib/constants'
const model_api = {
async getBots(token?: string): Promise {
@@ -4,12 +4,12 @@ import base64 from 'base64-encode-file'
import { useSession } from 'next-auth/react'
import process from 'process'
-import { getUserBalance } from '@/src/entities/balance'
-import { useAppDispatch } from '@/src/main/store/store'
-import { API_URL } from '@/src/shared/lib/constants'
-import { Device } from '@/src/shared/lib/types/entities'
-import { Message, MessageSend } from '@/src/shared/lib/types/model'
-import { IMessageRequest } from '@/src/shared/lib/types/types-gpt'
+import { getUserBalance } from '#/entities/balance'
+import { useAppDispatch } from '#/app/store/store'
+import { API_URL } from '#/shared/lib/constants'
+import { Device } from '#/shared/lib/types/entities'
+import { Message, MessageSend } from '#/shared/lib/types/model'
+import { IMessageRequest } from '#/shared/lib/types/types-gpt'
const formDataHelper = (file: File, dataForSend: MessageSend): FormData => {
const FD = new FormData()
@@ -23,11 +23,14 @@ const formDataHelper = (file: File, dataForSend: MessageSend): FormData =>
export const ModelsWithChatsEndpoints = {
getData: async (chatUid: string, offset: number, token?: string) => {
try {
- const { data } = await axios.get(API_URL + `/chats/${chatUid}/messages/?limit=10&offset=${offset}`, {
- headers: {
- Authorization: `Bearer ${token}`,
- },
- })
+ const { data } = await axios.get(
+ API_URL + `/chats/${chatUid}/messages/?limit=10&offset=${offset}`,
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ )
return data
} catch (err: any) {
return {
@@ -41,13 +44,17 @@ export const ModelsWithChatsEndpoints = {
const HeaderDataType = dataForSend instanceof FormData ? 'multipart/form-data' : 'application/json'
try {
- const { data } = await axios.post>(API_URL + `/chats/${chatUid}/messages/`, dataForSend, {
- withCredentials: true,
- headers: {
- Authorization: `Bearer ${token}`,
- 'Content-Type': HeaderDataType,
- },
- })
+ const { data } = await axios.post>(
+ API_URL + `/chats/${chatUid}/messages/`,
+ dataForSend,
+ {
+ withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${token}`,
+ 'Content-Type': HeaderDataType,
+ },
+ }
+ )
return data
} catch (err: any) {
@@ -165,7 +172,7 @@ export function useModel(
setMessages((prev) => [...prev!, userMessage])
try {
//@ts-ignore
- const message = (result.details as AxiosError).response.data.trim() ?? 'Ошибка отправки сообщения'
+ const message = (result.details as AxiosError).response!.data.trim() ?? 'Ошибка отправки сообщения'
showError(message)
return
} catch (e) {
@@ -212,13 +219,17 @@ export const ModelsWithImagesEndpoints = {
const HeaderDataType = dataForSend instanceof FormData ? 'multipart/form-data' : 'application/json'
try {
- const { data } = await axios.post>(API_URL + `/media/image/${type}`, dataForSend, {
- withCredentials: true,
- headers: {
- Authorization: `Bearer ${token}`,
- 'Content-Type': HeaderDataType,
- },
- })
+ const { data } = await axios.post>(
+ API_URL + `/media/image/${type}`,
+ dataForSend,
+ {
+ withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${token}`,
+ 'Content-Type': HeaderDataType,
+ },
+ }
+ )
return data
} catch (err: any) {
@@ -375,12 +386,16 @@ export const ModelsMediaApi = {
},
sendData: async (type: string | null, dataForSend: MessageSend | FormData, token?: string) => {
try {
- const { data } = await axios.post>(API_URL + `/media/audio/${type}`, dataForSend, {
- withCredentials: true,
- headers: {
- Authorization: `Bearer ${token}`,
- },
- })
+ const { data } = await axios.post>(
+ API_URL + `/media/audio/${type}`,
+ dataForSend,
+ {
+ withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ )
return data
} catch (err: any) {
@@ -1,8 +1,8 @@
import axios, { AxiosResponse } from 'axios'
import { User } from 'next-auth'
-import { API_URL } from '@/src/shared/lib/constants'
-import { IOffer } from '@/src/widgets/payment/model/payment'
+import { API_URL } from '#/shared/lib/constants'
+import { IOffer } from '#/widgets/payment/model/payment'
interface IUserBalance {
current_token_balance: number
@@ -61,7 +61,12 @@ export const accountApi = {
}
},
- async changePassword(token: string | null, password_1: string, password_2: string, current_password: string): Promise {
+ async changePassword(
+ token: string | null,
+ password_1: string,
+ password_2: string,
+ current_password: string
+ ): Promise {
try {
const { status } = await axios.put(
API_URL + '/auth/reset-pass',
@@ -2,10 +2,10 @@ import axios, { AxiosResponse } from 'axios'
import { Session } from 'next-auth'
import * as process from 'process'
-import { Chat } from '@/src/shared/api/type-model-chats'
-import { Error } from '@/src/shared/lib/types/entities'
-import { IImagesResponse } from '@/src/shared/lib/types/types-dalle'
-import { IMessageRequest, ISendMessageResponse } from '@/src/shared/lib/types/types-gpt'
+import { Chat } from '#/shared/api/type-model-chats'
+import { Error } from '#/shared/lib/types/entities'
+import { IImagesResponse } from '#/shared/lib/types/types-dalle'
+import { IMessageRequest, ISendMessageResponse } from '#/shared/lib/types/types-gpt'
import { Message } from '../lib/types/model'
@@ -96,12 +96,16 @@ export const api = {
async sendMessageChatGPT(token: string, message: any, uid: string): Promise {
try {
- const { data } = await axios.post>(API_URL + `/chats/${uid}/messages/`, message, {
- withCredentials: true,
- headers: {
- Authorization: `Bearer ${token}`,
- },
- })
+ const { data } = await axios.post>(
+ API_URL + `/chats/${uid}/messages/`,
+ message,
+ {
+ withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ )
return { data, isError: false }
} catch (err) {
@@ -157,7 +161,9 @@ export const createChat = async (model: string, token?: string) => {
export const getAllChats = async (model: string, token?: string): Promise => {
try {
- const { data } = await axios.get(API_URL + `/chats/?model=${model}`, { headers: { Authorization: `Bearer ${token}` } })
+ const { data } = await axios.get(API_URL + `/chats/?model=${model}`, {
+ headers: { Authorization: `Bearer ${token}` },
+ })
if (data.length === 0) {
const newChat = await createChat(model, token)
@@ -1,32 +1,30 @@
.card {
- width: 381px;
- overflow: hidden;
- position: relative;
- height: 290px;
- border-radius: 15px;
- background-color: var(--new-ui-main-color);
- margin-top: 15px;
- margin-right: 20px;
+ width: 381px;
+ overflow: hidden;
+ position: relative;
+ height: 290px;
+ border-radius: 15px;
+ background-color: var(--new-ui-main-color);
+ margin-top: 15px;
+ margin-right: 20px;
- @media (max-width:420px) {
- width: 92vw;
- height: 300px;
- }
-
- .description {
- padding: 15px 20px;
+ @media (max-width: 420px) {
+ width: 92vw;
+ height: 300px;
+ }
- .title {
- color: var(--new-ui-text-color);
- font-weight: 600;
- font-size: 21px;
- }
- .text {
- margin-top: 15px;
- font-size: 15px;
- color: var(--new-ui-gray-color);
- }
- }
+ .description {
+ padding: 15px 20px;
-
-}
\ No newline at end of file
+ .title {
+ color: var(--new-ui-text-color);
+ font-weight: 600;
+ font-size: 21px;
+ }
+ .text {
+ margin-top: 15px;
+ font-size: 15px;
+ color: var(--new-ui-gray-color);
+ }
+ }
+}
@@ -16,9 +16,7 @@ interface IProps {
export const Card = ({ text, icon, title, uid, slug, accessed_models }: IProps) => {
const link = useMemo(() => {
- return accessed_models && !accessed_models.includes(slug)
- ? '/account?scope=subscribe'
- : `/images/${slug}`
+ return accessed_models && !accessed_models.includes(slug) ? '/account?scope=subscribe' : `/images/${slug}`
}, [accessed_models])
return (
@@ -63,11 +61,7 @@ export const Card = ({ text, icon, title, uid, slug, accessed_models }: IProps)
textAlign: 'center',
}}
>
-
+
()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/iu
+const EMAIL_REGEXP =
+ /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/iu
const PHONE_REGEXP = /^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$/
export const emailOptions: RegisterOptions = {
@@ -1,4 +1,4 @@
-import { colorDark, colorLight } from '@/src/shared/lib/constants/colors'
+import { colorDark, colorLight } from '#/shared/lib/constants/colors'
export const TypographyLight = {
fontWeight: 600,
@@ -1,7 +1,10 @@
import { GetServerSidePropsContext } from 'next'
-import { Device, DeviceOs } from '@/src/shared/lib/types/entities'
+import { Device, DeviceOs } from '#/shared/lib/types/entities'
+/**
+ * @deprecated
+ */
export const getTypeDevice = (context: GetServerSidePropsContext): Device => {
const UA = context.req.headers['user-agent']
@@ -14,6 +17,22 @@ export const getTypeDevice = (context: GetServerSidePropsContext): Device => {
return isMobile ? 'mobile' : 'desktop'
}
+export const getDeviceType = (): Device => {
+ const UA = navigator.userAgent
+
+ if (!UA) {
+ return 'desktop'
+ }
+
+ const isMobile = Boolean(UA.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i))
+
+ return isMobile ? 'mobile' : 'desktop'
+}
+
+
+/**
+ * @deprecated
+ */
export const getDeviceOs = (context: GetServerSidePropsContext): DeviceOs => {
const UA = context.req.headers['user-agent']
@@ -25,3 +44,15 @@ export const getDeviceOs = (context: GetServerSidePropsContext): DeviceOs => {
return isIos ? 'ios' : 'android'
}
+
+export const getOs = (): DeviceOs => {
+ const UA = navigator.userAgent
+
+ if (!UA) {
+ return 'android'
+ }
+
+ const isIos = UA.includes('iPhone') || UA.includes('iPad')
+
+ return isIos ? 'ios' : 'android'
+}
@@ -12,7 +12,20 @@ export function getCurrentTimeAndGreeting(userName: string) {
greeting = 'Добрый вечер'
}
- const months = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']
+ const months = [
+ 'января',
+ 'февраля',
+ 'марта',
+ 'апреля',
+ 'мая',
+ 'июня',
+ 'июля',
+ 'августа',
+ 'сентября',
+ 'октября',
+ 'ноября',
+ 'декабря',
+ ]
const formattedDate = `Сегодня, ${day} ${months[monthIndex]} ${year}`
const greetingMessage = `${greeting}, ${userName}! 👋`
@@ -1,3 +1,4 @@
export { getAccessToken } from './get-token'
export { getTypeDevice } from './get-type-device'
export { useConcat } from './reactive-concat'
+export * from './get-type-device'
@@ -7,7 +7,7 @@ export class LocalStorageHelper {
this.modelTitle = key.toLowerCase()
}
- public readonly getSettingFromLS = (key: string, defaultValue: any, availableModels?:any[]) => {
+ public readonly getSettingFromLS = (key: string, defaultValue: any, availableModels?: any[]) => {
const finalKey = this.modelTitle + ': ' + key
if (typeof localStorage !== 'undefined') {
@@ -7,7 +7,10 @@ export const useAutoLoad = (desktop: boolean): [boolean, Dispatch {
- if (e.target.documentElement.scrollHeight - (e.target.documentElement.scrollTop + window.innerHeight) < 100) {
+ if (
+ e.target.documentElement.scrollHeight - (e.target.documentElement.scrollTop + window.innerHeight) <
+ 100
+ ) {
setFetching(true)
}
}
@@ -1,4 +1,4 @@
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
interface IThemeAndDevice {
theme: 'dark' | 'light'
@@ -1,7 +1,7 @@
import React from 'react'
-import { IModelInputs } from '@/src/shared/api/models/models'
-import { Device, DeviceOs } from '@/src/shared/lib/types/entities'
+import { IModelInputs } from '#/shared/api/models/models'
+import { Device, DeviceOs } from '#/shared/lib/types/entities'
export type MessageSend = {
content: string
@@ -49,4 +49,6 @@ export type ChatProps = {
currentVersion: string
}
-export type FiltersChatProps = Pick, 'device' | 'setting'> & { resetSettings: () => void }
+export type FiltersChatProps = Pick, 'device' | 'setting'> & {
+ resetSettings: () => void
+}
@@ -1,4 +1,4 @@
-import { IProps } from '@/src/shared/lib/types/entities'
+import { IProps } from '#/shared/lib/types/entities'
export interface IImagesResponse {
question: string
@@ -1,4 +1,4 @@
-import { IProps } from '@/src/shared/lib/types/entities'
+import { IProps } from '#/shared/lib/types/entities'
export interface IMessageResponse {
question: string
@@ -1,4 +1,4 @@
-import { IProps } from '@/src/shared/lib/types/entities'
+import { IProps } from '#/shared/lib/types/entities'
export interface IResponseSD {
question: string
@@ -1,3 +1,3 @@
-import { RootState } from '@/src/main/store/store'
+import { RootState } from '#/app/store/store'
export const balanceSelector = (state: RootState) => Math.floor(state.balance.balance)
@@ -1,12 +1,11 @@
.wrap {
- width: 85%;
+ width: 85%;
- @media (max-width: 1200px) {
- width: 95%;
- }
+ @media (max-width: 1200px) {
+ width: 95%;
+ }
- @media (max-width: 768px) {
- width: 100%;
- }
-
-}
\ No newline at end of file
+ @media (max-width: 768px) {
+ width: 100%;
+ }
+}
@@ -1,44 +1,44 @@
.main {
- width: 100%;
- display: flex;
- justify-content: flex-start;
- gap: 20px;
- margin-bottom: 24px;
+ width: 100%;
+ display: flex;
+ justify-content: flex-start;
+ gap: 20px;
+ margin-bottom: 24px;
- .chatWindow {
- width: 70%;
- }
+ .chatWindow {
+ width: 70%;
+ }
- .settings {
- width: 25%;
- }
+ .settings {
+ width: 25%;
+ }
- @media (max-width:768px) {
- width: 100%;
- display: flex;
-
- flex-direction: column-reverse;
-
- .chatWindow {
- width: 100%;
- }
+ @media (max-width: 768px) {
+ width: 100%;
+ display: flex;
- .settings {
- width: 100%;
- }
- }
+ flex-direction: column-reverse;
+
+ .chatWindow {
+ width: 100%;
+ }
+
+ .settings {
+ width: 100%;
+ }
+ }
}
-.wrapModelTitle{
- margin-bottom: 20px;
- margin-top: 15px;
- @media (max-width:768px) {
- margin: 0;
- margin-top: 15px;
- }
- .bigTitle {
- @media (max-width:768px) {
- display: none;
- overflow: hidden;
- }
- }
+.wrapModelTitle {
+ margin-bottom: 20px;
+ margin-top: 15px;
+ @media (max-width: 768px) {
+ margin: 0;
+ margin-top: 15px;
+ }
+ .bigTitle {
+ @media (max-width: 768px) {
+ display: none;
+ overflow: hidden;
+ }
+ }
}
@@ -1,82 +1,77 @@
+.wrap {
+ width: 100%;
+ background-color: var(--new-ui-main-color);
+ border-radius: 15px;
+ padding: 30px;
+ height: fit-content;
+ //margin-bottom: 15px;
+ max-height: 350px;
+ overflow-y: auto;
+ @media (max-width: 768px) {
+ padding: 10px 20px;
+ }
-.wrap {
- width: 100%;
- background-color: var(--new-ui-main-color);
- border-radius: 15px;
- padding: 30px;
- height: fit-content;
- //margin-bottom: 15px;
- max-height: 350px;
- overflow-y: auto;
+ .container {
+ display: block;
- @media (max-width:768px) {
- padding: 10px 20px;
- }
+ @media (max-width: 768px) {
+ display: flex;
+ overflow-x: scroll;
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+ &::-webkit-scrollbar {
+ width: 2px;
+ }
+ }
- .container {
- display: block;
-
- @media (max-width:768px) {
- display: flex;
- overflow-x: scroll;
- scrollbar-width: none;
- -ms-overflow-style: none;
- &::-webkit-scrollbar {
- width: 2px ;
- }
- }
+ .item {
+ padding: 0;
+ border: none;
+ width: 100%;
- .item {
- padding: 0;
- border:none;
- width: 100%;
-
-
- &:hover {
- background-color: transparent;
- }
-
- .main {
- display: flex;
- width: 100%;
- border:none;
- justify-content: space-between;
- background-color:transparent;
- border-radius:13px;
- padding:12px 15px;
- text-transform: none;
-
- &_active {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- border:none;
- border-radius:13px;
- padding:12px 15px;
- text-transform: none;
- background-color:rgba(130, 128, 255, 0.15);
-
- @media (max-width:768px) {
- margin-right: 10px;
- margin-top: 10px;
- width: 125px;
- max-width: 130px;
- overflow: hidden;
- padding: 8px 12px;
- justify-content: space-between;
- }
- }
-
- @media (max-width:768px) {
- margin-top: 10px;
- width: 100px;
- padding: 0;
- }
- }
- }
-
- }
-}
+ &:hover {
+ background-color: transparent;
+ }
+
+ .main {
+ display: flex;
+ width: 100%;
+ border: none;
+ justify-content: space-between;
+ background-color: transparent;
+ border-radius: 13px;
+ padding: 12px 15px;
+ text-transform: none;
+ &_active {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ border: none;
+ border-radius: 13px;
+ padding: 12px 15px;
+ text-transform: none;
+ background-color: rgba(130, 128, 255, 0.15);
+
+ @media (max-width: 768px) {
+ margin-right: 10px;
+ margin-top: 10px;
+ width: 125px;
+ max-width: 130px;
+ overflow: hidden;
+ padding: 8px 12px;
+ justify-content: space-between;
+ }
+ }
+
+ @media (max-width: 768px) {
+ margin-top: 10px;
+ width: 100px;
+ padding: 0;
+ }
+ }
+ }
+ }
+}
@@ -1,5 +1,5 @@
.button {
- background-color: #8280FF;
+ background-color: #8280ff;
border-radius: 13px;
text-transform: none;
color: white;
@@ -7,7 +7,7 @@ import Typography from '@mui/material/Typography'
import Image from 'next/image'
import Link from 'next/link'
-import { translateTypeModel } from '@/src/shared'
+import { translateTypeModel } from '#/shared'
export const Card: React.FC = ({
uid,
@@ -160,9 +160,19 @@ export const Card: React.FC = ({
}
>
{is_favourite ? (
-
+
) : (
-
+
)}
@@ -5,8 +5,8 @@ import CardMedia from '@mui/material/CardMedia'
import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography'
-import { translateTypeModel } from '@/src/shared'
-import { Device } from '@/src/shared/lib/types/entities'
+import { translateTypeModel } from '#/shared'
+import { Device } from '#/shared/lib/types/entities'
export const UnActiveCard: React.FC = ({ title, image_link, languages, description, model_config, device }) => {
const desktop = device === 'desktop'
@@ -3,7 +3,7 @@ import { DateTimePicker, LocalizationProvider } from '@mui/x-date-pickers'
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'
import dayjs, { Dayjs } from 'dayjs'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
import styles from './date.module.scss'
@@ -44,7 +44,13 @@ export const DateInput = ({
width: '100%',
}}
label={label ? label : 'Дата'}
- value={date ? dayjs(new Date().toDateString()) : prevdate ? dayjs(new Date().toDateString()).add(-1, 'year') : null}
+ value={
+ date
+ ? dayjs(new Date().toDateString())
+ : prevdate
+ ? dayjs(new Date().toDateString()).add(-1, 'year')
+ : null
+ }
onChange={(date) => {
if (date?.isValid()) {
setDate(JSON.stringify(date).split('"')[1].split('T')[0])
@@ -1,5 +1,5 @@
.button {
- background-color: #8280FF;
+ background-color: #8280ff;
border-radius: 13px;
text-transform: none;
color: white;
@@ -69,7 +69,12 @@ export const dataLine = {
return null
}
- const gradient = ctx.createLinearGradient(chartArea.left, chartArea.bottom, chartArea.left, chartArea.top)
+ const gradient = ctx.createLinearGradient(
+ chartArea.left,
+ chartArea.bottom,
+ chartArea.left,
+ chartArea.top
+ )
gradient.addColorStop(0.68, 'rgba(130, 128, 255, 0.20)')
gradient.addColorStop(1, 'rgba(130, 128, 255, 0.10)')
@@ -5,7 +5,13 @@ export const ArrowDownScroll: React.FC> = ({ ...props })
return (
)
}
@@ -6,9 +6,9 @@ import Stack from '@mui/material/Stack'
import { TextFieldProps } from '@mui/material/TextField/TextField'
import Image from 'next/image'
-import { Calculation } from '@/src/features/calculation-tokens-gpt'
-import { useAppSelector } from '@/src/main/store/store'
-import { styleInputWithoutBorderFocus } from '@/src/shared/ui/input'
+import { Calculation } from '#/features/calculation-tokens-gpt'
+import { useAppSelector } from '#/app/store/store'
+import { styleInputWithoutBorderFocus } from '#/shared/ui/input'
interface Input {
loading: boolean
@@ -104,7 +104,16 @@ export const InputImagesModels: FC = ({
const src = `/svg/chatgpt/send_message${theme === 'light' ? '' : '_dark'}.svg`
- return
+ return (
+
+ )
}
return (
@@ -24,5 +24,3 @@
right: 25px;
}
}
-
-
@@ -3,7 +3,7 @@ import { Box } from '@mui/material'
import Dialog from '@mui/material/Dialog'
import Image from 'next/image'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
import styles from './modal.module.scss'
export interface ModalProps {
@@ -3,7 +3,7 @@ import { TextField } from '@mui/material'
import { TextFieldProps } from '@mui/material/TextField/TextField'
import Image from 'next/image'
-import { styleInputWithoutBorderFocus } from '@/src/shared/ui/input'
+import { styleInputWithoutBorderFocus } from '#/shared/ui/input'
import styles from './search.module.scss'
export const Search = (props: TextFieldProps) => {
@@ -12,7 +12,11 @@ export const Search = (props: TextFieldProps) => {
sx={styleInputWithoutBorderFocus}
className={styles.search}
{...props}
- InputProps={{ endAdornment: }}
+ InputProps={{
+ endAdornment: (
+
+ ),
+ }}
/>
)
}
@@ -2,8 +2,8 @@ import React from 'react'
import { Typography } from '@mui/material'
import Box from '@mui/material/Box'
-import { useAppSelector } from '@/src/main/store/store'
-import { PrettoSlider, PrettoSliderDark } from '@/src/widgets/filters-gpt/ui/filters'
+import { useAppSelector } from '#/app/store/store'
+import { PrettoSlider, PrettoSliderDark } from '#/widgets/filters-gpt/ui/filters'
export const Slider = ({
value,
@@ -2,9 +2,9 @@ import React from 'react'
import { styled } from '@mui/material'
import Switch, { SwitchProps } from '@mui/material/Switch'
-import { useAppSelector } from '@/src/main/store/store'
-import { baseColor } from '@/src/shared/lib/constants/colors'
-import { pingFangFont } from '@/src/shared/lib/constants/font/font'
+import { useAppSelector } from '#/app/store/store'
+import { baseColor } from '#/shared/lib/constants/colors'
+import { pingFangFont } from '#/shared/lib/constants/font/font'
const AntSwitch = styled(Switch)(({ theme }) => ({
width: 29,
@@ -1,7 +1,7 @@
import React from 'react'
import { Tooltip } from '@mui/material'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
import styles from './styles.module.scss'
interface Props {
@@ -3,7 +3,7 @@ import { Box, Divider, Link, Menu, MenuItem, Typography } from '@mui/material'
import Router from 'next/router'
import { signOut, useSession } from 'next-auth/react'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
interface IAccountMenu {
anchorEl: HTMLElement | null
@@ -111,7 +111,12 @@ export const AccountMenu: React.FC = ({ anchorEl, changeVisible, d
fontWeight: '400',
}}
>
-
+
Блог
@@ -168,7 +173,12 @@ export const AccountMenu: React.FC = ({ anchorEl, changeVisible, d
marginTop: 1.2,
}}
>
-
+
Блог
@@ -6,7 +6,7 @@ import FormGroup from '@mui/material/FormGroup'
import Menu from '@mui/material/Menu'
import MenuItem from '@mui/material/MenuItem'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
interface IDalleFilterMenu {
anchorEl: null | HTMLElement
@@ -18,7 +18,15 @@ interface IDalleFilterMenu {
sliderChange: Function
}
-export const DalleFilterMenu: React.FC = ({ anchorEl, closeMenu, format, changeFormat, numberImages, sliderChange, open }) => {
+export const DalleFilterMenu: React.FC = ({
+ anchorEl,
+ closeMenu,
+ format,
+ changeFormat,
+ numberImages,
+ sliderChange,
+ open,
+}) => {
const theme = useAppSelector((state) => state.theme.theme)
return (
@@ -2,7 +2,7 @@ import { Button, Stack, Typography } from '@mui/material'
import Image from 'next/image'
import Link from 'next/link'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
export const DemoInfo = () => {
const { payment_plan, status } = useAppSelector((state) => state.user)
@@ -16,18 +16,27 @@ export const DemoInfo = () => {
const DemoDanger = () => {
return (
-
+
- Демо доступ
+
+ Демо доступ
+
- Вам доступны 5 токенов, которые можно потратить на любые продукты в AIR. Чтобы продолжить пользоваться платформой вы можете купить
- токены.
+ Вам доступны 5 токенов, которые можно потратить на любые продукты в AIR. Чтобы продолжить
+ пользоваться платформой вы можете купить токены.
Купить токены
@@ -1,7 +1,7 @@
import React from 'react'
import { Drawer } from '@mui/material'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
type DrawerProps = {
open: boolean
@@ -6,8 +6,8 @@ import { Box, Button, Modal, Stack, TextField, Typography } from '@mui/material'
import axios from 'axios'
import { useSession } from 'next-auth/react'
-import { useAppSelector } from '@/src/main/store/store'
-import { API_URL } from '@/src/shared/lib/constants'
+import { useAppSelector } from '#/app/store/store'
+import { API_URL } from '#/shared/lib/constants'
const style = {
position: 'absolute' as 'absolute',
@@ -146,7 +146,8 @@ const ErrorModal: React.FC = ({ open, handleClose, device }) => {
color: '#868686',
}}
>
- Ваше сообщение направлено нашим специалистам. Ответ придет на почту, указанную при регистрации
+ Ваше сообщение направлено нашим специалистам. Ответ придет на почту, указанную при
+ регистрации
) : (
@@ -202,7 +203,12 @@ const ErrorModal: React.FC = ({ open, handleClose, device }) => {
height: 25,
}}
/>
-
+
>
),
@@ -225,7 +231,9 @@ const ErrorModal: React.FC = ({ open, handleClose, device }) => {
alignItems: 'center',
}}
>
- Добавлено 1 изображение: {file.name}
+
+ Добавлено 1 изображение: {file.name}
+
setFile(undefined)}
sx={{
@@ -2,7 +2,7 @@ import React from 'react'
import { Alert, Slide, Snackbar, Typography } from '@mui/material'
import Image from 'next/image'
-import { useThemeAndDevice } from '@/src/shared/lib/hooks'
+import { useThemeAndDevice } from '#/shared/lib/hooks'
export interface IError {
error: string
@@ -13,7 +13,15 @@ export interface IError {
const ErrorIcon = () => {
const { theme } = useThemeAndDevice()
- return
+ return (
+
+ )
}
export const Error: React.FC = ({ error, handleClose, open }) => {
@@ -21,7 +29,12 @@ export const Error: React.FC = ({ error, handleClose, open }) => {
return (
-
+
}
severity='error'
@@ -1,31 +1,24 @@
-import Stack from '@mui/material/Stack';
-import useMediaQuery from '@mui/material/useMediaQuery';
+import Stack from '@mui/material/Stack'
+import useMediaQuery from '@mui/material/useMediaQuery'
-import { DrawerCustom } from './drawer';
+import { DrawerCustom } from './drawer'
-export function FiltersWrapper (props: {open: boolean, onClose: (value: boolean) => void, filetrs: React.ReactNode}) {
+export function FiltersWrapper(props: { open: boolean; onClose: (value: boolean) => void; filetrs: React.ReactNode }) {
+ const isDesktop = useMediaQuery('(min-width: 1025px)')
- const isDesktop = useMediaQuery('(min-width: 1025px)');
+ if (isDesktop) {
+ return (
+
+ {props.filetrs}
+
+ )
+ }
- if (isDesktop) {
- return (
-
- {props.filetrs}
-
- )
- }
-
- return (
- props.onClose(false)}>
-
- {props.filetrs}
-
-
- )
-
-}
\ No newline at end of file
+ return (
+ props.onClose(false)}>
+
+ {props.filetrs}
+
+
+ )
+}
@@ -3,8 +3,8 @@ import { RegisterOptions } from 'react-hook-form/dist/types/validator'
import { TextField } from '@mui/material'
import { TextFieldProps } from '@mui/material/TextField/TextField'
-import { baseColor } from '@/src/shared/lib/constants/colors'
-import { useThemeAndDevice } from '@/src/shared/lib/hooks'
+import { baseColor } from '#/shared/lib/constants/colors'
+import { useThemeAndDevice } from '#/shared/lib/hooks'
export const styleInputWithoutBorderFocus = {
'& .MuiOutlinedInput-root:hover': {
@@ -2,7 +2,7 @@ import * as React from 'react'
import Menu from '@mui/material/Menu'
import Typography from '@mui/material/Typography'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
interface INotificationMenu {
anchorEl: null | HTMLElement
@@ -3,7 +3,7 @@ import { Card, CardMedia } from '@mui/material'
import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography'
-import { getRandomImage } from '@/src/pages/login'
+import { getRandomImage } from '#/pages/login'
export const RandomImage = () => {
const refImage = React.useRef(getRandomImage())
@@ -4,11 +4,20 @@ import Link from 'next/link'
export const ReferralBlock = () => {
return (
-
-
+
+
Реферальная программа
-
+
Получай токены: 20% за подписки твоих рефералов!
@@ -24,7 +33,9 @@ export const ReferralBlock = () => {
width: '100%',
}}
>
- Пригласить друга
+
+ Пригласить друга
+
@@ -2,8 +2,8 @@ import React from 'react'
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
import { MenuItem, Select, SelectChangeEvent, Stack, Typography } from '@mui/material'
-import { useAppSelector } from '@/src/main/store/store'
-import { baseColor } from '@/src/shared/lib/constants/colors'
+import { useAppSelector } from '#/app/store/store'
+import { baseColor } from '#/shared/lib/constants/colors'
interface ISelect {
value: any
@@ -26,7 +26,9 @@ export const SocialMedia = () => {
}}
>
- Telegram
+
+ Telegram
+
@@ -43,7 +45,9 @@ export const SocialMedia = () => {
}}
>
- ВКонтакте
+
+ ВКонтакте
+
@@ -2,7 +2,7 @@ import React, { useMemo } from 'react'
import { Alert, Slide, Snackbar, Typography } from '@mui/material'
import Image from 'next/image'
-import { useThemeAndDevice } from '@/src/shared/lib/hooks'
+import { useThemeAndDevice } from '#/shared/lib/hooks'
interface ISuccess {
message: string
@@ -23,10 +23,17 @@ export const Success: React.FC = ({ message, handleClose, open, isErro
return (
-
+
,
+ success: (
+
+ ),
}}
severity='success'
sx={
@@ -5,16 +5,27 @@ import Link from 'next/link'
export const TelegramBlock = () => {
return (
-
+
-
+
Бесплатные токены
-
+
Получите 5 токенов за подписку на наш телеграм канал!
- Подписаться
+
+ Подписаться
+
@@ -27,5 +27,5 @@ export { Success } from './ui/success'
export { SwitchCustom } from './ui/switch/switch'
export { TooltipCustom } from './ui/tooltip/tooltip'
export { TooltipFreeTokens } from './ui/tooltip-free-tokens'
-export { useModel } from '@/src/shared/api/models/endpoints'
-export type { ChatProps, FiltersChatProps } from '@/src/shared/lib/types/model'
+export { useModel } from '#/shared/api/models/endpoints'
+export type { ChatProps, FiltersChatProps } from '#/shared/lib/types/model'
@@ -0,0 +1,42 @@
+import * as React from 'react'
+import { useEffect, useState } from 'react'
+import { Box, Typography } from '@mui/material'
+import { useSession } from 'next-auth/react'
+import { Card } from '#/shared/card/card'
+import { AudioModel } from '#/app/types/model'
+import { getAudio } from '#/entities/audio-model'
+import { NextPageWithLayout } from '#/pages/_app'
+
+export const AudioModelsPage: NextPageWithLayout = () => {
+ const [bots, setBots] = useState(null)
+
+ const { data, status } = useSession()
+
+ useEffect(() => {
+ if (!data) return
+
+ getAudio(data.access).then((res) => setBots(res))
+ }, [status])
+
+ return (
+ <>
+ Аудио
+
+ {bots?.map((item, idx) => {
+ return (
+
+ )
+ })}
+
+ >
+ )
+}
+
+export default AudioModelsPage
@@ -0,0 +1 @@
+export { default as AudioModelsPage } from './audio-models'
@@ -0,0 +1 @@
+export * from './ui'
\ No newline at end of file
@@ -0,0 +1,380 @@
+import React, { useCallback, useEffect } from 'react'
+import { useDispatch } from 'react-redux'
+import { Box, Collapse, Stack, Typography } from '@mui/material'
+import { useRouter } from 'next/router'
+import { useSession } from 'next-auth/react'
+import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
+
+import BotParamsMap from '#/features/bot-params/bot-params-map'
+import { useChats } from '#/features/chats'
+import Title from '#/features/title/title'
+import { TutorialContext } from '#/features/tutorial-context/tutorial-context'
+import { ChatSelect } from '#/app/components/chat_select'
+import { AllChatWindow } from '#/app/components/chat_window'
+import { ResetFilters } from '#/app/components/filters/reset_filters'
+import { setParams as setParametres } from '#/app/store/model-parametres-store'
+import { useAppSelector } from '#/app/store/store'
+import { DrawerCustom, Error, useModel, useShowData } from '#/shared'
+import model_api from '#/shared/api/models/api'
+import { IModel } from '#/shared/api/models/models'
+import styles from '#/shared/styles/chats-bot-pages.module.scss'
+import { Chats } from '#/widgets/chats'
+import { getDeviceType, getOs } from '#/shared/lib/helpers'
+import { NextPageWithLayout } from '#/pages/_app'
+import { getDefaultLayoutDynamic } from '#/widgets/layouts'
+import Head from 'next/head'
+
+export interface ChatBotPageProps {}
+
+const Page: NextPageWithLayout = () => {
+ const [botParams, setBotParams] = React.useState(null)
+ const [modelType, setModelType] = React.useState('')
+ const [openFiltersMobile, setOpenFiltersMobile] = React.useState(false)
+ const [version, setVersion] = React.useState('')
+ const [step, setStep] = React.useState(0)
+
+ const [params, setParams] = React.useState(false)
+ const [file, setFile] = React.useState(null)
+ const { error, showError } = useShowData()
+
+ const deviceType = getDeviceType()
+ const deviceOs = getOs()
+
+ const desktop = deviceType === 'desktop'
+ const { data } = useSession()
+ const router = useRouter()
+
+ const {
+ chats,
+ currentChat,
+ chatSetting,
+ setChatSetting,
+ setChat,
+ removeChat,
+ createNewChat,
+ handleClickChatSetting,
+ isTryRename,
+ setIsTryRename,
+ } = useChats(modelType)
+
+ const { messages, sendMessage, loading, getMessagesPagination, deleteMessage } = useModel(
+ currentChat,
+ showError,
+ modelType
+ )
+
+ const includeParams = useAppSelector((state) => state.params.params)
+ const dispatch = useDispatch()
+
+ const deleteMessageMemo = useCallback(deleteMessage, [currentChat, messages])
+
+ React.useEffect(() => {
+ if (data?.access) {
+ model_api.getBotParams(router.asPath.split('/')[2], data.access).then((res) => {
+ setBotParams(res)
+ setModelType(res.slug)
+ if (res.versions.length !== 0) {
+ setVersion(res.versions[0].slug)
+ dispatch(
+ setParametres(
+ res.parameters.reduce(
+ (a, v) =>
+ v.versions.includes(res.versions[0].slug)
+ ? { ...a, [v.key]: v.values.default }
+ : { ...a },
+ {}
+ )
+ )
+ )
+ } else {
+ setVersion('')
+ dispatch(
+ setParametres(res.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {}))
+ )
+ }
+ })
+ }
+ }, [data?.access, router.query])
+
+ const resetParams = () => {
+ if (botParams) {
+ dispatch(setParametres({}))
+ if (botParams.versions?.length !== 0) {
+ setVersion(botParams.versions[0].slug)
+ dispatch(
+ setParametres(
+ botParams.parameters.reduce(
+ (a, v) =>
+ v.versions.includes(botParams.versions[0].slug)
+ ? { ...a, [v.key]: v.values.default }
+ : { ...a },
+ {}
+ )
+ )
+ )
+ } else {
+ setVersion(botParams.slug)
+ dispatch(
+ setParametres(botParams.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {}))
+ )
+ }
+ }
+ }
+
+ const setDefaultParams = () => {
+ if (botParams) {
+ dispatch(setParametres({}))
+ if (version !== '') {
+ dispatch(
+ setParametres(
+ botParams.parameters.reduce(
+ (a, v) =>
+ v.versions.includes(version) ? { ...a, [v.key]: v.values.default } : { ...a },
+ {}
+ )
+ )
+ )
+ } else {
+ dispatch(
+ setParametres(botParams.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {}))
+ )
+ }
+ }
+ }
+
+ const viewMobileSettings = () => {
+ setOpenFiltersMobile(true)
+ }
+
+ const hideMobileSettings = () => {
+ setOpenFiltersMobile(false)
+ }
+
+ const onSendMessage = (input: string, required: (string | null)[]) => {
+ if (required.includes('text') && (input === '' || input === null)) {
+ showError('Введите сообщение!')
+ return false
+ }
+ if (required.includes('image') && file === null) {
+ showError('Прикрепите изображение!')
+ return false
+ }
+
+ let data = {}
+ if (version === '') {
+ data = {
+ ...includeParams,
+ }
+ } else {
+ data = {
+ version: version,
+ ...includeParams,
+ }
+ }
+
+ sendMessage({
+ content: input,
+ file: file,
+ info: {
+ ...data,
+ },
+ })
+ return true
+ }
+
+ return (
+ <>
+
+ {botParams ? botParams.title : 'Загрузка...'}
+
+
+
+
+
+
+
+
+
+ {desktop && (
+
+ {botParams?.versions && botParams.versions?.length !== 0 && (
+ <>
+
+ ВЕРСИИ
+
+
+ >
+ )}
+ {botParams && botParams.parameters?.length > 0 && (
+ {
+ setParams(!params)
+ }}
+ >
+
+ ПАРАМЕТРЫ
+
+
+
+ )}
+
+ {botParams && botParams.parameters?.length > 0 ? (
+
+
+
+
+ ) : (
+
+ Параметры отсутствуют
+
+ )}
+
+ )}
+ {!desktop && (
+
+
+ {botParams?.versions && botParams.versions?.length !== 0 && (
+ <>
+
+ ВЕРСИИ
+
+
+ >
+ )}
+ {botParams && botParams.parameters?.length > 0 ? (
+ <>
+
+ ПАРАМЕТРЫ
+
+
+
+ >
+ ) : (
+
+ Параметры отсутствуют
+
+ )}
+
+
+ )}
+
+
+
+
+ >
+ )
+}
+
+export default Page
@@ -0,0 +1,65 @@
+import * as React from 'react'
+import { useEffect, useState } from 'react'
+import { Box, Typography } from '@mui/material'
+import CircularProgress from '@mui/material/CircularProgress'
+import { useSession } from 'next-auth/react'
+
+import ChatCard from '#/app/components/chat_bot_card'
+import { useAppSelector } from '#/app/store/store'
+import model_api from '#/shared/api/models/api'
+import { IShortModel } from '#/shared/api/models/models'
+import { NextPageWithLayout } from '#/pages/_app'
+
+const Page: NextPageWithLayout = () => {
+ const [bots, setBots] = useState(null)
+ const { data } = useSession()
+ const user = useAppSelector((state) => state.user)
+
+ useEffect(() => {
+ if (!data?.access) {
+ return
+ }
+ model_api
+ .getBots(data?.access)
+ .then((res) => {
+ setBots(res)
+ })
+ .catch((err) => {})
+ }, [data?.access])
+
+ return (
+ <>
+ Чат-боты
+
+ {bots ? (
+ bots.map((item, idx) => (
+
+ ))
+ ) : (
+
+ )}
+
+ >
+ )
+}
+
+export default Page
@@ -0,0 +1,2 @@
+export { default as ChatBotsPage } from './chat-bots'
+export { default as ChatBotPage } from './chat-bot'
@@ -0,0 +1 @@
+export * from './ui'
\ No newline at end of file
@@ -0,0 +1,523 @@
+import * as React from 'react'
+import { useRef } from 'react'
+import { useDispatch } from 'react-redux'
+import { Collapse, Typography } from '@mui/material'
+import Box from '@mui/material/Box'
+import Stack from '@mui/material/Stack'
+import { useRouter } from 'next/router'
+import { useSession } from 'next-auth/react'
+
+import { Setting } from '#/domains/images-bots/babes/types'
+import BotParamsMap from '#/features/bot-params/bot-params-map'
+import Title from '#/features/title/title'
+import { ChatSelect } from '#/app/components/chat_select'
+import { ResetFilters } from '#/app/components/filters/reset_filters'
+import { UniqInput } from '#/app/components/uniq_input'
+import { setParams as setParametres } from '#/app/store/model-parametres-store'
+import { useAppSelector } from '#/app/store/store'
+import { DrawerCustom, Error } from '#/shared'
+import model_api from '#/shared/api/models/api'
+import { useModelImages } from '#/shared/api/models/endpoints'
+import { IModel } from '#/shared/api/models/models'
+import { useShowData } from '#/shared/lib/hooks'
+import { ArrowDownScroll } from '#/shared/ui/icon-components/scroll-down-arrow'
+import { ImageMessagesList } from '#/widgets/messages/image-messages-list'
+import { getDeviceType, getOs } from '#/shared/lib/helpers'
+import Head from 'next/head'
+import { NextPageWithLayout } from '#/pages/_app'
+
+const ImageModelPage: NextPageWithLayout = () => {
+ const [image, setImage] = React.useState(null)
+
+ const deviceType = getDeviceType()
+ const deviceOs = getOs()
+
+ const desktop = deviceType === 'desktop'
+ const ios = deviceOs === 'ios'
+
+ const { error, showError } = useShowData()
+ const [openFiltersMobile, setOpenFiltersMobile] = React.useState(false)
+ const router = useRouter()
+ const { data } = useSession()
+ const [botParams, setBotParams] = React.useState(null)
+ const [version, setVersion] = React.useState('')
+ const [modelType, setModelType] = React.useState('')
+ const [params, setParams] = React.useState(false)
+ const includeParams = useAppSelector((state) => state.params.params)
+ const dispatch = useDispatch()
+
+ const { messages, loading, createImage, isComplete, getMessagesPagination } = useModelImages(
+ showError,
+ modelType,
+ deviceType
+ )
+
+ const [chatScrollHeight, setChatScrollHeight] = React.useState(0)
+ const [scrollBottom, setScrollBottom] = React.useState(0)
+ const refScrollMobile = useRef()
+ const [isPaginating, setIsPaginating] = React.useState(false)
+
+ React.useEffect(() => {
+ model_api
+ .getBotParams(router.asPath.split('/')[2], data?.access)
+ .then((res) => {
+ setBotParams(res)
+ setModelType(res.slug)
+ if (res.versions.length !== 0) {
+ setVersion(res.versions[0].slug)
+ dispatch(
+ setParametres(
+ res.parameters.reduce(
+ (a, v) =>
+ v.versions.includes(res.versions[0].slug)
+ ? { ...a, [v.key]: v.values.default }
+ : { ...a },
+ {}
+ )
+ )
+ )
+ } else {
+ setVersion('')
+ dispatch(
+ setParametres(res.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {}))
+ )
+ }
+ })
+ .catch((err) => {})
+ }, [data?.access, router.query])
+
+ const onLoadImage = (event: React.ChangeEvent) => {
+ if (event.target.files) {
+ setImage(event.target.files[0])
+ // showError('Файл успешно загружен, можете отправлять его!')
+ }
+ }
+
+ const viewMobileSettings = () => {
+ setOpenFiltersMobile(true)
+ }
+
+ const hideMobileSettings = () => {
+ setOpenFiltersMobile(false)
+ }
+
+ const resetParams = () => {
+ if (botParams) {
+ dispatch(setParametres({}))
+ if (botParams.versions.length !== 0) {
+ setVersion(botParams.versions[0].slug)
+ dispatch(
+ setParametres(
+ botParams.parameters.reduce(
+ (a, v) =>
+ v.versions.includes(botParams.versions[0].slug)
+ ? { ...a, [v.key]: v.values.default }
+ : { ...a },
+ {}
+ )
+ )
+ )
+ } else {
+ setVersion(botParams.slug)
+ dispatch(
+ setParametres(botParams.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {}))
+ )
+ }
+ }
+ }
+
+ const setDefaultParams = () => {
+ if (botParams) {
+ dispatch(setParametres({}))
+ if (version !== '') {
+ dispatch(
+ setParametres(
+ botParams.parameters.reduce(
+ (a, v) =>
+ v.versions.includes(version) ? { ...a, [v.key]: v.values.default } : { ...a },
+ {}
+ )
+ )
+ )
+ } else {
+ dispatch(
+ setParametres(botParams.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {}))
+ )
+ }
+ }
+ }
+
+ const onCreateImage = (input: string, required: (string | null)[]) => {
+ if (required.includes('text') && (input === '' || input === null)) {
+ showError('Введите сообщение!')
+ return false
+ }
+ if (required.includes('image') && image === null) {
+ showError('Прикрепите изображение!')
+ return false
+ }
+ if (required.includes('zip') && image === null) {
+ showError('Прикрепите архив!')
+ return false
+ }
+ let data = {}
+ if (version === '') {
+ data = {
+ ...includeParams,
+ }
+ } else {
+ data = {
+ version: version,
+ ...includeParams,
+ }
+ }
+
+ createImage({
+ content: input,
+ file: image,
+ info: {
+ ...data,
+ },
+ })
+ return true
+ }
+
+ React.useEffect(() => {
+ if (isComplete) {
+ if (!desktop) {
+ const block = refScrollMobile.current
+ if (block) {
+ //@ts-ignore
+ block.scrollTop = block.scrollHeight
+ }
+ } else {
+ window.scroll(0, 0)
+ }
+ }
+ }, [isComplete])
+
+ const handleMobileScroll = () => {
+ setScrollBottom(
+ refScrollMobile.current?.scrollHeight -
+ refScrollMobile.current?.scrollTop -
+ refScrollMobile.current?.clientHeight
+ )
+
+ if (refScrollMobile.current && messages?.length !== 0) {
+ const { scrollTop, scrollHeight, clientHeight } = refScrollMobile.current
+ if (scrollTop === 0) {
+ if (getMessagesPagination) {
+ setIsPaginating(true)
+ getMessagesPagination(deviceType)
+ }
+ }
+ }
+ }
+
+ const handleScroll = () => {
+ if (window.scrollY + window.innerHeight >= document.documentElement.scrollHeight) {
+ setIsPaginating(true)
+ getMessagesPagination(deviceType)
+ }
+ }
+
+ React.useEffect(() => {
+ window.addEventListener('scroll', handleScroll)
+ return () => {
+ window.removeEventListener('scroll', handleScroll)
+ }
+ }, [])
+
+ React.useEffect(() => {
+ const block = deviceType === 'desktop' ? window : refScrollMobile.current
+ if (block) {
+ if (messages != undefined && !isPaginating) {
+ setChatScrollHeight(block.scrollHeight)
+ const time = setTimeout(() => {
+ //@ts-ignore
+ block.scrollTo({
+ top: block.scrollHeight,
+ behavior: 'smooth', // добавляем плавную прокрутку
+ })
+ }, 350)
+ return () => clearTimeout(time)
+ } else if (messages != undefined && isPaginating) {
+ //@ts-ignore
+ block.scrollTop = block.scrollHeight - chatScrollHeight
+
+ setChatScrollHeight(block.scrollHeight)
+ }
+ }
+ setIsPaginating(false)
+ }, [messages])
+
+ return (
+ <>
+
+ {botParams ? botParams.title : 'Загрузка...'}
+
+
+
+
+ {desktop ? (
+ <>
+
+ {botParams && (
+ setImage(null)}
+ viewMobileSettings={viewMobileSettings}
+ />
+ )}
+
+
+
+
+ >
+ ) : (
+
+ {scrollBottom > 500 && (
+ {
+ const block = refScrollMobile.current
+
+ block.scrollTo({
+ top: block.scrollHeight,
+ behavior: 'smooth', // добавляем плавную прокрутку
+ })
+ }}
+ >
+
+
+ )}
+
+
+
+
+ {botParams && (
+ setImage(null)}
+ viewMobileSettings={viewMobileSettings}
+ />
+ )}
+
+
+ )}
+
+ {desktop && (
+
+ {botParams?.versions && botParams.versions.length !== 0 ? (
+ <>
+
+ ВЕРСИИ
+
+
+ >
+ ) : (
+ <>>
+ )}
+ {botParams && botParams.parameters?.length > 0 && (
+ {
+ setParams(!params)
+ }}
+ >
+
+ ПАРАМЕТРЫ
+
+
+
+ )}
+
+ {botParams && botParams.parameters?.length > 0 ? (
+
+
+
+
+ ) : (
+
+ Параметры отсутствуют
+
+ )}
+
+ )}
+
+
+ {botParams?.versions && botParams.versions.length !== 0 ? (
+ <>
+
+ ВЕРСИИ
+
+
+ >
+ ) : (
+ <>>
+ )}
+ {botParams && botParams.parameters?.length > 0 ? (
+ <>
+
+ ПАРАМЕТРЫ
+
+
+
+ >
+ ) : (
+
+ Параметры отсутствуют
+
+ )}
+
+
+
+
+ >
+ )
+}
+
+export default ImageModelPage
@@ -0,0 +1,61 @@
+import * as React from 'react'
+import { useEffect, useState } from 'react'
+import { Box, Typography } from '@mui/material'
+import CircularProgress from '@mui/material/CircularProgress'
+import { useSession } from 'next-auth/react'
+
+import { useAppSelector } from '#/app/store/store'
+import model_api from '#/shared/api/models/api'
+import { IShortModel } from '#/shared/api/models/models'
+import { Card } from '#/shared/card/card'
+import { NextPageWithLayout } from '#/pages/_app'
+
+export const ImageModelsPage: NextPageWithLayout = () => {
+ const [bots, setBots] = useState(null)
+ const user = useAppSelector((state) => state.user)
+ const { data, status } = useSession()
+
+ useEffect(() => {
+ if (!data) return
+
+ model_api.getImages(data.access).then((res) => setBots(res))
+ }, [status])
+
+ return (
+ <>
+ Изображения
+
+ {bots ? (
+ bots.map((item, idx) => {
+ return (
+
+ )
+ })
+ ) : (
+
+ )}
+
+ >
+ )
+}
+
+export default ImageModelsPage
@@ -0,0 +1,2 @@
+export { default as ImageModelsPage } from './image-models'
+export { default as ImageModelPage } from './image-model'
@@ -0,0 +1 @@
+export * from './ui'
\ No newline at end of file
@@ -0,0 +1 @@
+export { default as MainPage } from './main'
@@ -0,0 +1,66 @@
+import * as React from 'react'
+import { useMemo } from 'react'
+import { Box, Stack, Typography } from '@mui/material'
+
+import { useAppSelector } from '#/app/store/store'
+import styles from '#/app/styles/styles-pages/index-styles.module.scss'
+import { ReferralBlock } from '#/shared'
+import { getCurrentTimeAndGreeting } from '#/shared/lib/helpers/getCurrentDateForMainScreen'
+
+import { DemoInfo } from '#//shared/ui/demo-info'
+import { SocialMedia } from '#//shared/ui/social-media-block'
+import { Statistics } from '#//widgets/stats/stats'
+import { NextPageWithLayout } from '#//pages/_app'
+import { getDeviceType } from '#//shared/lib/helpers/get-type-device'
+
+export interface MainPageProps {}
+
+const Main: NextPageWithLayout = () => {
+ const { first_name, account_type } = useAppSelector((state) => state.user)
+
+ const deviceType = getDeviceType()
+
+ const [greeting, time] = useMemo(() => getCurrentTimeAndGreeting(first_name), [first_name])
+
+ return (
+
+
+ {time}
+
+ {greeting}
+
+
+
+
+
+ {account_type === 'regular' && }
+
+
+ Полезная статья
+
+
+ {' '}
+ Что такое токен ?
+
+
+ Токен — это цифровая валюта для оплаты ИИ-продуктов и услуг. Юзеры
+ используют эту валюту, чтобы получить либо доступ к нейросетям, либо
+ результат генерации — текст, картинку и т.д. Еще токенами называют единицы
+ текста, на которых обучается нейросеть. Например, в предложении «Я люблю
+ шоколад» слова «Я», «люблю» и «шоколад» могут быть токенами.
+
+
+
+
+
+
+
+ )
+}
+
+export default Main
@@ -0,0 +1 @@
+export * from './ui'
@@ -1,5 +1,4 @@
.screenWrap {
-
}
.screen {
@@ -3,14 +3,20 @@ import { Box, Typography } from '@mui/material'
import Image from 'next/image'
import Link from 'next/link'
-import { ButtonUI } from '@/src/shared'
+import { ButtonUI } from '#/shared'
import styles from './screen-for-inactive.module.scss'
export const ScreenForInactive = () => {
return (
-
+
Корпоративный аккаунт
Для бизнеса и команд
@@ -5,24 +5,24 @@ import axios from 'axios'
import { Dayjs } from 'dayjs'
import { useSession } from 'next-auth/react'
-import { getAll, ResponseAllInfo } from '@/src/entities/user-account/model/user-type-slice'
-import { ResponseGetPersons } from '@/src/features/invite-person-in-business'
-import { useAppSelector } from '@/src/main/store/store'
-import styles from '@/src/main/styles/business.module.scss'
-import { InputStyleDark, InputStyleLight } from '@/src/shared'
-import { API_URL } from '@/src/shared/lib/constants'
-import { DateInput } from '@/src/shared/ui/date-input/date-input'
-import { Info } from '@/src/widgets/business-info'
-import { getInfo, InfoBusiness } from '@/src/widgets/business-info/api/get-info'
-import { ModelsList } from '@/src/widgets/business-models'
-import styles2 from '@/src/widgets/business-models/ui/models-list/models-list.module.scss'
-import { PersonsList } from '@/src/widgets/business-persons'
-import { getPersons } from '@/src/widgets/business-persons/api/get-persons'
-import { BusinessGroups } from '@/src/widgets/business-persons/ui/persons-list/business-group'
-import { IpList } from '@/src/widgets/business-persons/ui/persons-list/ip-list'
-import { LogList } from '@/src/widgets/business-persons/ui/persons-list/log-list'
-import { SecurityList } from '@/src/widgets/business-persons/ui/persons-list/security-list'
-import ArrowUpOrDown from '@/src/widgets/top-bar-model/ui/arrow-up-or-down'
+import { getAll, ResponseAllInfo } from '#/entities/user-account/model/user-type-slice'
+import { ResponseGetPersons } from '#/features/invite-person-in-business'
+import { useAppSelector } from '#/app/store/store'
+import styles from '#/app/styles/business.module.scss'
+import { InputStyleDark, InputStyleLight } from '#/shared'
+import { API_URL } from '#/shared/lib/constants'
+import { DateInput } from '#/shared/ui/date-input/date-input'
+import { Info } from '#/widgets/business-info'
+import { getInfo, InfoBusiness } from '#/widgets/business-info/api/get-info'
+import { ModelsList } from '#/widgets/business-models'
+import styles2 from '#/widgets/business-models/ui/models-list/models-list.module.scss'
+import { PersonsList } from '#/widgets/business-persons'
+import { getPersons } from '#/widgets/business-persons/api/get-persons'
+import { BusinessGroups } from '#/widgets/business-persons/ui/persons-list/business-group'
+import { IpList } from '#/widgets/business-persons/ui/persons-list/ip-list'
+import { LogList } from '#/widgets/business-persons/ui/persons-list/log-list'
+import { SecurityList } from '#/widgets/business-persons/ui/persons-list/security-list'
+import ArrowUpOrDown from '#/widgets/top-bar-model/ui/arrow-up-or-down'
type ListType = 'personal' | 'security'
@@ -63,10 +63,13 @@ export default function BusinessHost() {
}
const download = () => {
- axios.get(API_URL + `/auth/business-host/download-expenses?type=employees&from_date=${fromDate}&to_date=${toDate}`, {
- responseType: 'arraybuffer',
- headers: { Authorization: `Bearer ${data?.access}` },
- }).then((res) => {
+ axios.get(
+ API_URL + `/auth/business-host/download-expenses?type=employees&from_date=${fromDate}&to_date=${toDate}`,
+ {
+ responseType: 'arraybuffer',
+ headers: { Authorization: `Bearer ${data?.access}` },
+ }
+ ).then((res) => {
const file = new Blob([res.data], {
type: 'application/ms-excel;charset=utf-8',
})
@@ -80,7 +83,11 @@ export default function BusinessHost() {
}
useEffect(() => {
- axios.put(API_URL + '/auth/business-host', { token_cap_enabled: mailing }, { headers: { Authorization: `Bearer ${data?.access}` } })
+ axios.put(
+ API_URL + '/auth/business-host',
+ { token_cap_enabled: mailing },
+ { headers: { Authorization: `Bearer ${data?.access}` } }
+ )
}, [mailing])
return (
@@ -95,7 +102,11 @@ export default function BusinessHost() {
Затраты
- setShowPersons((prev) => !prev)} className={styles2.arrow} />
+ setShowPersons((prev) => !prev)}
+ className={styles2.arrow}
+ />
{showPersons && (
@@ -148,7 +159,11 @@ const MailingBlock = ({ info, mailing }: { info: InfoBusiness | null | undefined
}
const req = async (mailingArr: string[]) => {
- await axios.put(API_URL + '/auth/business-host', { token_cap_emails: mailingArr }, { headers: { Authorization: `Bearer ${data?.access}` } })
+ await axios.put(
+ API_URL + '/auth/business-host',
+ { token_cap_emails: mailingArr },
+ { headers: { Authorization: `Bearer ${data?.access}` } }
+ )
}
return (
@@ -175,7 +190,11 @@ const MailingBlock = ({ info, mailing }: { info: InfoBusiness | null | undefined
placeholder={'Введите почту'}
onChange={(e) => setNewMail(e.target.value)}
fullWidth
- sx={theme === 'light' ? { ...InputStyleLight } : { ...InputStyleDark }}
+ sx={
+ theme === 'light'
+ ? { ...InputStyleLight }
+ : { ...InputStyleDark }
+ }
/>
@@ -1,6 +1,6 @@
import axios from 'axios'
-import { API_URL } from '@/src/shared/lib/constants'
+import { API_URL } from '#/shared/lib/constants'
export type InfoBusiness = {
company_name: string
@@ -4,10 +4,10 @@ import Switch from '@mui/material/Switch'
import axios from 'axios'
import { useSession } from 'next-auth/react'
-import { ResponseAllInfo } from '@/src/entities/user-account/model/user-type-slice'
-import { useAppSelector } from '@/src/main/store/store'
-import { Balance } from '@/src/shared'
-import { API_URL } from '@/src/shared/lib/constants'
+import { ResponseAllInfo } from '#/entities/user-account/model/user-type-slice'
+import { useAppSelector } from '#/app/store/store'
+import { Balance } from '#/shared'
+import { API_URL } from '#/shared/lib/constants'
import { getInfo, InfoBusiness } from '../../api/get-info'
@@ -52,7 +52,13 @@ export const Info = ({
{!security ? {data?.company_name} : <>>}
-
+
Роль:{' '}
{type === 'business_host'
? 'Владелец'
@@ -65,7 +71,9 @@ export const Info = ({
{type !== 'business_security' ? (
Режим валидации по IP :{' '}
- {data?.is_ip_whitelist_enabled ? 'включен' : 'выключен'}
+
+ {data?.is_ip_whitelist_enabled ? 'включен' : 'выключен'}
+
) : (
<>>
@@ -1,7 +1,7 @@
import axios from 'axios'
-import { AllowedModels } from '@/src/features/changeAccessToModel'
-import { API_URL } from '@/src/shared/lib/constants'
+import { AllowedModels } from '#/features/changeAccessToModel'
+import { API_URL } from '#/shared/lib/constants'
export const getModels = async (token?: string): Promise => {
try {
const { data } = await axios.get(API_URL + '/auth/business-host/allowed-models', {
@@ -9,9 +9,9 @@ import TableHead from '@mui/material/TableHead'
import TableRow from '@mui/material/TableRow'
import { useSession } from 'next-auth/react'
-import { AllowedModels, SwitchAccess } from '@/src/features/changeAccessToModel'
-import { Search, translateTypeModel } from '@/src/shared'
-import ArrowUpOrDown from '@/src/widgets/top-bar-model/ui/arrow-up-or-down'
+import { AllowedModels, SwitchAccess } from '#/features/changeAccessToModel'
+import { Search, translateTypeModel } from '#/shared'
+import ArrowUpOrDown from '#/widgets/top-bar-model/ui/arrow-up-or-down'
import { getModels } from '../../api/get-models'
@@ -35,7 +35,11 @@ export const ModelsList = () => {
Нейросети
{models.length}
- setShowModels((prev) => !prev)} className={styles.arrow} />
+ setShowModels((prev) => !prev)}
+ className={styles.arrow}
+ />
{showModels && (
@@ -52,9 +56,18 @@ export const ModelsList = () => {
{models.map((model) => {
return (
-
+
{model.title}
- {translateTypeModel(model.model_type)}
+
+ {translateTypeModel(model.model_type)}
+
=> {
try {
@@ -1,8 +1,8 @@
import axios from 'axios'
-import { ResponseGetPersons } from '@/src/features/invite-person-in-business'
-import { ResponseGetIpList } from '@/src/features/invite-person-in-business/model/types'
-import { API_URL } from '@/src/shared/lib/constants'
+import { ResponseGetPersons } from '#/features/invite-person-in-business'
+import { ResponseGetIpList } from '#/features/invite-person-in-business/model/types'
+import { API_URL } from '#/shared/lib/constants'
export const getIpList = async (token?: string): Promise => {
try {
@@ -1,8 +1,8 @@
import axios from 'axios'
import { Dayjs } from 'dayjs'
-import { ResponseGetLogsList } from '@/src/features/invite-person-in-business/model/types'
-import { API_URL } from '@/src/shared/lib/constants'
+import { ResponseGetLogsList } from '#/features/invite-person-in-business/model/types'
+import { API_URL } from '#/shared/lib/constants'
export const getLogsList = async (
offset: number,
@@ -1,7 +1,7 @@
import axios from 'axios'
-import { ResponseGetPersons } from '@/src/features/invite-person-in-business'
-import { API_URL } from '@/src/shared/lib/constants'
+import { ResponseGetPersons } from '#/features/invite-person-in-business'
+import { API_URL } from '#/shared/lib/constants'
export const getPersons = async (token?: string, security?: boolean): Promise => {
try {
@@ -1,4 +1,4 @@
-import { AcceptanceStatus } from '@/src/features/invite-person-in-business/model/types'
+import { AcceptanceStatus } from '#/features/invite-person-in-business/model/types'
export const translateEmailStatus = (status: AcceptanceStatus) => {
switch (status) {
@@ -12,22 +12,24 @@ import { filter } from 'lodash'
import Image from 'next/image'
import { useSession } from 'next-auth/react'
-import { AddBusinessGroup } from '@/src/features/business-group'
-import { ChangeBusinessGroup } from '@/src/features/business-group/ui/change-business-group'
-import { ResponseGetPersons } from '@/src/features/invite-person-in-business'
-import { ResponseGetBusinessGroups } from '@/src/features/invite-person-in-business/model/types'
-import { XMark } from '@/src/features/remove-person'
-import { Search } from '@/src/shared'
-import { API_URL } from '@/src/shared/lib/constants'
-import styles from '@/src/widgets/business-models/ui/models-list/models-list.module.scss'
-import { getBusinessGroups } from '@/src/widgets/business-persons/api/get-businessGroups'
-import ArrowUpOrDown from '@/src/widgets/top-bar-model/ui/arrow-up-or-down'
+import { AddBusinessGroup } from '#/features/business-group'
+import { ChangeBusinessGroup } from '#/features/business-group/ui/change-business-group'
+import { ResponseGetPersons } from '#/features/invite-person-in-business'
+import { ResponseGetBusinessGroups } from '#/features/invite-person-in-business/model/types'
+import { XMark } from '#/features/remove-person'
+import { Search } from '#/shared'
+import { API_URL } from '#/shared/lib/constants'
+import styles from '#/widgets/business-models/ui/models-list/models-list.module.scss'
+import { getBusinessGroups } from '#/widgets/business-persons/api/get-businessGroups'
+import ArrowUpOrDown from '#/widgets/top-bar-model/ui/arrow-up-or-down'
import { getIpList } from '../../api/get-ipList'
export const BusinessGroups = ({ company_uid }: { company_uid?: string }) => {
const [businessGroups, setBusinessGroups] = useState()
- const [searchGroup, setSearchGroup] = useState(businessGroups ? businessGroups : [])
+ const [searchGroup, setSearchGroup] = useState(
+ businessGroups ? businessGroups : []
+ )
const [businessAddModal, setBusinessAddModal] = useState(false)
const [showPersons, setShowPersons] = useState(true)
const [search, setSearch] = useState('')
@@ -96,7 +98,11 @@ export const BusinessGroups = ({ company_uid }: { company_uid?: string }) => {
Бизнес-группы
- setShowPersons((prev) => !prev)} className={styles.arrow} />
+ setShowPersons((prev) => !prev)}
+ className={styles.arrow}
+ />
{
@@ -129,12 +135,22 @@ export const BusinessGroups = ({ company_uid }: { company_uid?: string }) => {
{searchGroup && searchGroup.length !== 0 ? (
searchGroup?.map((group) => {
return (
-
+
{group.title}
-
- {group.token_limit ? group.token_limit.split('.')[0] : 'Не указано'}
+
+ {group.token_limit
+ ? group.token_limit.split('.')[0]
+ : 'Не указано'}
{
)
})
) : (
-
+
Не найдено группы с таким именем
@@ -9,11 +9,11 @@ import TableHead from '@mui/material/TableHead'
import TableRow from '@mui/material/TableRow'
import { useSession } from 'next-auth/react'
-import { ResponseGetPersons } from '@/src/features/invite-person-in-business'
-import { ResponseGetIpList } from '@/src/features/invite-person-in-business/model/types'
-import { Search, Success, useShowData } from '@/src/shared'
-import styles from '@/src/widgets/business-models/ui/models-list/models-list.module.scss'
-import ArrowUpOrDown from '@/src/widgets/top-bar-model/ui/arrow-up-or-down'
+import { ResponseGetPersons } from '#/features/invite-person-in-business'
+import { ResponseGetIpList } from '#/features/invite-person-in-business/model/types'
+import { Search, Success, useShowData } from '#/shared'
+import styles from '#/widgets/business-models/ui/models-list/models-list.module.scss'
+import ArrowUpOrDown from '#/widgets/top-bar-model/ui/arrow-up-or-down'
import { getIpList } from '../../api/get-ipList'
@@ -62,13 +62,22 @@ export const IpList = () => {
) : (
<>>
)}
- setShowPersons((prev) => !prev)} className={styles.arrow} />
+ setShowPersons((prev) => !prev)}
+ className={styles.arrow}
+ />
{showPersons && (
- setSearch(e.target.value)} fullWidth placeholder='Введите IP-адрес' />
+ setSearch(e.target.value)}
+ fullWidth
+ placeholder='Введите IP-адрес'
+ />
@@ -81,7 +90,12 @@ export const IpList = () => {
{ipList && searchIp && searchIp.length > 0 ? (
searchIp.map((ip) => {
return (
-
+
{ip}
@@ -89,7 +103,13 @@ export const IpList = () => {
)
})
) : (
-
+
IP-адреса не найдены
@@ -10,13 +10,13 @@ import TableRow from '@mui/material/TableRow'
import { Dayjs } from 'dayjs'
import { useSession } from 'next-auth/react'
-import { ResponseGetLogsList } from '@/src/features/invite-person-in-business/model/types'
-import { useAppSelector } from '@/src/main/store/store'
-import { Search } from '@/src/shared'
-import { DateInput } from '@/src/shared/ui/date-input/date-input'
-import styles from '@/src/widgets/business-models/ui/models-list/models-list.module.scss'
-import { getLogsList } from '@/src/widgets/business-persons/api/get-logsList'
-import ArrowUpOrDown from '@/src/widgets/top-bar-model/ui/arrow-up-or-down'
+import { ResponseGetLogsList } from '#/features/invite-person-in-business/model/types'
+import { useAppSelector } from '#/app/store/store'
+import { Search } from '#/shared'
+import { DateInput } from '#/shared/ui/date-input/date-input'
+import styles from '#/widgets/business-models/ui/models-list/models-list.module.scss'
+import { getLogsList } from '#/widgets/business-persons/api/get-logsList'
+import ArrowUpOrDown from '#/widgets/top-bar-model/ui/arrow-up-or-down'
export const LogList = () => {
const [logs, setLogs] = useState()
@@ -44,7 +44,9 @@ export const LogList = () => {
if (search) {
return logs?.filter(
- (el) => el.user.toLowerCase().includes(search.toLowerCase()) || el.message.toLowerCase().includes(search.toLowerCase())
+ (el) =>
+ el.user.toLowerCase().includes(search.toLowerCase()) ||
+ el.message.toLowerCase().includes(search.toLowerCase())
)
} else {
return logs
@@ -64,7 +66,11 @@ export const LogList = () => {
Журнал
- setShowPersons((prev) => !prev)} className={styles.arrow} />
+ setShowPersons((prev) => !prev)}
+ className={styles.arrow}
+ />
@@ -116,7 +122,12 @@ export const LogList = () => {
- setSearch(e.target.value)} fullWidth placeholder='Введите пользователя' />
+ setSearch(e.target.value)}
+ fullWidth
+ placeholder='Введите пользователя'
+ />
@@ -131,22 +142,47 @@ export const LogList = () => {
{searchLogs && searchLogs.length !== 0 ? (
searchLogs?.map((log, idx) => {
return (
-
+
{log.user}
{log.action_time.split('T')[0]} |{' '}
- {log.action_time.split('T')[1].split('.')[0].split(':')[0]}:
- {log.action_time.split('T')[1].split('.')[0].split(':')[1]}
+ {
+ log.action_time
+ .split('T')[1]
+ .split('.')[0]
+ .split(':')[0]
+ }
+ :
+ {
+ log.action_time
+ .split('T')[1]
+ .split('.')[0]
+ .split(':')[1]
+ }
{log.message}
)
})
) : (
-
-
+
+
Логов не найдено
@@ -9,15 +9,15 @@ import TableHead from '@mui/material/TableHead'
import TableRow from '@mui/material/TableRow'
import { useSession } from 'next-auth/react'
-import { PersonInBusiness } from '@/src/features/business-security-download'
-import { LimitModal } from '@/src/features/change-limit'
-import { InviteModal, ResponseGetPersons, RoleSelect } from '@/src/features/invite-person-in-business'
-import { InviteRoles } from '@/src/features/invite-person-in-business/lib/constants'
-import { XMark } from '@/src/features/remove-person'
-import { Search, Success, useShowData } from '@/src/shared'
-import styles from '@/src/widgets/business-models/ui/models-list/models-list.module.scss'
-import { getPersons } from '@/src/widgets/business-persons/api/get-persons'
-import ArrowUpOrDown from '@/src/widgets/top-bar-model/ui/arrow-up-or-down'
+import { PersonInBusiness } from '#/features/business-security-download'
+import { LimitModal } from '#/features/change-limit'
+import { InviteModal, ResponseGetPersons, RoleSelect } from '#/features/invite-person-in-business'
+import { InviteRoles } from '#/features/invite-person-in-business/lib/constants'
+import { XMark } from '#/features/remove-person'
+import { Search, Success, useShowData } from '#/shared'
+import styles from '#/widgets/business-models/ui/models-list/models-list.module.scss'
+import { getPersons } from '#/widgets/business-persons/api/get-persons'
+import ArrowUpOrDown from '#/widgets/top-bar-model/ui/arrow-up-or-down'
import { translateEmailStatus } from '../../lib/lib'
@@ -99,7 +99,11 @@ export const PersonsList = ({
Сотрудники
{persons?.length !== 0 && {persons?.length}}
- setShowPersons((prev) => !prev)} className={styles.arrow} />
+ setShowPersons((prev) => !prev)}
+ className={styles.arrow}
+ />
setInviteModal(true)}>Добавить сотрудника
@@ -134,33 +138,54 @@ export const PersonsList = ({
{searchPersons?.map((person) => {
return (
-
+
{person.email}
- {RoleSelect[person.account_type]}
+
+ {RoleSelect[person.account_type]}
+
{translateEmailStatus(person.acceptance_status)}
-
+
{Math.floor(+person.token_limit)}
- setCurrentPerson(persons?.find((el) => el.email === person.email) || null)
+ setCurrentPerson(
+ persons?.find(
+ (el) => el.email === person.email
+ ) || null
+ )
}
className={styles.tableLimit}
align='center'
>
Изменить
-
+
setPersons(
(prev) =>
- prev?.filter((el) => el.email !== persons.email) || null
+ prev?.filter(
+ (el) =>
+ el.email !==
+ persons.email
+ ) || null
)
}
email={person.email}
@@ -13,15 +13,15 @@ import axios, { AxiosResponse } from 'axios'
import Image from 'next/image'
import { useSession } from 'next-auth/react'
-import { InviteRoles } from '@/src/features/business-group/lib/constants'
-import { ResponseGetBusinessGroups } from '@/src/features/business-group/model/types'
-import { LimitModal } from '@/src/features/change-limit'
-import { ResponseGetPersons, RoleSelect } from '@/src/features/invite-person-in-business'
-import { invitePerson } from '@/src/features/invite-person-in-business/api/invite-person'
-import { inviteRoles } from '@/src/features/invite-person-in-business/lib/constants'
-import styles2 from '@/src/features/invite-person-in-business/ui/invite-modal.module.scss'
-import { IEmailForms } from '@/src/features/register-by-email/model/types'
-import { useAppSelector } from '@/src/main/store/store'
+import { InviteRoles } from '#/features/business-group/lib/constants'
+import { ResponseGetBusinessGroups } from '#/features/business-group/model/types'
+import { LimitModal } from '#/features/change-limit'
+import { ResponseGetPersons, RoleSelect } from '#/features/invite-person-in-business'
+import { invitePerson } from '#/features/invite-person-in-business/api/invite-person'
+import { inviteRoles } from '#/features/invite-person-in-business/lib/constants'
+import styles2 from '#/features/invite-person-in-business/ui/invite-modal.module.scss'
+import { IEmailForms } from '#/features/register-by-email/model/types'
+import { useAppSelector } from '#/app/store/store'
import {
ButtonGray,
ButtonUI,
@@ -34,12 +34,12 @@ import {
ModalProps,
onlyNumbersOption,
Select,
-} from '@/src/shared'
-import { Search, Success, useShowData } from '@/src/shared'
-import { API_URL } from '@/src/shared/lib/constants'
-import styles from '@/src/widgets/business-models/ui/models-list/models-list.module.scss'
-import { getBusinessGroups } from '@/src/widgets/business-persons/api/get-businessGroups'
-import ArrowUpOrDown from '@/src/widgets/top-bar-model/ui/arrow-up-or-down'
+} from '#/shared'
+import { Search, Success, useShowData } from '#/shared'
+import { API_URL } from '#/shared/lib/constants'
+import styles from '#/widgets/business-models/ui/models-list/models-list.module.scss'
+import { getBusinessGroups } from '#/widgets/business-persons/api/get-businessGroups'
+import ArrowUpOrDown from '#/widgets/top-bar-model/ui/arrow-up-or-down'
import { translateEmailStatus } from '../../lib/lib'
@@ -121,7 +121,11 @@ export const SecurityList = ({
Сотрудники безопасности
{persons?.length !== 0 && {persons?.length}}
- setShowPersons((prev) => !prev)} className={styles.arrow} />
+ setShowPersons((prev) => !prev)}
+ className={styles.arrow}
+ />
setInviteModal(true)}>Добавить сотрудника
@@ -156,42 +160,71 @@ export const SecurityList = ({
{searchPersons?.map((person) => {
return (
-
+
{person.email}
- {RoleSelect[person.account_type]}
+
+ {RoleSelect[person.account_type]}
+
{translateEmailStatus(person.acceptance_status)}
-
+
{Math.floor(+person.token_limit)}
- setCurrentPerson(persons?.find((el) => el.email === person.email) || null)
+ setCurrentPerson(
+ persons?.find(
+ (el) => el.email === person.email
+ ) || null
+ )
}
className={styles.tableLimit}
align='center'
>
Изменить
-
+
{
axios.put<
- { token_limit: string; role: string },
+ {
+ token_limit: string
+ role: string
+ },
AxiosResponse
>(
- API_URL + `/auth/business-host/accounts/${person.email}`,
- { account_privileges: 'regular' },
- { headers: { Authorization: `Bearer ${data?.access}` } }
+ API_URL +
+ `/auth/business-host/accounts/${person.email}`,
+ {
+ account_privileges: 'regular',
+ },
+ {
+ headers: {
+ Authorization: `Bearer ${data?.access}`,
+ },
+ }
).then((res) => {
if (securityList)
setSecurityList(
securityList.filter(
- (el) => el.email !== res.data.email
+ (el) =>
+ el.email !==
+ res.data.email
)
)
addList(res.data, 'personal')
@@ -214,7 +247,11 @@ export const SecurityList = ({
)}
- setInviteModal(false)} showNewPersons={showNewPerson} />
+ setInviteModal(false)}
+ showNewPersons={showNewPerson}
+ />
{currentPerson && (
= ({ open, onClose, showN
{/* Поле с выбором роли сотрудника */}
Выберите роль
-
+
{/* Поле с выбором группы */}
Выберите бизнес-группу
@@ -1,7 +1,7 @@
import React from 'react'
import { Box, Button, Grow, Menu, Typography } from '@mui/material'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
interface IContext {
context: { message: string; uid: string }[]
@@ -10,7 +10,12 @@ interface IContext {
device?: 'mobile' | 'desktop'
}
-const Context: React.FC = ({ context, deleteContextMessage, deleteAllContextMessage, device = 'desktop' }) => {
+const Context: React.FC = ({
+ context,
+ deleteContextMessage,
+ deleteAllContextMessage,
+ device = 'desktop',
+}) => {
const [anchorEl, setAnchorEl] = React.useState(null)
const open = Boolean(anchorEl)
const handleClick = (event: React.MouseEvent) => {
@@ -101,7 +106,12 @@ const Context: React.FC = ({ context, deleteContextMessage, deleteAllC
<>
{context.map((message) => {
return (
-
+
deleteContextMessage(message.uid)} sx={{ width: 'fit-content' }}>
{
const { theme } = useThemeAndDevice()
@@ -1,8 +1,8 @@
import React from 'react'
import { Tooltip } from '@mui/material'
-import { useThemeAndDevice } from '@/src/shared/lib/hooks'
-import TooltipContextText from '@/src/widgets/chat-gpt-field/ui/tooltip-context-text'
+import { useThemeAndDevice } from '#/shared/lib/hooks'
+import TooltipContextText from '#/widgets/chat-gpt-field/ui/tooltip-context-text'
interface ITooltipContext {
children: React.ReactNode
@@ -1,15 +1,25 @@
import React from 'react'
-import { Box, Input, Menu, MenuItem, Popover, TextField, ToggleButton, ToggleButtonGroup, Typography } from '@mui/material'
+import {
+ Box,
+ Input,
+ Menu,
+ MenuItem,
+ Popover,
+ TextField,
+ ToggleButton,
+ ToggleButtonGroup,
+ Typography,
+} from '@mui/material'
import axios from 'axios'
import Image from 'next/image'
import { useSession } from 'next-auth/react'
-import { Chat, ChatsReturn } from '@/src/features/chats'
-import { useAppSelector } from '@/src/main/store/store'
-import styles2 from '@/src/main/styles/account.module.css'
-import { TooltipCustom } from '@/src/shared'
-import { api } from '@/src/shared/api/endpoints'
-import chatsStyles from '@/src/shared/styles/chats-menu.module.scss'
+import { Chat, ChatsReturn } from '#/features/chats'
+import { useAppSelector } from '#/app/store/store'
+import styles2 from '#/app/styles/account.module.css'
+import { TooltipCustom } from '#/shared'
+import { api } from '#/shared/api/endpoints'
+import chatsStyles from '#/shared/styles/chats-menu.module.scss'
export const Chats = ({
chats,
@@ -60,7 +70,10 @@ export const Chats = ({
const renameChat = () => {
if (newTitle !== '' && newTitle !== 'Новый чат') {
api.updRenameChat(localChat, newTitle, data?.access).then((res) => {
- if (res.data && chats) setLocalChats(chats.filter((el) => (el.uid === res.data.uid ? (el.title = res.data.title) : el)))
+ if (res.data && chats)
+ setLocalChats(
+ chats.filter((el) => (el.uid === res.data.uid ? (el.title = res.data.title) : el))
+ )
setNewTitle('')
})
}
@@ -69,7 +82,16 @@ export const Chats = ({
return (
- ЧАТЫ
+
+ ЧАТЫ
+
) : (
-
+
{el?.title}
@@ -195,7 +227,9 @@ export const Chats = ({
{el?.uid === currentChat && (
= ({
open,
@@ -5,12 +5,17 @@ import { SelectChangeEvent } from '@mui/material/Select'
import Stack from '@mui/material/Stack'
import { styled } from '@mui/material/styles'
-import { TutorialContext } from '@/src/features/tutorial-context/tutorial-context'
-import { useAppSelector } from '@/src/main/store/store'
-import { Select, Slider as Sl, SwitchCustom, TooltipCustom } from '@/src/shared'
-import { ITypeModels, ParameterPresencePenalty, ParameterTemperature, ParameterTopP } from '@/src/widgets/filters-gpt/lib/constants'
-import FiltersMobile from '@/src/widgets/filters-gpt/ui/filters-mobile'
-import TooltipModelTypes from '@/src/widgets/filters-gpt/ui/tooltip-model-types'
+import { TutorialContext } from '#/features/tutorial-context/tutorial-context'
+import { useAppSelector } from '#/app/store/store'
+import { Select, Slider as Sl, SwitchCustom, TooltipCustom } from '#/shared'
+import {
+ ITypeModels,
+ ParameterPresencePenalty,
+ ParameterTemperature,
+ ParameterTopP,
+} from '#/widgets/filters-gpt/lib/constants'
+import FiltersMobile from '#/widgets/filters-gpt/ui/filters-mobile'
+import TooltipModelTypes from '#/widgets/filters-gpt/ui/tooltip-model-types'
import 'intro.js/introjs.css'
@@ -137,7 +142,13 @@ export const Filters: React.FC = memo(
padding: '30px',
height: 'fit-content',
borderRadius: '15px',
- backgroundColor: desktop ? (theme === 'light' ? 'white' : '#151518') : theme === 'light' ? 'white' : '#4B4B4B',
+ backgroundColor: desktop
+ ? theme === 'light'
+ ? 'white'
+ : '#151518'
+ : theme === 'light'
+ ? 'white'
+ : '#4B4B4B',
}}
>
@@ -181,7 +192,12 @@ export const Filters: React.FC = memo(
{isAdditionalCtx && (
-
+
= memo(
>
Увеличенный контекст
- changeAdditionalCtx!()} />
+ changeAdditionalCtx!()}
+ />
)}
@@ -1,7 +1,7 @@
import React from 'react'
import { Box, Tooltip, Typography } from '@mui/material'
-import { useAppSelector } from '@/src/main/store/store'
+import { useAppSelector } from '#/app/store/store'
interface ITooltip {
title: string
@@ -1,8 +1,15 @@
-import { IProps } from '@/src/shared/lib/types/entities'
-import { Styles } from '@/src/widgets/filters-sd/ui/filters'
+import { IProps } from '#/shared/lib/types/entities'
+import { Styles } from '#/widgets/filters-sd/ui/filters'
export type TImageFormat = '512x512' | '640x384' | '384x640' | '768x512' | '512x768' | '1024x1024'
-export type TClipGuidancePresets = 'FAST_BLUE' | 'FAST_GREEN' | 'Без фильтров' | 'SIMPLE' | 'SLOW' | 'SLOWER' | 'SLOWEST'
+export type TClipGuidancePresets =
+ | 'FAST_BLUE'
+ | 'FAST_GREEN'
+ | 'Без фильтров'
+ | 'SIMPLE'
+ | 'SLOW'
+ | 'SLOWER'
+ | 'SLOWEST'
export type TSamplerTypes =
| 'DDIM'
| 'DDPM'
@@ -2,14 +2,20 @@ import React, { useState } from 'react'
import SettingsSuggestIcon from '@mui/icons-material/SettingsSuggest'
import { Box, Button, Drawer, Stack, Typography } from '@mui/material'
-import { useAppSelector } from '@/src/main/store/store'
-import { Select, SwitchCustom } from '@/src/shared'
-import { Slider } from '@/src/shared'
-import { SelectUI } from '@/src/shared/ui/select'
-import { PrettoSlider, PrettoSliderDark } from '@/src/widgets/filters-gpt/ui/filters'
-import { GeneratingModel } from '@/src/widgets/filters-sd/lib/constants'
-import { ISDFilters, TClipGuidancePresets, TGeneratingModel, TImageFormat, TSamplerTypes } from '@/src/widgets/filters-sd/lib/types'
-import { Styles,styles } from '@/src/widgets/filters-sd/ui/filters'
+import { useAppSelector } from '#/app/store/store'
+import { Select, SwitchCustom } from '#/shared'
+import { Slider } from '#/shared'
+import { SelectUI } from '#/shared/ui/select'
+import { PrettoSlider, PrettoSliderDark } from '#/widgets/filters-gpt/ui/filters'
+import { GeneratingModel } from '#/widgets/filters-sd/lib/constants'
+import {
+ ISDFilters,
+ TClipGuidancePresets,
+ TGeneratingModel,
+ TImageFormat,
+ TSamplerTypes,
+} from '#/widgets/filters-sd/lib/types'
+import { Styles, styles } from '#/widgets/filters-sd/ui/filters'
interface ISDFiltersMobile extends ISDFilters {
isOpenDrawer: boolean
@@ -142,7 +148,9 @@ export const FiltersMobile: React.FC = ({
size={'small'}
title={'clip_guidance_preset'}
value={clipGuidancePreset}
- onChange={(e) => changeClipGuidancePreset(e.target.value as TClipGuidancePresets)}
+ onChange={(e) =>
+ changeClipGuidancePreset(e.target.value as TClipGuidancePresets)
+ }
list={clipGuidancePresets}
/>
@@ -1,10 +1,16 @@
import React from 'react'
import { Box, Stack, Typography } from '@mui/material'
-import { Slider, SwitchCustom } from '@/src/shared'
-import { SelectUI } from '@/src/shared/ui/select'
-import { GeneratingModel } from '@/src/widgets/filters-sd/lib/constants'
-import { ISDFilters, TClipGuidancePresets, TGeneratingModel, TImageFormat, TSamplerTypes } from '@/src/widgets/filters-sd/lib/types'
+import { Slider, SwitchCustom } from '#/shared'
+import { SelectUI } from '#/shared/ui/select'
+import { GeneratingModel } from '#/widgets/filters-sd/lib/constants'
+import {
+ ISDFilters,
+ TClipGuidancePresets,
+ TGeneratingModel,
+ TImageFormat,
+ TSamplerTypes,
+} from '#/widgets/filters-sd/lib/types'
export type Styles =
| null
@@ -81,7 +87,12 @@ export const FiltersSd: React.FC = ({
/>
- changeStyle(e.target.value as Styles)} list={Object.values(styles)} />
+ changeStyle(e.target.value as Styles)}
+ list={Object.values(styles)}
+ />
= {}) {
+ return (page: ReactElement) => {page}
+}
+
+export const getDefaultLayoutDynamic = function (getLayoutProps: () => Omit) {
+ return (page: ReactElement) => {page}
+}
+
@@ -0,0 +1 @@
+export * from './get-layout'
\ No newline at end of file
@@ -0,0 +1 @@
+export * from './layout-props'
\ No newline at end of file
@@ -0,0 +1,9 @@
+
+
+export interface LayoutProps {
+ children: React.ReactNode
+ titlePage?: string
+ isAuthPage?: boolean
+ title?: string | React.ReactNode | null
+ isLoader?: boolean
+}
\ No newline at end of file
@@ -0,0 +1,158 @@
+import React, { useState } from 'react'
+import { Box } from '@mui/material'
+import { ThemeProvider } from '@mui/material/styles'
+import Head from 'next/head'
+import { useRouter } from 'next/router'
+import { useSession } from 'next-auth/react'
+
+import { getUserBalance } from '#/entities/balance'
+import { useTheme } from '#/entities/theme'
+import { getAllInfo } from '#/entities/user-account'
+import { isSettingExist } from '#/entities/user-account/lib/helpers/is-setting-exist'
+import { getUserAccountSettings, setSettings } from '#/entities/user-account/model/settings'
+import InfoBar from '#/app/layout/ui/info-bar'
+import { useAppDispatch, useAppSelector } from '#/app/store/store'
+import { Loader } from '#/shared'
+import { pingFangFont } from '#/shared/lib/constants/font/font'
+import { Device } from '#/shared/lib/types/entities'
+import { MainMenuMobile } from '#/widgets/main-menu'
+import { SideMenu } from '#/widgets/side-menu'
+import { getDeviceType } from '#/shared/lib/helpers'
+import { LayoutProps } from '../types'
+
+const freeRoutes = ['/login', '/register', '/reset', '/changePassword']
+
+export const Layout: React.FC = ({
+ children,
+ isAuthPage = false,
+ titlePage,
+ title = titlePage,
+ isLoader,
+}) => {
+ const { data: sessionData } = useSession()
+ const appState = useAppSelector((state) => state)
+ const dispatch = useAppDispatch()
+
+ const device = getDeviceType()
+
+ const desktop = device === 'desktop'
+
+ const [sidemenuDefaultOpen, setSidemenuDefaultOpen] = useState(true)
+
+ useTheme()
+
+ const { data, status } = useSession()
+
+ const router = useRouter()
+
+ React.useEffect(() => {
+ if (status === 'authenticated') {
+ dispatch(getUserBalance(data?.access))
+ dispatch(getAllInfo(data?.access))
+ }
+
+ if (status === 'unauthenticated' && !freeRoutes.includes(router.route)) {
+ router.push('/login')
+ }
+ }, [status])
+
+ React.useEffect(() => {
+ if (
+ (sessionData && !sessionStorage.getItem('firstRender')) ||
+ (sessionData && !localStorage.getItem('global_settings'))
+ ) {
+ dispatch(getUserAccountSettings(sessionData.access))
+ sessionStorage.setItem('firstRender', 'true')
+ }
+ }, [sessionData])
+
+ React.useEffect(() => {
+ const lsData = localStorage.getItem('global_settings')
+ if (lsData !== null) {
+ dispatch(setSettings(JSON.parse(lsData)))
+ }
+
+ window.addEventListener('beforeunload', () => {
+ sessionStorage.removeItem('firstRender')
+ sessionStorage.clear()
+ })
+ }, [])
+
+ React.useEffect(() => {
+ if (appState.settings.state !== null && device) {
+ let setting = isSettingExist({
+ settings: appState.settings.state,
+ targetDevice: device,
+ targetType: 'sidemenu',
+ })
+ if (setting)
+ setting?.value?.sidemenu_state === 'opened'
+ ? setSidemenuDefaultOpen(true)
+ : setSidemenuDefaultOpen(false)
+ }
+ }, [appState.settings.state])
+
+ if (status === 'loading' || isLoader) {
+ return (
+
+
+
+ )
+ }
+
+ return (
+ <>
+
+ {titlePage && {titlePage}}
+
+
+
+
+
+
+
+
+
+ {!isAuthPage ? (
+ desktop ? (
+
+
+
+
+
+ {children}
+
+
+
+ ) : (
+
+
+ {children}
+
+ )
+ ) : (
+ <>{children}>
+ )}
+
+
+
+ >
+ )
+}
@@ -0,0 +1 @@
+export * from './default'
@@ -0,0 +1,3 @@
+export * from './ui'
+export * from './model'
+export * from './types'
\ No newline at end of file
@@ -9,10 +9,10 @@ import Link from 'next/link'
import Router, { useRouter } from 'next/router'
import { signOut, useSession } from 'next-auth/react'
-import { change } from '@/src/entities/theme'
-import { getAll, ResponseAllInfo } from '@/src/entities/user-account/model/user-type-slice'
-import { useAppDispatch, useAppSelector } from '@/src/main/store/store'
-import { AccountMenu } from '@/src/shared'
+import { change } from '#/entities/theme'
+import { getAll, ResponseAllInfo } from '#/entities/user-account/model/user-type-slice'
+import { useAppDispatch, useAppSelector } from '#/app/store/store'
+import { AccountMenu } from '#/shared'
import { menuListMiddle, menuListTop } from '../../side-menu/ui/side-menu'
@@ -155,14 +155,31 @@ export const MainMenuMobile = memo(() => {
dispatch(change(null))
}}
>
-
+
signOut()}>
-
+
-
+
Реквизиты
@@ -170,7 +187,11 @@ export const MainMenuMobile = memo(() => {
- push('/account')} sx={{ width: 29, height: 29 }} src={String(profile_picture_link)}>
+ push('/account')}
+ sx={{ width: 29, height: 29 }}
+ src={String(profile_picture_link)}
+ >
{first_name[0]}
@@ -192,7 +213,10 @@ type MenuItemProps = {
}
export function MenuItem(props: MenuItemProps) {
- const isActive = useMemo(() => props.link === props.pathname || props.activeList?.some((el) => props.pathname.includes(el)), [props.pathname])
+ const isActive = useMemo(
+ () => props.link === props.pathname || props.activeList?.some((el) => props.pathname.includes(el)),
+ [props.pathname]
+ )
return (
@@ -8,11 +8,11 @@ import Image from 'next/image'
import Router, { useRouter } from 'next/router'
import { useSession } from 'next-auth/react'
-import { change } from '@/src/entities/theme'
-import { useAppDispatch, useAppSelector } from '@/src/main/store/store'
-import { AccountMenu } from '@/src/shared'
-import { NotificationMenu } from '@/src/shared'
-import { TooltipFreeTokens } from '@/src/shared'
+import { change } from '#/entities/theme'
+import { useAppDispatch, useAppSelector } from '#/app/store/store'
+import { AccountMenu } from '#/shared'
+import { NotificationMenu } from '#/shared'
+import { TooltipFreeTokens } from '#/shared'
function a11yProps(index: number) {
return {
@@ -79,7 +79,7 @@ export const MainMenu: React.FC = memo(() => {
const selectPage = pathname === '/' ? 0 : pathname === '/service-keys' ? 1 : pathname === '/admin' ? 2 : 3
- const ErrorModalLazy = dynamic(() => import('@/src/shared/ui/error-modal'), { ssr: false })
+ const ErrorModalLazy = dynamic(() => import('#/shared/ui/error-modal'), { ssr: false })
return (
@@ -111,7 +111,11 @@ export const MainMenu: React.FC = memo(() => {
alt={''}
height={18}
width={18}
- src={pathname == '/' ? '/svg/main_menu/marketplace.svg' : '/svg/main_menu/marketplace_off.svg'}
+ src={
+ pathname == '/'
+ ? '/svg/main_menu/marketplace.svg'
+ : '/svg/main_menu/marketplace_off.svg'
+ }
/>
}
iconPosition='start'
@@ -134,7 +138,8 @@ export const MainMenu: React.FC = memo(() => {
'& .MuiTooltip-arrow': {
color: theme === 'light' ? '#E8E8FA' : '#4B4B4B',
},
- boxShadow: '0px 0px 4px rgba(0, 0, 0, 0.04), 0px 4px 32px rgba(0, 0, 0, 0.16)',
+ boxShadow:
+ '0px 0px 4px rgba(0, 0, 0, 0.04), 0px 4px 32px rgba(0, 0, 0, 0.16)',
},
},
}}
@@ -147,7 +152,11 @@ export const MainMenu: React.FC = memo(() => {
}
@@ -177,7 +186,13 @@ export const MainMenu: React.FC = memo(() => {
alt='Error'
/>
)}
- {openErrorModal && }
+ {openErrorModal && (
+
+ )}
{
width={19}
alt='Bell'
/>
-
+
{
- const LazyCode = dynamic(() => import('@/src/widgets/chat-gpt-field/ui/code'))
+ const LazyCode = dynamic(() => import('#/widgets/chat-gpt-field/ui/code'))
return (
{
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<>
-
+
{children}
>
@@ -1,5 +1,18 @@
export const getDayMontsString = (inputDate: string): string => {
- const monthNames = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']
+ const monthNames = [
+ 'января',
+ 'февраля',
+ 'марта',
+ 'апреля',
+ 'мая',
+ 'июня',
+ 'июля',
+ 'августа',
+ 'сентября',
+ 'октября',
+ 'ноября',
+ 'декабря',
+ ]
const date = new Date(inputDate)
const day = date.getDate()
@@ -2,7 +2,7 @@ import React from 'react'
import { Box } from '@mui/material'
import Link from 'next/link'
-import { Message } from '@/src/shared/lib/types/model'
+import { Message } from '#/shared/lib/types/model'
export function AnswerWrap(props: { message: Message }) {
if (props.message.file) {
@@ -3,9 +3,9 @@ import { Box, Menu, MenuItem, Slide, Typography } from '@mui/material'
import Stack from '@mui/material/Stack'
import Image from 'next/image'
-import { useAppSelector } from '@/src/main/store/store'
-import { TooltipCustom } from '@/src/shared'
-import { Markdown } from '@/src/widgets/markdown/markdown'
+import { useAppSelector } from '#/app/store/store'
+import { TooltipCustom } from '#/shared'
+import { Markdown } from '#/widgets/markdown/markdown'
export function BotMessage(props: any) {
// const LazyCode = dynamic(() => import('src/widgets/chat-gpt-field/ui/code'))
@@ -136,7 +136,13 @@ export function BotMessage(props: any) {
}}
>
{props.message.file && props.modelType !== 'chatgpt' ? (
-
@@ -160,10 +170,40 @@ export function BotMessage(props: any) {
aria-expanded={open ? 'true' : undefined}
>
-
-
-
-
+
+
+
+
@@ -197,10 +237,20 @@ export function BotMessage(props: any) {
gap: '10px',
}}
onClick={() => {
- copy(props.message.content ? props.message.content : props.message.file.split('/')[4].split('?')[0])
+ copy(
+ props.message.content
+ ? props.message.content
+ : props.message.file.split('/')[4].split('?')[0]
+ )
}}
>
-
+
-
+
- {props.message.file && }
+ {props.message.file && (
+
+ )}
{!props.message.from_model ? (
//
@@ -129,7 +131,8 @@ export const UserMessage = React.memo(function UserMessage(props: IMessagesList)
{!loaded && (
-
+
@@ -198,12 +207,18 @@ export const UserMessage = React.memo(function UserMessage(props: IMessagesList)
onClick={handleClose}
sx={{
'& .MuiMenu-list': {
- backgroundColor: theme === 'dark' ? '#303035' : '#EFF0F2',
+ backgroundColor:
+ theme === 'dark'
+ ? '#303035'
+ : '#EFF0F2',
color: '#8280FF',
borderRadius: '15px',
},
'& .MuiPopover-paper': {
- backgroundColor: theme === 'dark' ? '#303035' : '#EFF0F2',
+ backgroundColor:
+ theme === 'dark'
+ ? '#303035'
+ : '#EFF0F2',
borderRadius: '15px',
},
}}
@@ -262,7 +277,8 @@ export const UserMessage = React.memo(function UserMessage(props: IMessagesList)
gap: '5px',
}}
onClick={() => {
- if (props.deleteMessage) props.deleteMessage(props.message.uid)
+ if (props.deleteMessage)
+ props.deleteMessage(props.message.uid)
}}
>
30 ? 'pre-wrap' : 'pre',
+ whiteSpace:
+ props.message.content.length > 30
+ ? 'pre-wrap'
+ : 'pre',
}}
>
{/**/}
@@ -360,7 +382,13 @@ export const UserMessage = React.memo(function UserMessage(props: IMessagesList)
stroke='#A4AAB5'
strokeWidth='2'
/>
-
+
@@ -373,12 +401,14 @@ export const UserMessage = React.memo(function UserMessage(props: IMessagesList)
onClick={handleClose}
sx={{
'& .MuiMenu-list': {
- backgroundColor: theme === 'dark' ? '#303035' : '#EFF0F2',
+ backgroundColor:
+ theme === 'dark' ? '#303035' : '#EFF0F2',
color: '#8280FF',
borderRadius: '15px',
},
'& .MuiPopover-paper': {
- backgroundColor: theme === 'dark' ? '#303035' : '#EFF0F2',
+ backgroundColor:
+ theme === 'dark' ? '#303035' : '#EFF0F2',
borderRadius: '15px',
},
}}
@@ -437,7 +467,8 @@ export const UserMessage = React.memo(function UserMessage(props: IMessagesList)
gap: '5px',
}}
onClick={() => {
- if (props.deleteMessage) props.deleteMessage(props.message.uid)
+ if (props.deleteMessage)
+ props.deleteMessage(props.message.uid)
}}
>
30 ? 'pre-wrap' : 'pre',
+ whiteSpace:
+ props.message.content.length > 30 ? 'pre-wrap' : 'pre',
}}
>
{/**/}
@@ -2,10 +2,10 @@ import React, { memo, useEffect } from 'react'
import { Box, CircularProgress } from '@mui/material'
import { useSession } from 'next-auth/react'
-import { Message } from '@/src/shared/lib/types/model'
-import { ArrowDownScroll } from '@/src/shared/ui/icon-components/scroll-down-arrow'
-import { IsNextDay } from '@/src/widgets/messages/is-next-day'
-import { PreviewView } from '@/src/widgets/messages/message-components/preview-view'
+import { Message } from '#/shared/lib/types/model'
+import { ArrowDownScroll } from '#/shared/ui/icon-components/scroll-down-arrow'
+import { IsNextDay } from '#/widgets/messages/is-next-day'
+import { PreviewView } from '#/widgets/messages/message-components/preview-view'
interface IMessagesList {
device: 'mobile' | 'desktop'
@@ -22,7 +22,18 @@ interface IMessagesList {
}
export const ChatMessagesList: React.FC = memo(
- ({ messageResponse, onLoadImage, setResendValue, modelTitle, device, modelType, mode, getMessagesPagination, deleteMessage, loading }) => {
+ ({
+ messageResponse,
+ onLoadImage,
+ setResendValue,
+ modelTitle,
+ device,
+ modelType,
+ mode,
+ getMessagesPagination,
+ deleteMessage,
+ loading,
+ }) => {
const paginationScroll = React.useRef()
const [isPaginating, setIsPaginating] = React.useState(false)
const [chatScrollHeight, setChatScrollHeight] = React.useState(0)
@@ -62,8 +73,16 @@ export const ChatMessagesList: React.FC = memo(
}, [messageResponse])
const handleScroll = () => {
- console.log(paginationScroll.current?.scrollHeight - paginationScroll.current?.scrollTop - paginationScroll.current?.clientHeight)
- setScrollBottom(paginationScroll.current?.scrollHeight - paginationScroll.current?.scrollTop - paginationScroll.current?.clientHeight)
+ console.log(
+ paginationScroll.current?.scrollHeight -
+ paginationScroll.current?.scrollTop -
+ paginationScroll.current?.clientHeight
+ )
+ setScrollBottom(
+ paginationScroll.current?.scrollHeight -
+ paginationScroll.current?.scrollTop -
+ paginationScroll.current?.clientHeight
+ )
if (paginationScroll.current && messageResponse?.length !== 0) {
const { scrollTop, scrollHeight, clientHeight } = paginationScroll.current
@@ -1,36 +1,35 @@
.wrap {
- display: flex;
- overflow: hidden;
- width: 100%;
- flex-wrap: wrap;
- gap: 20px;
- @media (max-width: 766px) {
- height: 70vh;
- width: 100%;
- overflow-y: scroll;
- text-align: center;
- justify-content: center;
- }
- div {
- margin-right: 10px;
- @media (max-width: 766px) {
- width: 100%;
- }
+ display: flex;
+ overflow: hidden;
+ width: 100%;
+ flex-wrap: wrap;
+ gap: 20px;
+ @media (max-width: 766px) {
+ height: 70vh;
+ width: 100%;
+ overflow-y: scroll;
+ text-align: center;
+ justify-content: center;
+ }
+ div {
+ margin-right: 10px;
+ @media (max-width: 766px) {
+ width: 100%;
+ }
- .image {
- margin:10px auto;
- width: 250px;
- height: 250px;
- border-radius: 15px !important;
- }
+ .image {
+ margin: 10px auto;
+ width: 250px;
+ height: 250px;
+ border-radius: 15px !important;
+ }
- @media (max-width: 1700px) {
+ @media (max-width: 1700px) {
+ }
- }
-
- @media (max-width: 766px) {
- text-align: center;
- width: 80%;
- }
- }
-}
\ No newline at end of file
+ @media (max-width: 766px) {
+ text-align: center;
+ width: 80%;
+ }
+ }
+}
@@ -4,11 +4,11 @@ import Box from '@mui/material/Box'
import Image from 'next/image'
import Link from 'next/link'
-import FullScreenModal from '@/src/features/image-modal/full-screen-modal'
-import { useAppSelector } from '@/src/main/store/store'
-import { Success, TooltipCustom, useShowData } from '@/src/shared'
-import { useAutoScroll } from '@/src/shared/lib/hooks'
-import { Message } from '@/src/shared/lib/types/model'
+import FullScreenModal from '#/features/image-modal/full-screen-modal'
+import { useAppSelector } from '#/app/store/store'
+import { Success, TooltipCustom, useShowData } from '#/shared'
+import { useAutoScroll } from '#/shared/lib/hooks'
+import { Message } from '#/shared/lib/types/model'
import styles from './image-messages-list.module.scss'
@@ -60,7 +60,13 @@ export const ImageMessagesList: React.FC = memo(({ device, images
return (
<>
toggleMenu(uid)}
width='35'
height='35'
@@ -226,8 +232,13 @@ export const ImageMessagesList: React.FC = memo(({ device, images
}}
width={500}
height={500}
- src={(message.file as unknown as string) || ''}
- alt={'К сожалению, изображение не загрузилось'}
+ src={
+ (message.file as unknown as string) ||
+ ''
+ }
+ alt={
+ 'К сожалению, изображение не загрузилось'
+ }
/>
= memo(({ device, images
}}
width={10}
height={10}
- src={(message.file as unknown as string) || ''}
+ src={
+ (message.file as unknown as string) ||
+ ''
+ }
alt=''
/>
>
@@ -267,7 +281,10 @@ export const ImageMessagesList: React.FC = memo(({ device, images
userSelect: 'none',
objectFit: 'contain',
}}
- src={(message.file as unknown as string) || ''}
+ src={
+ (message.file as unknown as string) ||
+ ''
+ }
alt='К сожалению, изображение не загрузилось'
/>
= memo(({ device, images
right: 0,
filter: 'blur(10px) brightness(0.7)',
}}
- src={(message.file as unknown as string) || ''}
+ src={
+ (message.file as unknown as string) ||
+ ''
+ }
alt='К сожалению, изображение не загрузилось'
/>
>
@@ -295,14 +315,19 @@ export const ImageMessagesList: React.FC = memo(({ device, images
{!loaded && (
@@ -331,7 +356,9 @@ export const ImageMessagesList: React.FC = memo(({ device, images
{!loaded
? ''
: message.content.length > 0
- ? message?.content.replaceAll('"', '').slice(0, 30)
+ ? message?.content
+ .replaceAll('"', '')
+ .slice(0, 30)
: 'описание отсутствует'}
{message?.content.length > 30 && loaded && '...'}
@@ -1,10 +1,10 @@
import React, { memo } from 'react'
import { Box, Typography } from '@mui/material'
-import { Message } from '@/src/shared/lib/types/model'
-import { getDateFromString } from '@/src/widgets/messages/lib/getDateFromString'
-import { getDayMontsString } from '@/src/widgets/messages/lib/getDayMontsString'
-import { UserMessage } from '@/src/widgets/messages/message-components/user-message'
+import { Message } from '#/shared/lib/types/model'
+import { getDateFromString } from '#/widgets/messages/lib/getDateFromString'
+import { getDayMontsString } from '#/widgets/messages/lib/getDayMontsString'
+import { UserMessage } from '#/widgets/messages/message-components/user-message'
interface IProps {
message: Message
@@ -21,7 +21,18 @@ interface IProps {
}
export const IsNextDay = memo(
- ({ message, index, onLoadImage, messageResponse, modelTitle, deleteMessage, isNewMessage, modelType, device, setResendValue }: IProps) => {
+ ({
+ message,
+ index,
+ onLoadImage,
+ messageResponse,
+ modelTitle,
+ deleteMessage,
+ isNewMessage,
+ modelType,
+ device,
+ setResendValue,
+ }: IProps) => {
if (messageResponse && message.created_at) {
const date = getDateFromString(message.created_at)
const prevDate = getDateFromString(messageResponse[index]?.created_at)
@@ -1,5 +1,5 @@
import { NavigationSearchModelLink } from './types'
-import { API_URL } from '@/src/shared/lib/constants'
+import { API_URL } from '#/shared/lib/constants'
import axios from 'axios'
export const getModelChatLinks = async (token: string) => {
@@ -8,5 +8,5 @@ export interface NavigationSearchLink {
url: string
category: string
external?: boolean
- uid?: string
+ uid?: string
}
@@ -1,35 +1,35 @@
-import { NavigationSearchLink } from "../api/types";
+import { NavigationSearchLink } from '../api/types'
export const staticLinks: NavigationSearchLink[] = [
{
label: 'Дашборд',
url: '/',
- category: 'Навигация'
+ category: 'Навигация',
},
{
label: 'Оплата',
url: '/account?scope=subscribe',
- category: 'Навигация',
+ category: 'Навигация',
},
{
label: 'Настройки',
url: '/account?scope=setting',
- category: 'Навигация',
+ category: 'Навигация',
},
{
label: 'Настройки корп. аккаунта',
url: '/account?scope=business',
- category: 'Навигация',
+ category: 'Навигация',
},
{
label: 'API-ключи',
url: '/api-keys',
- category: 'Навигация',
+ category: 'Навигация',
},
{
label: 'Реквизиты',
url: 'https://air.fail/requisites',
- category: 'Навигация',
+ category: 'Навигация',
external: true,
},
]
@@ -1,2 +1,2 @@
export * from './use-model'
-export * from './use-chat-links'
\ No newline at end of file
+export * from './use-chat-links'
@@ -10,7 +10,7 @@ export const useNavigationSearchChatLinks = () => {
const { data } = useSession()
const fetchChatLinks = async () => {
- if(!data) return
+ if (!data) return
setChatLinks((await getModelChatLinks(data.access)).data)
}
@@ -4,8 +4,8 @@ import Image from 'next/image'
import { KeyForSearch } from './key-for-search'
import { useNavigationSearchChatLinks, useNavigationSearchModel } from '../model'
import { staticLinks } from '../config'
-import { InputStyleDark, InputStyleLight, useConcat } from '@/src/shared'
-import { useAppSelector } from '@/src/main/store/store'
+import { InputStyleDark, InputStyleLight, useConcat } from '#/shared'
+import { useAppSelector } from '#/app/store/store'
import { useRouter } from 'next/router'
import { NavigationSearchLink } from '../api/types'
import { useNavigationSearchMediaLinks } from '../model/use-media-links'
@@ -25,18 +25,13 @@ export const Search = ({ device }: SearchProps) => {
const { fetchMediaLinks, visibleMediaLinks } = useNavigationSearchMediaLinks()
- const links = useConcat(
- visibleChatLinks,
- visibleMediaLinks,
- staticLinks
- )
-
- useEffect(() => {
- console.log(links)
- }, [links])
+ const links = useConcat(visibleChatLinks, visibleMediaLinks, staticLinks)
+
+ useEffect(() => {
+ console.log(links)
+ }, [links])
- const { search, setSearch, searchOpen, setSearchOpen, searchRef, filteredLinks } =
- useNavigationSearchModel(links)
+ const { search, setSearch, searchOpen, setSearchOpen, searchRef, filteredLinks } = useNavigationSearchModel(links)
useEffect(() => {
fetchChatLinks()
@@ -138,11 +133,7 @@ export const Search = ({ device }: SearchProps) => {
/>
),
endAdornment: (
-
+
),
}}
/>
@@ -1,2 +1,2 @@
export * from './ui'
-export * from './config'
\ No newline at end of file
+export * from './config'
@@ -4,11 +4,11 @@ import { Accordion, AccordionDetails, AccordionSummary, Box, Button, MenuItem, S
import Router, { useRouter } from 'next/router'
import { useSession } from 'next-auth/react'
-import { useAppSelector } from '@/src/main/store/store'
-import { CheckBoxAgreeWithRules, Loader, Select } from '@/src/shared'
-import { accountApi } from '@/src/shared/api/account-endpoints'
-import { getPaymentsHistory, PaymentHistory } from '@/src/shared/api/endpoints'
-import Offer from '@/src/widgets/payment/ui/offer'
+import { useAppSelector } from '#/app/store/store'
+import { CheckBoxAgreeWithRules, Loader, Select } from '#/shared'
+import { accountApi } from '#/shared/api/account-endpoints'
+import { getPaymentsHistory, PaymentHistory } from '#/shared/api/endpoints'
+import Offer from '#/widgets/payment/ui/offer'
import styles from '../ui/payment.module.scss'
@@ -71,7 +71,12 @@ export const Payment: React.FC = ({ device, changeClose })
{offers?.map((offer) => {
return (
@@ -91,10 +96,19 @@ export const Payment: React.FC = ({ device, changeClose })
})}
{messages && (
-
+
История
{messages.map((el) => (
-
+
))}
@@ -146,7 +160,11 @@ const HistoryMessage: React.FC = ({ tokens, time, price }) => {
}
return (
-
+
Оплата
{price} ₽, {Math.floor(+tokens)} токенов
@@ -2,10 +2,10 @@ import React from 'react'
import { Box, Typography } from '@mui/material'
import Button from '@mui/material/Button'
-import { Balance } from '@/src/shared'
-import { useThemeAndDevice } from '@/src/shared/lib/hooks'
-import { IOffer } from '@/src/widgets/payment/model/payment'
-import styles from '@/src/widgets/payment/ui/payment.module.scss'
+import { Balance } from '#/shared'
+import { useThemeAndDevice } from '#/shared/lib/hooks'
+import { IOffer } from '#/widgets/payment/model/payment'
+import styles from '#/widgets/payment/ui/payment.module.scss'
interface IOfferProps extends IOffer {
pickOffer: (uid: string) => void
@@ -19,7 +19,16 @@ const duration = {
year: 'год',
}
-const Offer: React.FC = ({ pickOffer, uid, tokens_per_plan, price, selectedOffer, title, duration: dur, pay }) => {
+const Offer: React.FC = ({
+ pickOffer,
+ uid,
+ tokens_per_plan,
+ price,
+ selectedOffer,
+ title,
+ duration: dur,
+ pay,
+}) => {
return (
pickOffer(uid)}>
{title}
@@ -15,7 +15,6 @@
}
div {
-
height: 176px;
display: flex;
flex-direction: column;
@@ -65,7 +64,7 @@
padding: 30px;
@media (max-width: 768px) {
width: 94vw;
-
+
height: 300px;
margin: 0;
margin-top: 10px;
@@ -4,10 +4,10 @@ import Image from 'next/image'
import { useRouter } from 'next/router'
import { useSession } from 'next-auth/react'
-import { useAppSelector } from '@/src/main/store/store'
-import { Success, useShowData } from '@/src/shared'
-import { getReferral, IReferral } from '@/src/shared/api/endpoints'
-import { API_HOST } from '@/src/shared/lib/constants'
+import { useAppSelector } from '#/app/store/store'
+import { Success, useShowData } from '#/shared'
+import { getReferral, IReferral } from '#/shared/api/endpoints'
+import { API_HOST } from '#/shared/lib/constants'
interface IProps {
device: 'desktop' | 'mobile'
}
@@ -55,8 +55,17 @@ export const Referral = ({ device }: IProps) => {
}, [data?.access])
return (
-
-
+
+
{
Пригласи друга!
-
+
Получай токены: 20% за подписки твоих рефералов!
{/*Условия акции*/}
@@ -95,15 +111,26 @@ export const Referral = ({ device }: IProps) => {
{
- navigator.clipboard.writeText(url).then(() => showError('Ссылка скопирована!'))
+ navigator.clipboard
+ .writeText(url)
+ .then(() => showError('Ссылка скопирована!'))
}}
/>
-
+
{
Регистраций
- {referrals?.registrations_count || 0}
+
+ {referrals?.registrations_count || 0}
+
@@ -222,7 +251,9 @@ export const Referral = ({ device }: IProps) => {
Бонусов
- {referrals?.accrued_bonuses_amount || 0}
+
+ {referrals?.accrued_bonuses_amount || 0}
+
@@ -257,13 +288,31 @@ export const Referral = ({ device }: IProps) => {
alt={'avatar'}
width={50}
height={50}
- style={{ width: '50px', height: '50px', borderRadius: '100%', objectFit: 'cover' }}
+ style={{
+ width: '50px',
+ height: '50px',
+ borderRadius: '100%',
+ objectFit: 'cover',
+ }}
/>
-
- {el.username.length > 20 ? el.username.slice(0, 20) + '...' : el.username}
+
+ {el.username.length > 20
+ ? el.username.slice(0, 20) + '...'
+ : el.username}
-
+
{el.joined_at.slice(0, 10).split('-').reverse().join('.')}
@@ -2,9 +2,9 @@ import React, { memo } from 'react'
import { Box, Typography } from '@mui/material'
import Image from 'next/image'
-import { useAppSelector } from '@/src/main/store/store'
-import { useAutoScroll } from '@/src/shared/lib/hooks'
-import { IResponseSD } from '@/src/shared/lib/types/types-sd'
+import { useAppSelector } from '#/app/store/store'
+import { useAutoScroll } from '#/shared/lib/hooks'
+import { IResponseSD } from '#/shared/lib/types/types-sd'
interface ISDMessagesList {
messages: IResponseSD[]
@@ -22,7 +22,13 @@ export const SdMessagesList: React.FC = memo(({ messages, devic
ref={refScroll}
sx={{
overflowY: 'scroll',
- backgroundColor: desktop ? (theme === 'light' ? '#F8F8F8' : '#4B4B4B') : theme === 'light' ? 'white' : '#4B4B4B',
+ backgroundColor: desktop
+ ? theme === 'light'
+ ? '#F8F8F8'
+ : '#4B4B4B'
+ : theme === 'light'
+ ? 'white'
+ : '#4B4B4B',
maxWidth: '100%',
padding: 2,
borderRadius: 5,
@@ -61,9 +67,21 @@ export const SdMessagesList: React.FC = memo(({ messages, devic
href={img.link}
download
>
-
+
-
+
import('@/src/shared/ui/error-modal'), { ssr: false })
+ const ErrorModalLazy = dynamic(() => import('#/shared/ui/error-modal'), { ssr: false })
const [openErrorModal, setOpenErrorModal] = React.useState(false)
@@ -125,7 +140,11 @@ export const SideMenu = ({ device, sidemenuDefaultOpen }: { device: Device; side
useEffect(() => {
if (settings.state !== null && isInitialValueSet) {
- let response = isSettingExist({ settings: settings.state, targetDevice: device, targetType: 'sidemenu' })
+ let response = isSettingExist({
+ settings: settings.state,
+ targetDevice: device,
+ targetType: 'sidemenu',
+ })
if (response && data?.access) {
dispatch(
@@ -140,7 +159,11 @@ export const SideMenu = ({ device, sidemenuDefaultOpen }: { device: Device; side
dispatch(
addUserAccountSettings({
token: data.access,
- setting: { device, type: 'sidemenu', value: { sidemenu_state: open ? 'opened' : 'closed' } },
+ setting: {
+ device,
+ type: 'sidemenu',
+ value: { sidemenu_state: open ? 'opened' : 'closed' },
+ },
})
)
}
@@ -149,7 +172,11 @@ export const SideMenu = ({ device, sidemenuDefaultOpen }: { device: Device; side
useEffect(() => {
if (settings.state !== null && !isInitialValueSet) {
- let setting = isSettingExist({ settings: settings.state, targetDevice: device, targetType: 'sidemenu' })
+ let setting = isSettingExist({
+ settings: settings.state,
+ targetDevice: device,
+ targetType: 'sidemenu',
+ })
if (setting) {
setting?.value?.sidemenu_state === 'opened' ? setOpen(true) : setOpen(false)
}
@@ -160,7 +187,12 @@ export const SideMenu = ({ device, sidemenuDefaultOpen }: { device: Device; side
return (
@@ -180,7 +212,14 @@ export const SideMenu = ({ device, sidemenuDefaultOpen }: { device: Device; side
alignItems={'center'}
justifyContent='space-between'
>
-
+
>
)}
- {openErrorModal && }
+ {openErrorModal && (
+
+ )}
{open && (
-
+
Реквизиты
@@ -282,7 +330,10 @@ type MenuItemProps = {
}
export function MenuItem(props: MenuItemProps) {
- const isActive = useMemo(() => props.link === props.pathname || props.activeList?.some((el) => props.pathname.includes(el)), [props.pathname])
+ const isActive = useMemo(
+ () => props.link === props.pathname || props.activeList?.some((el) => props.pathname.includes(el)),
+ [props.pathname]
+ )
const theme = useAppSelector((state) => state.theme.theme)
return (
@@ -341,7 +392,12 @@ export function MenuItem(props: MenuItemProps) {
justifyContent: 'center',
}}
>
-
+
@@ -1,16 +1,35 @@
import { useMemo } from 'react'
import { Doughnut, Line } from 'react-chartjs-2'
-import { Box, LinearProgress, linearProgressClasses, styled, ToggleButton, ToggleButtonGroup, Typography } from '@mui/material'
+import {
+ Box,
+ LinearProgress,
+ linearProgressClasses,
+ styled,
+ ToggleButton,
+ ToggleButtonGroup,
+ Typography,
+} from '@mui/material'
import { LocalizationProvider } from '@mui/x-date-pickers'
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'
-import { ArcElement, CategoryScale, Chart as ChartJS, Filler, Legend, LinearScale, LineElement, PointElement, Title, Tooltip } from 'chart.js'
+import {
+ ArcElement,
+ CategoryScale,
+ Chart as ChartJS,
+ Filler,
+ Legend,
+ LinearScale,
+ LineElement,
+ PointElement,
+ Title,
+ Tooltip,
+} from 'chart.js'
-import { useStats } from '@/src/features/use-stats/use-stats'
-import { RootState, useAppSelector } from '@/src/main/store/store'
-import styles2 from '@/src/main/styles/account.module.css'
-import styles from '@/src/main/styles/styles-pages/index-styles.module.scss'
-import { DoughnutOptions, lineOptions } from '@/src/shared'
-import { balanceSelector } from '@/src/shared/lib/selectors'
+import { useStats } from '#/features/use-stats/use-stats'
+import { RootState, useAppSelector } from '#/app/store/store'
+import styles2 from '#/app/styles/account.module.css'
+import styles from '#/app/styles/styles-pages/index-styles.module.scss'
+import { DoughnutOptions, lineOptions } from '#/shared'
+import { balanceSelector } from '#/shared/lib/selectors'
const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
height: 18,
@@ -26,7 +45,11 @@ const BorderLinearProgress = styled(LinearProgress)(({ theme }) => ({
ChartJS.register(ArcElement, Tooltip, Legend, CategoryScale, LinearScale, PointElement, LineElement, Title, Filler)
-const timeForStatsValues = { current_month: 'Текущий месяц', current_week: 'Текущая неделя', previous_month: 'Предыдущий месяц' }
+const timeForStatsValues = {
+ current_month: 'Текущий месяц',
+ current_week: 'Текущая неделя',
+ previous_month: 'Предыдущий месяц',
+}
export const Statistics = (props: any) => {
const { payment_plan } = useAppSelector((state) => state.user)
@@ -41,7 +64,13 @@ export const Statistics = (props: any) => {
- 1 + 2} aria-label='Platform'>
+ 1 + 2}
+ aria-label='Platform'
+ >
{Object.entries(timeForStatsValues).map(([key, value]) => {
return (
{
className={styles2.toggle_button}
value='web'
>
-
-
+
+
{value}
@@ -97,7 +138,11 @@ export const Statistics = (props: any) => {
paddingBottom: '35px !important',
}}
>
-
+
Расходы по дням
@@ -108,7 +153,13 @@ export const Statistics = (props: any) => {
)}
-
+
Расходы по категориям
@@ -127,7 +178,10 @@ export const Statistics = (props: any) => {
marginRight: '15px',
}}
>
-
+
@@ -152,7 +206,10 @@ export const Statistics = (props: any) => {
marginRight: '15px',
}}
>
-
+
@@ -167,8 +224,19 @@ export const Statistics = (props: any) => {
function NoData() {
return (
-
- Для отображения статистики пока что недостаточно данных в заданном диапазоне 😢
+
+
+ Для отображения статистики пока что недостаточно данных в заданном диапазоне 😢{' '}
+
)
}
@@ -191,7 +259,14 @@ function LabelList(props: any) {
return (
{(props.data as any).labels?.map((el: any, idx: any) => {
- return
+ return (
+
+ )
})}
)
@@ -2,8 +2,8 @@ import React, { memo } from 'react'
import { Box } from '@mui/material'
import dayjs, { Dayjs } from 'dayjs'
-import { Group, Product, Stats } from '@/src/features/get-admin-stats'
-import { IProps } from '@/src/shared/lib/types/entities'
+import { Group, Product, Stats } from '#/features/get-admin-stats'
+import { IProps } from '#/shared/lib/types/entities'
import StatsFilters from '../ui/stats-filters'
@@ -34,7 +34,15 @@ export const StatsField: React.FC = memo(({ device, token, theme }) => {
changeProduct={(product) => setProduct(product)}
productsList={productList}
/>
-
+
)
})
@@ -5,8 +5,8 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'
import { Dayjs } from 'dayjs'
-import { Group, Product, RequestStats } from '@/src/features/get-admin-stats'
-import { Select } from '@/src/shared'
+import { Group, Product, RequestStats } from '#/features/get-admin-stats'
+import { Select } from '#/shared'
interface StatsFiltersProps extends RequestStats {
changeStartDate: (date: Dayjs | null) => void
@@ -32,7 +32,12 @@ const StatsFilters: React.FC = ({
return (
- changeStartDate(e)} sx={{ marginBottom: 2 }} label='Начиная с' />
+ changeStartDate(e)}
+ sx={{ marginBottom: 2 }}
+ label='Начиная с'
+ />
changeEndDate(e)} label='По' />