+
{Number(actual_stat.tokens_cost)}
@@ -0,0 +1,19 @@
+import { Attributes, FC, ReactElement } from 'react'
+import { Layout } from '../ui'
+import { LayoutProps } from '../types'
+import React from 'react'
+
+export const getDefaultLayout = function (layoutProps: Omit
= {}) {
+ return (page: ReactElement) => {page}
+}
+
+export const getLayout = function (
+ Element: (...props: any) => JSX.Element,
+ layoutProps: Omit = {}
+) {
+ 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,10 @@
+import { Device } from "#/shared/lib/types/entities"
+
+
+export interface LayoutProps {
+ children: React.ReactNode
+ titlePage?: string
+ title?: string | React.ReactNode | null
+ device?: Device
+ isLoader?: boolean
+}
\ No newline at end of file
@@ -0,0 +1,150 @@
+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', '/change-password']
+
+export const Layout: React.FC = ({
+ children,
+ titlePage,
+ title = titlePage,
+ isLoader,
+ device = getDeviceType(),
+}) => {
+ const { data: sessionData } = useSession()
+ const appState = useAppSelector((state) => state)
+ const dispatch = useAppDispatch()
+
+ 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}
+
+
+
+
+
+
+
+
+ {desktop ? (
+
+
+
+
+
+ {children}
+
+
+
+ ) : (
+
+
+ {children}
+
+ )}
+
+
+ >
+ )
+}
@@ -0,0 +1,2 @@
+export * from './default'
+export * from './layout-without-sidemenu'
@@ -0,0 +1,40 @@
+import React, { Component, FunctionComponent } from 'react'
+import { LayoutProps } from '../types'
+import { Box } from '@mui/material'
+import Head from 'next/head'
+import { getDeviceType } from '#/shared/lib/helpers'
+import { useTheme } from '#/entities/theme'
+
+export const LayoutWithoutSideMenu = ({ children, titlePage, device = getDeviceType() }: LayoutProps) => {
+ const desktop = device === 'desktop'
+
+ useTheme()
+
+ return (
+ <>
+
+ {titlePage && {titlePage}}
+
+
+
+
+
+
+
+
+ {children}
+
+
+ >
+ )
+}
@@ -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'
/>
-
+
@@ -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]
+ )
}}
>
-
+
-
+
= memo(({ device, images,
}
}
- const ImageIcons = ({
- uid,
- url,
- content,
- }: {
- uid: string
- url: string | null
- content: string | undefined
- }) => {
+ const ImageIcons = ({ uid, url, content }: { uid: string; url: string | null; content: string | undefined }) => {
return (
<>
= memo(({ device, images,
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
-
+
= memo(({ device, images,
images={computedLibraryImages}
modal={modal}
onSlideFalse={() => getMessagesPagination && getMessagesPagination()}
- setModal={setModal}
+ setModal={setModal}
reverse={device === 'desktop'}
current={chosenImage}
/>,
@@ -216,29 +203,14 @@ export const ImageMessagesList: React.FC = memo(({ device, images,
sx={{
border: '1px solid #8280FF',
borderRadius: 5,
- width:
- device === 'desktop'
- ? '250px'
- : '291px',
- height:
- device === 'desktop'
- ? '284px'
- : '291px',
+ width: device === 'desktop' ? '250px' : '291px',
+ height: device === 'desktop' ? '284px' : '291px',
}}
>
-
- Эта генерация является архивом
-
-
-
- Скачать
-
+ Эта генерация является архивом
+
+ Скачать
@@ -247,14 +219,8 @@ export const ImageMessagesList: React.FC = memo(({ device, images,
= memo(({ device, images,
{
- setChosenImage(
- message.file as string
- )
+ setChosenImage(message.file as string)
setModal(true)
}}
- onLoadingComplete={() =>
- setLoaded(true)
- }
+ onLoadingComplete={() => setLoaded(true)}
style={{
- position:
- 'relative',
+ position: 'relative',
zIndex: '2',
borderRadius: 15,
width: '100%',
height: '100%',
- opacity: loaded
- ? '100%'
- : '0%',
+ opacity: loaded ? '100%' : '0%',
userSelect: 'none',
- objectFit:
- 'contain',
+ objectFit: 'contain',
}}
width={500}
height={500}
@@ -302,19 +260,14 @@ export const ImageMessagesList: React.FC = memo(({ device, images,
/>
- setLoaded(true)
- }
+ onLoadingComplete={() => setLoaded(true)}
style={{
- position:
- 'absolute',
+ position: 'absolute',
zIndex: '1',
borderRadius: 15,
width: '100%',
height: '100%',
- opacity: loaded
- ? '100%'
- : '0%',
+ opacity: loaded ? '100%' : '0%',
userSelect: 'none',
objectFit: 'cover',
right: 0,
@@ -334,21 +287,17 @@ export const ImageMessagesList: React.FC = memo(({ device, images,
{
- setChosenImage(
- message.file as string
- )
+ setChosenImage(message.file as string)
setModal(true)
}}
style={{
- position:
- 'relative',
+ position: 'relative',
zIndex: '2',
borderRadius: 15,
width: '100%',
height: '100%',
userSelect: 'none',
- objectFit:
- 'contain',
+ objectFit: 'contain',
}}
src={
(message.file as unknown as string) ||
@@ -361,15 +310,12 @@ export const ImageMessagesList: React.FC = memo(({ device, images,
width='10px'
height='10px'
style={{
- position:
- 'absolute',
+ position: 'absolute',
zIndex: '1',
borderRadius: 15,
width: '100%',
height: '100%',
- opacity: loaded
- ? '100%'
- : '0%',
+ opacity: loaded ? '100%' : '0%',
userSelect: 'none',
objectFit: 'cover',
right: 0,
@@ -408,35 +354,21 @@ export const ImageMessagesList: React.FC = memo(({ device, images,
key={message.uid}
uid={message.uid}
content={message.content}
- url={
- message.file
- ? message.file.toString()
- : null
- }
+ url={message.file ? message.file.toString() : null}
/>
30
- ? message.content
- : ''
- }
+ title={message.content.length > 30 ? message.content : ''}
>
{!loaded
@@ -446,9 +378,7 @@ export const ImageMessagesList: React.FC = memo(({ device, images,
.replaceAll('"', '')
.slice(0, 30)
: 'описание отсутствует'}
- {message?.content.length > 30 &&
- loaded &&
- '...'}
+ {message?.content.length > 30 && loaded && '...'}
@@ -1,10 +1,10 @@
import React, { memo, useMemo } from 'react'
import { Box, Typography } from '@mui/material'
-import { Message } from '@/src/shared/lib/types/model'
-import { getDateFromString } from '@/src/widgets/messages/lib/date-from-string'
-import { getDayMontsString } from '@/src/widgets/messages/lib/day-months-string'
-import { UserMessage } from '@/src/widgets/messages/ui/user-message'
+import { Message } from '#/shared/lib/types/model'
+import { getDateFromString } from '#/widgets/messages/lib/date-from-string'
+import { getDayMontsString } from '#/widgets/messages/lib/day-months-string'
+import { UserMessage } from '#/widgets/messages'
interface IProps {
message: Message
@@ -3,11 +3,11 @@ import { Box, Menu, MenuItem, Skeleton, Slide, Typography } from '@mui/material'
import Stack from '@mui/material/Stack'
import Image from 'next/image'
-import { ImageModal } from '@/src/features/image-modal'
-import { useAppSelector } from '@/src/main/store/store'
-import { TooltipCustom } from '@/src/shared'
-import { Message } from '@/src/shared/lib/types/model'
-import { BotMessage } from '@/src/widgets/messages/ui/bot-message'
+import { ImageModal } from '#/features/image-modal'
+import { useAppSelector } from '#/app/store/store'
+import { TooltipCustom } from '#/shared'
+import { Message } from '#/shared/lib/types/model'
+import { BotMessage } from '#/widgets/messages/ui/bot-message'
interface IMessagesList {
// messageResponse: Message[] | null
@@ -147,13 +147,9 @@ export const UserMessage = React.memo(function UserMessage({ setModal, setCurren
{
return await axios.get(API_URL + '/api/chats/links', {
@@ -8,5 +8,5 @@ export interface NavigationSearchLink {
url: string
category: string
external?: boolean
- uid?: string
+ uid?: string
}
@@ -4,32 +4,32 @@ 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-chat-links'
-export * from './use-model'
\ No newline at end of file
+export * from './use-model'
@@ -11,7 +11,7 @@ export const useNavigationSearchChatLinks = () => {
const { data } = useSession()
const fetchChatLinks = async () => {
- if(!data) return
+ if (!data) return
setChatLinks((await getModelChatLinks(data.access)).data)
}
@@ -1,17 +1,17 @@
import React, { useEffect, useMemo } from 'react'
import { Autocomplete, Box, Stack, TextField, Typography } from '@mui/material'
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 '#/shared'
+import { useAppSelector } from '#/app/store/store'
import { useRouter } from 'next/router'
-import { useAppSelector } from '@/src/main/store/store'
-import { InputStyleDark, InputStyleLight, useConcat } from '@/src/shared'
import { NavigationSearchLink } from '../api/types'
-import { staticLinks } from '../config'
-import { useNavigationSearchChatLinks, useNavigationSearchModel } from '../model'
import { useNavigationSearchMediaLinks } from '../model/use-media-links'
-import { KeyForSearch } from './key-for-search'
interface SearchProps {
device: string
@@ -28,14 +28,13 @@ export const Search = ({ device }: SearchProps) => {
const { fetchMediaLinks, visibleMediaLinks } = useNavigationSearchMediaLinks()
- const links = useConcat(
- visibleChatLinks,
- visibleMediaLinks,
- staticLinks
- )
+ 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()
@@ -1,2 +1,2 @@
export * from './config'
-export * from './ui'
\ No newline at end of file
+export * from './ui'
@@ -4,13 +4,14 @@ 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 { 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'
-import { getPaymentsPlans, payProduct } from '@/src/entities/user-account'
+import { getPaymentsPlans, payProduct } from '#/entities/user-account'
export interface IOffer {
uid: string
@@ -71,7 +72,12 @@ export const Payment: React.FC = ({ device, changeClose })
{offers?.map((offer) => {
return (
@@ -91,10 +97,19 @@ export const Payment: React.FC = ({ device, changeClose })
})}
{messages && (
-
+
История
{messages.map((el) => (
-
+
))}
@@ -146,7 +161,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)
@@ -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='По' />