Binary files a/public/svg/copy/Bold-dark.png and /dev/null differ
Binary files a/public/svg/copy/Bold.png and /dev/null differ
Binary files a/public/svg/copy/Center-dark.png and /dev/null differ
Binary files a/public/svg/copy/Center.png and /dev/null differ
Binary files a/public/svg/copy/Italic-dark.png and /dev/null differ
Binary files a/public/svg/copy/Italic.png and /dev/null differ
Binary files a/public/svg/copy/Left-dark.png and /dev/null differ
Binary files a/public/svg/copy/Left.png and /dev/null differ
Binary files a/public/svg/copy/Ordered-dark.png and /dev/null differ
Binary files a/public/svg/copy/Ordered.png and /dev/null differ
Binary files a/public/svg/copy/Redo-dark.png and /dev/null differ
Binary files a/public/svg/copy/Redo.png and /dev/null differ
Binary files a/public/svg/copy/Right-dark.png and /dev/null differ
Binary files a/public/svg/copy/Right.png and /dev/null differ
Binary files a/public/svg/copy/Underline-dark.png and /dev/null differ
Binary files a/public/svg/copy/Underline.png and /dev/null differ
Binary files a/public/svg/copy/Undo-dark.png and /dev/null differ
Binary files a/public/svg/copy/Undo.png and /dev/null differ
Binary files a/public/svg/copy/Unordered-dark.png and /dev/null differ
Binary files a/public/svg/copy/Unordered.png and /dev/null differ
@@ -1,24 +0,0 @@
-
\ No newline at end of file
Binary files a/public/logo180.png and /dev/null differ
Binary files a/public/logo192.png and /dev/null differ
Binary files a/public/logo512.png and /dev/null differ
@@ -1,19 +0,0 @@
-{
- "name": "AIR",
- "short_name": "AIR",
- "icons": [
- {
- "src": "/logo192.png",
- "sizes": "192x192",
- "type": "image/png"
- },
- {
- "src": "/logo512.png",
- "sizes": "512x512",
- "type": "image/png"
- }
- ],
- "start_url": "/",
- "display": "standalone"
- }
-
\ No newline at end of file
Binary files a/public/spin-spinning.gif and /dev/null differ
@@ -0,0 +1,15 @@
+import { Template } from '@/src/domains/copywrite/proxy/types/template'
+
+export const emptyTemplate: Template = {
+ id: 1000,
+ title: 'Пустой шаблон',
+ content: '',
+ keywords: [],
+ tov: '',
+ language: '',
+ theme: '',
+ resources_urls: [],
+ picture: '123',
+ target_audience: '',
+ description: '',
+}
@@ -0,0 +1,6 @@
+import { ContentState, EditorState } from 'draft-js'
+
+export const toEditorState = (text: string) => {
+ const newContentState = ContentState.createFromText(text)
+ return EditorState.createWithContent(newContentState)
+}
@@ -0,0 +1,13 @@
+export interface Template {
+ id: number
+ title: string
+ description: string
+ picture: string
+ theme: string
+ content: string
+ target_audience: string
+ resources_urls: string[]
+ keywords: string[]
+ tov: string
+ language: string
+}
@@ -0,0 +1,34 @@
+import axios from 'axios'
+
+import { Template } from '@/src/domains/copywrite/proxy/types/template'
+import { API_URL } from '@/src/shared/lib/constants'
+import { Message } from '@/src/shared/lib/types/model'
+
+export class CopywriteProxy {
+ token?: string
+
+ constructor(token: string | undefined) {
+ this.token = token
+ }
+
+ static async getGeneration(token?: string): Promise {
+ const { data } = await axios.get(API_URL + '/copywrite/', {
+ headers: { Authorization: `Bearer ${token}` },
+ })
+ return data
+ }
+
+ static async getTemplates(token?: string): Promise {
+ const { data } = await axios.get(API_URL + '/copywrite/templates/', {
+ headers: { Authorization: `Bearer ${token}` },
+ })
+ return data
+ }
+
+ static async createTemplates(token?: string): Promise {
+ const { data } = await axios.post(API_URL + '/copywrite/templates/', {
+ headers: { Authorization: `Bearer ${token}` },
+ })
+ return data
+ }
+}
@@ -0,0 +1,30 @@
+import React from 'react'
+import { Typography } from '@mui/material'
+
+import { Input, Slider } from '@/src/shared'
+
+import { FiltersProps } from './types'
+
+export function Filters({
+ strength,
+ setStrength,
+ upscale,
+ setUpscale,
+ negative_prompt,
+ num_inference_steps,
+ guidance_scale,
+ setGuidanceScale,
+ setNegative_prompt,
+ setSteps,
+}: FiltersProps) {
+ return (
+ <>
+
+
+
+
+ Запрос для исключения из генерации
+
+ >
+ )
+}
@@ -0,0 +1,17 @@
+import { ChangeEvent } from 'react'
+
+export interface Setting {
+ strength: number
+ upscale: number
+ negative_prompt: string
+ num_inference_steps: number
+ guidance_scale: number
+}
+
+export interface FiltersProps extends Setting {
+ setStrength: (e: Event, cur: number | number[]) => void
+ setUpscale: (e: Event, cur: number | number[]) => void
+ setGuidanceScale: (e: Event, cur: number | number[]) => void
+ setNegative_prompt: (e: ChangeEvent) => void
+ setSteps: (e: Event, cur: number | number[]) => void
+}
@@ -0,0 +1,36 @@
+import React from 'react'
+import { Stack, Typography } from '@mui/material'
+
+import { Input, Slider } from '@/src/shared'
+import { SelectUI } from '@/src/shared/ui/select'
+
+import { Filters } from './types'
+
+const sizes = [128, 256, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024]
+
+export function EpicPhotoFilters({
+ guidance_scale,
+ height,
+ negative_prompt,
+ num_inference_steps,
+ num_outputs,
+ setGuidance_scale,
+ setHeight,
+ setNegative_prompt,
+ setNum_inference_steps,
+ setNum_outputs,
+ setWidth,
+ width,
+}: Filters) {
+ return (
+ <>
+
+
+
+
+
+ Запрос для исключения из генерации
+
+ >
+ )
+}
@@ -0,0 +1,2 @@
+export * from './epic-photo-filters'
+export * from './types'
@@ -0,0 +1,20 @@
+import { ChangeEvent, ChangeEventHandler } from 'react'
+import { SelectChangeEvent } from '@mui/material'
+
+export interface Setting {
+ num_outputs: number
+ negative_prompt: string
+ width: number
+ height: number
+ num_inference_steps: number
+ guidance_scale: number
+}
+
+export interface Filters extends Setting {
+ setWidth: (e: SelectChangeEvent) => void
+ setHeight: (e: SelectChangeEvent) => void
+ setNum_outputs: (e: Event, cur: number | number[]) => void
+ setNum_inference_steps: (e: Event, cur: number | number[]) => void
+ setGuidance_scale: (e: Event, cur: number | number[]) => void
+ setNegative_prompt: (e: ChangeEvent) => void
+}
@@ -0,0 +1,2 @@
+export * from './kandinsky-filters'
+export * from './types'
@@ -0,0 +1,76 @@
+import React from 'react'
+import { Box, Typography } from '@mui/material'
+
+import { Input, Slider, SwitchCustom } from '@/src/shared'
+import { SelectUI } from '@/src/shared/ui/select'
+
+import { Filters } from './types'
+
+export function KandinskyFilters({
+ height,
+ isTranslate,
+ negativePrompt,
+ num_outputs,
+ setHeight,
+ setNegative_prompt,
+ setNumber,
+ setSteps,
+ setWidth,
+ steps,
+ width,
+ setIsTranslate,
+}: Filters) {
+ return (
+ <>
+ Настройки
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Переводить запрос
+
+
+
+
+
+
+ Запрос для исключения из генерации
+
+
+
+ >
+ )
+}
@@ -0,0 +1,20 @@
+import { ChangeEvent } from 'react'
+import { SelectChangeEvent } from '@mui/material'
+
+export interface Setting {
+ steps: number
+ num_outputs: number
+ width: number
+ height: number
+ isTranslate: boolean
+ negativePrompt: string
+}
+
+export interface Filters extends Setting {
+ setWidth: (e: SelectChangeEvent) => void
+ setHeight: (e: SelectChangeEvent) => void
+ setSteps: (e: Event, cur: number | number[]) => void
+ setNumber: (e: Event, cur: number | number[]) => void
+ setNegative_prompt: (e: ChangeEvent) => void
+ setIsTranslate: () => void
+}
@@ -0,0 +1,33 @@
+import React from 'react'
+import { Typography } from '@mui/material'
+
+import { Input, Slider } from '@/src/shared'
+import { SelectUI } from '@/src/shared/ui/select'
+
+import { FiltersProps } from './types'
+
+const sizes = [384, 512, 576, 640, 704, 768]
+
+export function Filters({
+ height,
+ negative_prompt,
+ num_inference_steps,
+ num_outputs,
+ setHeight,
+ setNegative_prompt,
+ setNumOutputs,
+ setSteps,
+ setWidth,
+ width,
+}: FiltersProps) {
+ return (
+ <>
+
+
+
+
+ Запрос для исключения из генерации
+
+ >
+ )
+}
@@ -0,0 +1,2 @@
+export * from './filters'
+export * from './types'
@@ -0,0 +1,18 @@
+import { ChangeEvent } from 'react'
+import { SelectChangeEvent } from '@mui/material'
+
+export interface Setting {
+ width: number
+ height: number
+ num_outputs: number
+ negative_prompt: string
+ num_inference_steps: number
+}
+
+export interface FiltersProps extends Setting {
+ setWidth: (e: SelectChangeEvent) => void
+ setHeight: (e: SelectChangeEvent) => void
+ setNumOutputs: (e: Event, cur: number | number[]) => void
+ setSteps: (e: Event, cur: number | number[]) => void
+ setNegative_prompt: (e: ChangeEvent) => void
+}
@@ -92,14 +92,11 @@ const initialState: UserState & ResponseAllInfo = {
export const getAll = async (token: string | null | undefined): Promise => {
try {
- const { data } = await axios.get>(
- API_URL + '/auth/me',
- {
- headers: {
- Authorization: `Bearer ${token}`,
- },
- }
- )
+ const { data } = await axios.get>(API_URL + '/auth/me', {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ })
return data
} catch (err) {
@@ -107,23 +104,13 @@ export const getAll = async (token: string | null | undefined): Promise {
- return await getAll(token)
- }
-)
+export const getAllInfo = createAsyncThunk('user/getAllInfo', async (token: string | null | undefined) => {
+ return await getAll(token)
+})
-export const unfollowEmail = createAsyncThunk(
- 'user/unfollowEmail',
- async (token: string | null | undefined) => {
- await axios.patch(
- API_URL + '/auth/email-sub',
- {},
- { headers: { Authorization: `Bearer ${token}` } }
- )
- }
-)
+export const unfollowEmail = createAsyncThunk('user/unfollowEmail', async (token: string | null | undefined) => {
+ await axios.patch(API_URL + '/auth/email-sub', {}, { headers: { Authorization: `Bearer ${token}` } })
+})
export const userSlice = createSlice({
name: 'userSlice',
@@ -0,0 +1,12 @@
+export const costModel: any = {
+ 'gpt-3.5-turbo': 0.0017,
+ 'gpt-3.5-turbo-16k': 0.00255,
+ 'text-davinci-003': 0.017,
+ 'text-curie-001': 0.0017,
+ 'text-babbage-001': 0.000425,
+ 'text-ada-001': 0.000034,
+ 'gpt-4': 0.01785,
+ 'gpt-4-32k': 0.0255,
+}
+
+export const textTooltipCalculating = 'Столько токенов спишется за ваш текущий запрос.'
@@ -0,0 +1,8 @@
+const price = {
+ '1024x1024': 8.5,
+ '512x512': 7.65,
+ '256x256': 6.8,
+}
+export const calculatingDalle = (count: number, quality: '1024x1024' | '512x512' | '256x256') => {
+ return price[quality] * count
+}
@@ -0,0 +1,59 @@
+import React from 'react'
+import { encoding_for_model } from '@dqbd/tiktoken'
+
+import { costModel } from '@/src/features/calculation-tokens-gpt/lib/constants'
+import { calculatingDalle } from '@/src/features/calculation-tokens-gpt/model/calculating-dalle'
+import { ImessageContext } from '@/src/shared/lib/types/types-gpt'
+import { TypeModelGPT, typeModels } from '@/src/widgets/filters-gpt/lib/constants'
+
+const getFullModelTypeName = (name: string): TypeModelGPT => {
+ return typeModels.filter((el) => el.key === name)[0].value as TypeModelGPT
+}
+
+const getTransformPrice = (price: number, isGpt: boolean = false) => {
+ if (price === 0) {
+ return '0'
+ }
+
+ return price < 1 ? ' < 1' : `${isGpt ? '≈' : ''} ${price.toFixed(2).replace('.', ',')}`
+}
+
+const checkIsAdditional = (model: string, isAdditional?: boolean): any => {
+ if (model === 'gpt-3.5-turbo') {
+ return isAdditional ? 'gpt-3.5-turbo-16k' : model
+ }
+
+ if (model === 'gpt-4') {
+ return isAdditional ? 'gpt-4-32k' : model
+ }
+
+ return model
+}
+export const useCalculating = (
+ model: 'gpt' | 'dalle' | 'sd',
+ count?: number,
+ quality?: any,
+ prompt?: string,
+ gptType?: TypeModelGPT,
+ isAdditionalCtx?: boolean,
+ context?: { message: string; uid: string }[]
+): string => {
+ if (model === 'dalle') {
+ return getTransformPrice(calculatingDalle(count as number, quality))
+ }
+
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ const modelFullName = React.useMemo(() => getFullModelTypeName(gptType as TypeModelGPT), [gptType])
+
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ const encoding = React.useMemo(() => encoding_for_model(modelFullName), [gptType])
+
+ const tokens =
+ context?.length === 0
+ ? encoding.encode(prompt as string).length
+ : encoding.encode((prompt as string) + context?.map((el) => el.message).toString()).length
+
+ const price = prompt ? costModel[checkIsAdditional(modelFullName, isAdditionalCtx)] * tokens + 0.1 : 0
+
+ return getTransformPrice(price, true)
+}
@@ -0,0 +1,89 @@
+import React, { memo } from 'react'
+import { Box, Tooltip } from '@mui/material'
+import Typography from '@mui/material/Typography'
+import Image from 'next/image'
+
+import { useCalculating } from '@/src/features/calculation-tokens-gpt/model/use-calculating'
+import TooltipCalculating from '@/src/features/calculation-tokens-gpt/ui/tooltip-calculating'
+import { useAppSelector } from '@/src/main/store/store'
+import { baseColor } from '@/src/shared/lib/constants/colors'
+import { ImessageContext } from '@/src/shared/lib/types/types-gpt'
+import { TypeModelGPT } from '@/src/widgets/filters-gpt/lib/constants'
+
+interface ICalculationTokenProps {
+ model: 'gpt' | 'sd' | 'dalle'
+ quality?: string
+ count?: number
+ prompt?: string
+ isAdditional?: boolean
+ gptType?: TypeModelGPT
+ context?: { message: string; uid: string }[]
+}
+
+export const Calculation: React.FC = memo(({ prompt, gptType, context, isAdditional, count, quality, model }) => {
+ const price = useCalculating(model, count, quality, prompt, gptType, isAdditional, context)
+
+ const theme = useAppSelector((state) => state.theme.theme)
+
+ return (
+ }
+ componentsProps={{
+ tooltip: {
+ sx: {
+ '&.MuiTooltip-tooltip': {
+ '&.MuiTooltip-tooltipPlacementBottom': {
+ marginTop: '2px',
+ },
+ '&.MuiTooltip-tooltipPlacementTop': {
+ marginBottom: '7px',
+ },
+ '&.MuiTooltip-tooltipPlacementLeft': {
+ marginRight: '24px',
+ },
+ },
+ bgcolor: theme === 'light' ? 'white' : '#4B4B4B',
+ borderRadius: '10px',
+ '& .MuiTooltip-arrow': {
+ color: theme === 'light' ? 'white' : '#4B4B4B',
+ },
+ boxShadow: '0px 0px 4px rgba(0, 0, 0, 0.04), 0px 4px 32px rgba(0, 0, 0, 0.16)',
+ },
+ },
+ }}
+ arrow
+ >
+
+
+
+ {price}
+
+
+
+ )
+})
+
+Calculation.displayName = 'Calculation'
@@ -0,0 +1,39 @@
+import React from 'react'
+import { Box } from '@mui/material'
+import Typography from '@mui/material/Typography'
+
+import { textTooltipCalculating } from '@/src/features/calculation-tokens-gpt/lib/constants'
+import { useAppSelector } from '@/src/main/store/store'
+
+const TooltipCalculating = ({ model = 'dalle' }: { model?: 'gpt' | 'dalle' | 'sd' }) => {
+ const theme = useAppSelector((state) => state.theme.theme)
+
+ return (
+
+
+ {textTooltipCalculating}
+
+
+ {model === 'gpt' && (
+
+ Фактическое значение может немного отличаться
+
+ )}
+
+ )
+}
+
+export default TooltipCalculating
@@ -0,0 +1 @@
+export { Calculation } from './ui/calculation'
@@ -37,7 +37,7 @@ export function useChats(model: string): ChatsReturn {
const { data } = useSession()
useEffect(() => {
- ;[][1]
+ [][1]
if (model && data?.access) {
getAllChats(model, data?.access).then((res) => {
setChats(res)
@@ -8,7 +8,6 @@ interface IProps {
setModal: Dispatch>
image: string
}
-
export default function FullScreenModal({ modal, setModal, image }: IProps) {
const isSvg = image.includes('.svg')
@@ -1,6 +1,6 @@
.close_block{
position: absolute;
- z-index: 110;
+ z-index: 105;
cursor: pointer;
right: 25px;
top: 25px;
@@ -1,5 +1,5 @@
import React from 'react'
-import { Avatar, Box, Typography } from '@mui/material'
+import { Box, Typography } from '@mui/material'
import Link from 'next/link'
import styles from '@/src/shared/styles/chats-bot-pages.module.scss'
@@ -10,16 +10,11 @@ export default function Title(props: any) {
{' '}
- {props.linkBack && props.linkBack !== '' ? (
- {props.type}
- ) : (
- {props.type}
- )} •{' '}
+ {props.type} •{' '}
- {props.title}
+ {props.title}
- {props.icon && }
{props.title}
@@ -56,3 +56,10 @@ export const options: Options = {
doneLabel: 'Готово',
disableInteraction: true,
}
+
+export const responseGPT =
+ 'Для нахождения минимального элемента в массиве предлагаю написать собственную функцию с использованием функции высшего порядка reduce и стандартного метода Math.min():\n' +
+ '\n' +
+ 'const numbers = [-94, 87, 12, 0, -67, 32];\n' +
+ 'const min = (values) => values.reduce((x, y) => Math.min(x, y));\n' +
+ 'console.log(min(numbers)); // => -94\n'
@@ -0,0 +1,44 @@
+import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
+
+import { CopywriteProxy } from '@/src/domains/copywrite/proxy/copywrite-proxy'
+import { Template } from '@/src/domains/copywrite/proxy/types/template'
+import { Message } from '@/src/shared/lib/types/model'
+
+export interface Theme {
+ templates: Template[] | null
+ generation: Message[] | null
+}
+
+const initialState: Theme = {
+ templates: null,
+ generation: null,
+}
+
+export const loadTemplates = createAsyncThunk('copywrite/loadTemplates', async (token?: string): Promise => {
+ return await CopywriteProxy.getTemplates(token)
+})
+
+export const loadGeneration = createAsyncThunk('copywrite/loadGeneration', async (token?: string): Promise => {
+ return await CopywriteProxy.getGeneration(token)
+})
+
+export const copySlice = createSlice({
+ name: 'copySlice',
+ initialState,
+ reducers: {
+ loadTemplates: (state, action) => {},
+ },
+ extraReducers: (builder) => {
+ builder
+ .addCase(loadTemplates.fulfilled, (state, action) => {
+ state.templates = action.payload
+ })
+ .addCase(loadGeneration.fulfilled, (state, action) => {
+ state.generation = action.payload
+ })
+ },
+})
+
+export const {} = copySlice.actions
+
+export default copySlice.reducer
@@ -1,98 +0,0 @@
-import { createSlice } from '@reduxjs/toolkit'
-import { EditorState } from 'draft-js'
-
-import { CopywriteDefaultVariables, CopywriteOverrideVariables } from '@/src/widgets/copy/api/models'
-import { getHtmlText } from '@/src/widgets/copy/lib/getEditorHtml'
-
-export interface Theme {
- output_content: string | null
- input_content: string
- variables: { [p: string]: string | null }[]
- defaultVariables: CopywriteDefaultVariables[] | []
- overridenVariables: CopywriteOverrideVariables[] | []
-}
-
-const initialState: Theme = {
- output_content: null,
- input_content: '',
- variables: [],
- defaultVariables: [],
- overridenVariables: [],
-}
-
-export const copyStore = createSlice({
- name: 'copyStore',
- initialState,
- reducers: {
- // OUTPUT CONTENT
- setNewOutputContent: (state, action: { payload: string }) => {
- state.output_content = action.payload
- },
- addOutputContent: (state, action: { payload: string }) => {
- state.output_content += action.payload
- },
-
- // INPUT CONTENT
- setTextInputContent: (state, action: { payload: string }) => {
- state.input_content = action.payload
- },
- setEditorInputContent: (state, action: { payload: EditorState | undefined }) => {
- if (action.payload !== undefined) state.output_content = getHtmlText(action.payload)
- },
-
- // VARIABLES
- setAllVariables: (state, action: { payload: { [p: string]: string | null }[] }) => {
- state.variables = action.payload
- },
- updateVariable: (state, action: { payload: { id: string; value: string | null } }) => {
- state.variables = state.variables.map((el) => {
- if (el.id === action.payload.id) {
- el.value = action.payload.value
- }
- return el
- })
- },
- createVariables: (state) => {},
-
- // DEFAULT VARIABLES
- setDefaultVariables: (state, action: { payload: CopywriteDefaultVariables[] }) => {
- state.defaultVariables = action.payload
- },
- updateDefaultVariables: (state, action: { payload: { action: 'add' | 'remove'; variable: CopywriteDefaultVariables } }) => {
- if (action.payload.action === 'add') {
- state.defaultVariables = [...state.defaultVariables, action.payload.variable]
- }
- if (action.payload.action === 'remove') {
- state.defaultVariables = state.defaultVariables.filter((el) => el.id !== action.payload.variable.id)
- }
- },
-
- // OVERRIDE VARIABLES
- setOverrideVariables: (state, action: { payload: CopywriteOverrideVariables[] }) => {
- state.overridenVariables = action.payload
- },
- updateOverrideVariables: (state, action: { payload: { action: 'add' | 'remove'; variable: CopywriteOverrideVariables } }) => {
- if (action.payload.action === 'add') {
- state.overridenVariables = [...state.overridenVariables, action.payload.variable]
- }
- if (action.payload.action === 'remove') {
- state.overridenVariables = state.overridenVariables.filter((el) => el.variable !== action.payload.variable.id)
- }
- },
- },
-})
-
-export const {
- setNewOutputContent,
- addOutputContent,
- setTextInputContent,
- setEditorInputContent,
- updateVariable,
- setAllVariables,
- updateDefaultVariables,
- setDefaultVariables,
- setOverrideVariables,
- updateOverrideVariables,
-} = copyStore.actions
-
-export default copyStore.reducer
@@ -0,0 +1,72 @@
+import { Dispatch, SetStateAction, useEffect, useMemo, useState } from 'react'
+import { useRouter } from 'next/router'
+import { useSession } from 'next-auth/react'
+
+import { emptyTemplate } from '@/src/domains/copywrite/lib/constants'
+import { Template } from '@/src/domains/copywrite/proxy/types/template'
+import { loadGeneration, loadTemplates } from '@/src/features/use-copy/copy-slice'
+import { useAppDispatch, useAppSelector } from '@/src/main/store/store'
+import { Message } from '@/src/shared/lib/types/model'
+
+interface UseCopy {
+ currentTemplate: Template | null
+ generations: Message[] | null
+ pickGeneration: Message | null
+ setPickGeneration: Dispatch>
+ createEmpty: () => void
+}
+
+export const useCopy = (): UseCopy => {
+ const [pickGeneration, setPickGeneration] = useState(null)
+
+ const { data } = useSession()
+
+ const { query, push, pathname } = useRouter()
+
+ const templates = useAppSelector((state) => state.copy.templates)
+
+ const generations = useAppSelector((state) => state.copy.generation)
+
+ const dispatch = useAppDispatch()
+
+ const getId = () => {
+ const id = query['id']
+
+ if (id) {
+ return Number(id)
+ }
+ }
+
+ const createEmpty = () => {
+ setPickGeneration({
+ content: '',
+ uid: '123',
+ created_at: '123',
+ file: null,
+ info: null,
+ from_model: false,
+ elapsed_time: '12',
+ is_favourite: false,
+ is_sent: false,
+ })
+ }
+
+ useEffect(() => {
+ if (data?.access) {
+ dispatch(loadTemplates(data.access))
+ dispatch(loadGeneration(data.access))
+ }
+ }, [data?.access])
+
+ const currentTemplate = useMemo(() => {
+ const id = getId()
+ const foundTemplate = templates?.find((el) => el.id === id)
+ if (foundTemplate) {
+ return foundTemplate
+ }
+
+ return emptyTemplate
+ }, [templates])
+
+ return { currentTemplate, generations, pickGeneration, setPickGeneration, createEmpty }
+}
@@ -0,0 +1,166 @@
+import { Dispatch, SetStateAction, useEffect, useState } from 'react'
+import axios, { AxiosError, AxiosResponse } from 'axios'
+import { ContentState, EditorState } from 'draft-js'
+import { useSession } from 'next-auth/react'
+
+import { Template } from '@/src/domains/copywrite/proxy/types/template'
+import { loadGeneration } from '@/src/features/use-copy/copy-slice'
+import { useAppDispatch } from '@/src/main/store/store'
+import { useShowData } from '@/src/shared'
+import { API_URL } from '@/src/shared/lib/constants'
+import { Message, MessageSend } from '@/src/shared/lib/types/model'
+
+type Languages = 'ru' | 'en' | 'it' | 'fr'
+type LanguagesText = 'Русский' | 'Английский' | 'Итальянский' | 'Французский'
+
+export const langs: Record = {
+ Русский: 'ru',
+ Английский: 'en',
+ Итальянский: 'it',
+ Французский: 'fr',
+}
+
+export const languages = { ...langs, Немецкий: 'de' }
+export const target_audiences = ['Вся', '18+', '21+', '30+', '14-20', '35-40']
+export const tovs = ['Нейтральный', 'Спокойный', 'Агрессивный', 'Серьезный', 'Провокационный', 'Остроумный', 'Наставнический', 'Дружелюбный']
+
+type Setting = Pick
+
+type UseTemplate = {
+ text: EditorState
+ isLoading: boolean
+
+ lang: string
+ targetAudiences: string
+ tov: string
+ theme: string
+ content: string
+ keywords: string[]
+ resource_urls: string[]
+
+ setLang: Dispatch>
+ setTargetAudiences: Dispatch>
+ setTov: Dispatch>
+ setTheme: Dispatch>
+ setContent: Dispatch>
+ setKeywords: Dispatch>
+ setResourceUrls: Dispatch>
+
+ clearSetting: () => void
+ createText: () => void
+ onEditorChange: (a: any) => void
+}
+
+export const useTemplate = (currentTemplate: Template | null): UseTemplate => {
+ const [text, setText] = useState(EditorState.createEmpty())
+
+ const onEditorChange = (editorState: any) => {
+ setText(editorState)
+ }
+
+ const [isLoading, setIsLoading] = useState(false)
+
+ const dispatch = useAppDispatch()
+
+ const { showError } = useShowData()
+
+ const { data: session } = useSession()
+
+ const [lang, setLang] = useState(() => {
+ const a = Object.entries(languages)
+
+ const b = a.find(([key, value]) => value === currentTemplate?.language)
+
+ if (b) {
+ return b[0]
+ } else {
+ return a[0][0]
+ }
+ })
+
+ const [targetAudiences, setTargetAudiences] = useState(currentTemplate?.target_audience || target_audiences[0])
+
+ const [tov, setTov] = useState(currentTemplate?.tov || tovs[0])
+
+ const [theme, setTheme] = useState(currentTemplate?.theme || '')
+
+ const [content, setContent] = useState(currentTemplate?.content || '')
+
+ const [keywords, setKeywords] = useState(currentTemplate?.keywords || [])
+
+ const [resource_urls, setResourceUrls] = useState(currentTemplate?.resources_urls || [])
+
+ const clearSetting = () => {
+ setLang('Русский')
+ setTargetAudiences(currentTemplate?.target_audience || target_audiences[0])
+ setTov(currentTemplate?.tov || tovs[0])
+ setTheme(currentTemplate?.theme || '')
+ setKeywords(currentTemplate?.keywords || [])
+ setResourceUrls(currentTemplate?.resources_urls || [])
+ }
+
+ const createText = async () => {
+ const dataForSend: MessageSend = {
+ content: content,
+ file: null,
+ info: {
+ keywords,
+ language: Object.entries(languages).find(([key, value]) => key === lang)![1],
+ tov,
+ resources_urls: resource_urls,
+ target_audience: targetAudiences,
+ theme: theme,
+ },
+ }
+
+ if (!session?.access) {
+ showError('У вас неактивный токен, попробуйте перезайти в аккаунт', true)
+ return
+ }
+
+ try {
+ setIsLoading(true)
+ const { data } = await axios.post>(API_URL + '/copywrite/', dataForSend, {
+ withCredentials: true,
+ headers: {
+ Authorization: `Bearer ${session?.access}`,
+ },
+ })
+ setIsLoading(false)
+
+ const newContentState = ContentState.createFromText(data[0].content)
+
+ setText(EditorState.createWithContent(newContentState))
+ dispatch(loadGeneration(session?.access))
+ } catch (err: any) {
+ setIsLoading(false)
+ return {
+ error: true,
+ message: 'Произошла ошибка при выполнении запроса',
+ details: err as AxiosError,
+ }
+ }
+ }
+
+ return {
+ tov,
+ setTov,
+ lang,
+ setLang,
+ clearSetting,
+ createText,
+ isLoading,
+ keywords,
+ setKeywords,
+ setResourceUrls,
+ resource_urls,
+ setTargetAudiences,
+ targetAudiences,
+ setTheme,
+ text,
+ onEditorChange,
+ theme,
+ setContent,
+ content,
+ }
+}
@@ -4,7 +4,7 @@ import Switch from '@mui/material/Switch'
import { setParams } from '@/src/main/store/model-parametres-store'
import { useAppDispatch } from '@/src/main/store/store'
-import TooltipModelTypes from '@/src/shared/ui/tooltip-model-types'
+import TooltipModelTypes from '@/src/widgets/filters-gpt/ui/tooltip-model-types'
interface IProps {
name: string
@@ -8,7 +8,7 @@ import { setParams } from '@/src/main/store/model-parametres-store'
import { useAppDispatch } from '@/src/main/store/store'
import { InputStyleDark, InputStyleLight } from '@/src/shared'
import { useThemeAndDevice } from '@/src/shared/lib/hooks'
-import TooltipModelTypes from '@/src/shared/ui/tooltip-model-types'
+import TooltipModelTypes from '@/src/widgets/filters-gpt/ui/tooltip-model-types'
interface IProps {
title: string
@@ -21,7 +21,7 @@ interface IProps {
setNewParam: (payload: { [p: string]: string | number | number[] | boolean }) => void
}
-export const InputFilter = ({ filters, item_key, values, title, description = '', setNewParam }: IProps) => {
+export const InputFilter = ({ filters, item_key, values, title, description, setNewParam }: IProps) => {
const { theme } = useThemeAndDevice()
const [value, setValue] = React.useState(values?.default || '')
@@ -5,7 +5,7 @@ import { MenuItem, Select, SelectChangeEvent, Stack, Typography } from '@mui/mat
import { setParams } from '@/src/main/store/model-parametres-store'
import { useAppDispatch, useAppSelector } from '@/src/main/store/store'
import { baseColor } from '@/src/shared/lib/constants/colors'
-import TooltipModelTypes from '@/src/shared/ui/tooltip-model-types'
+import TooltipModelTypes from '@/src/widgets/filters-gpt/ui/tooltip-model-types'
interface IProps {
selects: { availables: string[]; default: any; end: number; start: number; step: number }
@@ -3,7 +3,7 @@ import * as React from 'react'
import { setParams } from '@/src/main/store/model-parametres-store'
import { useAppDispatch } from '@/src/main/store/store'
import { Slider as Sl } from '@/src/shared'
-import TooltipModelTypes from '@/src/shared/ui/tooltip-model-types'
+import TooltipModelTypes from '@/src/widgets/filters-gpt/ui/tooltip-model-types'
interface IProps {
title: string
@@ -15,6 +15,10 @@ export type CardProps = {
}
const ChatCard = ({ text, icon, title, uid, slug, accessed_models }: CardProps) => {
+ useEffect(() => {
+ console.log(accessed_models)
+ }, [accessed_models])
+
return (
@@ -5,7 +5,7 @@ import { MenuItem, Select, SelectChangeEvent, Stack, Typography } from '@mui/mat
import { useAppSelector } from '@/src/main/store/store'
import { IModelVersions } from '@/src/shared/api/models/models'
import { baseColor } from '@/src/shared/lib/constants/colors'
-import TooltipModelTypes from '@/src/shared/ui/tooltip-model-types'
+import TooltipModelTypes from '@/src/widgets/filters-gpt/ui/tooltip-model-types'
interface ISelect {
value: string
@@ -86,7 +86,6 @@ function Chat({
modelType={modelType}
deleteMessage={deleteMessage}
modelTitle={modelTitle}
- loading={loading}
/>
(toShort: T, lang: LangParam): LangRet
return arrLang.find(([_, value]) => lang === value)![0] as LangReturn
}
+function KeyForSearch(props: any) {
+ if (props.text === null) {
+ return null
+ }
+
+ const checkType = () => {
+ if (props.text.includes('Windows')) {
+ return 'Ctrl + F'
+ } else {
+ return '⌥+F'
+ }
+ }
+
+ return (
+
+ {checkType()}
+
+ )
+}
+
const InfoBar: React.FC = ({ title, device }) => {
const theme = useAppSelector((state) => state.theme.theme)
@@ -64,6 +83,8 @@ const InfoBar: React.FC = ({ title, device }) => {
const show_balance = useAppSelector((state) => state.user.show_balance)
+ const desktop = device === 'desktop'
+
const { pathname, replace } = useRouter()
const { data } = useSession()
@@ -75,9 +96,7 @@ const InfoBar: React.FC = ({ title, device }) => {
await i18n.changeLanguage(newLang)
}
- const { email, first_name, last_name, profile_picture_link, account_type } = useAppSelector(
- (state) => state.user
- )
+ const { email, first_name, last_name, profile_picture_link, account_type } = useAppSelector((state) => state.user)
const dispatch = useAppDispatch()
@@ -91,6 +110,37 @@ const InfoBar: React.FC = ({ title, device }) => {
getModels(data?.access).then((res) => setModels(res))
}, [data?.access])
+ const filtersFn = () => {
+ if (!search.trim()) {
+ return models
+ }
+
+ return models.filter((el) => el.title.toLowerCase().includes(search.toLowerCase()))
+ }
+
+ const searchRef = useRef(null)
+ const searchRef2 = useRef(null)
+ const autocompleteRef = useRef(null)
+
+ useEffect(() => {
+ document.addEventListener('keydown', ctrlF, false)
+ return () => {
+ document.removeEventListener('keydown', ctrlF, false)
+ }
+ //@ts-ignore
+ }, [ctrlF])
+
+ const ctrlF = useCallback((e: any) => {
+ if ((e.key === 'f' || e.key === 'F') && (e.ctrlKey || e.metaKey)) {
+ e.preventDefault()
+ //@ts-ignore
+ searchRef.current!.focus()
+ setSearchOpen(true)
+ }
+ }, [])
+
+ const { push } = useRouter()
+
const [anchorEl, setAnchorEl] = React.useState(null)
const [anchorEl2, setAnchorEl2] = React.useState(null)
@@ -119,7 +169,60 @@ const InfoBar: React.FC = ({ title, device }) => {
return (
-
+
+ setSearchOpen(true)}
+ onClose={() => setSearchOpen(false)}
+ //@ts-ignore
+ getOptionLabel={(label: Model) => label.title}
+ onChange={(event, value) => {
+ if (value) {
+ //@ts-ignore
+ push(`chat-bots/${value.slug}`)
+ }
+ }}
+ renderInput={(params) => (
+ setSearch(e.target.value)}
+ placeholder='Поиск по платформе'
+ InputProps={{
+ ...params.InputProps,
+ startAdornment: (
+
+ ),
+ endAdornment: ,
+ }}
+ />
+ )}
+ />
+
+
= ({ title, device }) => {
>
- Мы уже работаем над этой проблемой. Попробуйте перезайти в
- аккаунт
+ Мы уже работаем над этой проблемой. Попробуйте перезайти в аккаунт
-
@@ -196,10 +294,7 @@ const InfoBar: React.FC = ({ title, device }) => {
{show_balance && (
-
+
{declineToken(balance.toString())}
@@ -213,13 +308,7 @@ const InfoBar: React.FC = ({ title, device }) => {
handleClick(e)
}
src={profile_picture_link as string}
- sx={{
- width: 40,
- height: 40,
- bgcolor: '#8280FF',
- marginLeft: '10px',
- cursor: 'pointer',
- }}
+ sx={{ width: 40, height: 40, bgcolor: '#8280FF', marginLeft: '10px', cursor: 'pointer' }}
>
{email[0] || 'N'}
@@ -227,8 +316,7 @@ const InfoBar: React.FC = ({ title, device }) => {
sx={{ marginTop: '6px' }}
PaperProps={{
style: {
- backgroundColor:
- theme === 'dark' ? '#151518' : 'white',
+ backgroundColor: theme === 'dark' ? '#151518' : 'white',
borderRadius: '13px',
boxShadow: 'none',
},
@@ -248,22 +336,9 @@ const InfoBar: React.FC = ({ title, device }) => {
>
-
- router.push('/account?scope=setting')
- }
- >
-
-
+ router.push('/account?scope=setting')}>
+
+
{' '}
Настройки{' '}
@@ -271,26 +346,9 @@ const InfoBar: React.FC = ({ title, device }) => {
-
- router.push(
- '/account?scope=business'
- )
- }
- >
-
-
+ router.push('/account?scope=business')}>
+
+
{' '}
Компаниям{' '}
@@ -301,26 +359,9 @@ const InfoBar: React.FC = ({ title, device }) => {
{account_type === 'regular' && (
-
- router.push(
- '/account?scope=referral'
- )
- }
- >
-
-
+ router.push('/account?scope=referral')}>
+
+
{' '}
Рефералам{' '}
@@ -331,45 +372,18 @@ const InfoBar: React.FC = ({ title, device }) => {
-
- router.push(
- '/account?scope=subscribe'
- )
- }
- >
-
-
+ router.push('/account?scope=subscribe')}>
+
+
{' '}
Оплата{' '}
- signOut()}
- sx={{ marginTop: '15px', cursor: 'pointer' }}
- >
-
-
+ signOut()} sx={{ marginTop: '15px', cursor: 'pointer' }}>
+
+
Выйти
@@ -29,14 +29,7 @@ interface Props {
isLoader?: boolean
}
-export const Layout: React.FC = ({
- children,
- device,
- isAuthPage = false,
- titlePage,
- title = titlePage,
- isLoader,
-}) => {
+export const Layout: React.FC = ({ children, device, isAuthPage = false, titlePage, title = titlePage, isLoader }) => {
const { data: sessionData } = useSession()
const appState = useAppSelector((state) => state)
const dispatch = useAppDispatch()
@@ -44,7 +37,6 @@ export const Layout: React.FC = ({
const desktop = device === 'desktop'
const [sidemenuDefaultOpen, setSidemenuDefaultOpen] = useState(true)
- const [readyToDisplay, setReadyToDisplay] = useState(false)
useTheme()
@@ -67,7 +59,6 @@ export const Layout: React.FC = ({
if ((sessionData && !sessionStorage.getItem('firstRender')) || (sessionData && !localStorage.getItem('global_settings'))) {
dispatch(getUserAccountSettings(sessionData.access))
sessionStorage.setItem('firstRender', 'true')
- setReadyToDisplay(true)
}
}, [sessionData])
@@ -75,7 +66,6 @@ export const Layout: React.FC = ({
const lsData = localStorage.getItem('global_settings')
if (lsData !== null) {
dispatch(setSettings(JSON.parse(lsData)))
- setReadyToDisplay(true)
}
window.addEventListener('beforeunload', () => {
@@ -86,27 +76,14 @@ export const Layout: React.FC = ({
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)
+ 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 (
-
+
)
@@ -119,8 +96,6 @@ export const Layout: React.FC = ({
-
-
= ({
padding: isAuthPage ? '0px' : desktop ? '0px' : '10px',
}}
>
- {readyToDisplay && (
-
-
- {!isAuthPage ? (
- desktop ? (
-
-
-
-
-
- {children}
-
+
+
+ {!isAuthPage ? (
+ desktop ? (
+
+
+
+
+
+ {children}
- ) : (
-
-
- {children}
-
- )
+
) : (
- <>{children}>
- )}
-
-
- )}
+
+
+ {children}
+
+ )
+ ) : (
+ <>{children}>
+ )}
+
+
>
)
@@ -6,7 +6,7 @@ import { themeSlice } from '@/src/entities/theme'
import { userSlice } from '@/src/entities/user-account'
import { settingsSlice } from '@/src/entities/user-account/model/settings'
import { stepperSlice } from '@/src/features/register-business'
-import { copyStore } from '@/src/features/use-copy/copy-store'
+import { copySlice } from '@/src/features/use-copy/copy-slice'
import { paramsStore } from '@/src/main/store/model-parametres-store'
import { notificationSlice } from './notification-slice'
@@ -17,7 +17,7 @@ export const store = configureStore({
balance: balanceSlice.reducer,
stepper: stepperSlice.reducer,
user: userSlice.reducer,
- copy: copyStore.reducer,
+ copy: copySlice.reducer,
notification: notificationSlice.reducer,
params: paramsStore.reducer,
settings: settingsSlice.reducer,
@@ -1,19 +1,19 @@
:root[data-theme='light'] {
- --air-color: #8280ff;
- --background-color-main: #ffffff;
- --background-color-additional: #ffffff;
- --background-color-page: #fbfbfb;
- --background-color-table: white;
- --bg-color-button-gray: #e8e8e8;
- --color-btn-gray: #5a5a5a;
- --search-bg: white;
- --text-color-purple: #7f7df3;
- --text-color-main: #373737;
- --text-color-additional-one: #868686;
- --text-color-additional-two: #5e5e5e;
- --border-color: #f5f5f5;
- --border-color2: #e7e7e7;
- --bg-audio: #f2f2fe;
+ --air-color: #8280FF;
+ --background-color-main: #ffffff;
+ --background-color-additional: #ffffff;
+ --background-color-page: #fbfbfb;
+ --background-color-table: white;
+ --bg-color-button-gray: #e8e8e8;
+ --color-btn-gray: #5a5a5a;
+ --search-bg: white;
+ --text-color-purple: #7f7df3;
+ --text-color-main: #373737;
+ --text-color-additional-one: #868686;
+ --text-color-additional-two: #5e5e5e;
+ --border-color: #f5f5f5;
+ --border-color2: #e7e7e7;
+ --bg-audio: #f2f2fe;
--new-ui-bg-app-color: #eff0f2;
--new-ui-main-color: white;
@@ -23,31 +23,24 @@
--new-ui-btn-danger-bg: #FF23721A;
--new-ui-ctrl-f-button-bg:#F9F9FC;
--new-ui-ctrl-f-button-border:1px solid #C4CBD8;
-
- --copy-border: #EFF0F2;
- --copy-color: #343437;
-
- --cards-hover:#F9F9FF;
- --choosen-tab: #FFFFFF;
- --choosen-tab-color:#373737 ;
}
:root[data-theme='dark'] {
- --air-color: #8280ff;
- --background-color-main: #303030;
- --background-color-page: #303030;
- --background-color-table: #4b4b4b;
- --background-color-additional: #373737;
- --search-bg: #464646;
- --color-btn-gray: #d0d0d0;
- --bg-color-button-gray: #5d5a5a;
- --text-color-additional-one: #d4d4d4;
- --text-color-main: #ffffff;
- --text-color-additional-two: #ffffff;
- --text-color-purple: #7f7df3;
- --border-color: #202020;
- --border-color2: #2c2c2c;
- --bg-audio: #303030;
+ --air-color: #8280FF;
+ --background-color-main: #303030;
+ --background-color-page: #303030;
+ --background-color-table: #4b4b4b;
+ --background-color-additional: #373737;
+ --search-bg: #464646;
+ --color-btn-gray: #d0d0d0;
+ --bg-color-button-gray: #5d5a5a;
+ --text-color-additional-one: #d4d4d4;
+ --text-color-main: #ffffff;
+ --text-color-additional-two: #ffffff;
+ --text-color-purple: #7f7df3;
+ --border-color: #202020;
+ --border-color2: #2c2c2c;
+ --bg-audio: #303030;
--new-ui-bg-app-color: #303035;
--new-ui-border: 1px solid #40404E;
@@ -57,72 +50,63 @@
--new-ui-btn-danger-bg: #FF23721A;
--new-ui-ctrl-f-button-bg:#242428;
--new-ui-ctrl-f-button-border:1px solid #303035;
-
- --copy-border: #343437;
- --copy-color:#EFF0F2;
-
- --cards-hover:#303047;
- --choosen-tab: #151518;
- --choosen-tab-color: #FFFFFF;
}
* {
- box-sizing: border-box;
- padding: 0;
- margin: 0;
+ box-sizing: border-box;
+ padding: 0;
+ margin: 0;
}
-
-
-
html {
+
}
body {
- max-width: 100vw;
- background-color: var(--new-ui-bg-app-color);
- scroll-behavior: smooth;
- font-feature-settings: 'lnum' 1;
+ max-width: 100vw;
+ background-color: var(--new-ui-bg-app-color);
+ scroll-behavior: smooth;
+ font-feature-settings: 'lnum' 1;
}
a {
- color: inherit;
- text-decoration: none;
+ color: inherit;
+ text-decoration: none;
}
p {
- font-size: 15px;
- font-style: normal;
- font-weight: 400;
- color: var(--new-ui-text-color);
+ font-size: 15px;
+ font-style: normal;
+ font-weight: 400;
+ color: var(--new-ui-text-color);
}
.introjs-tooltip {
- max-width: 350px !important;
- border-radius: 10px;
- background-color: transparent !important;
- box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.04), 0px 4px 32px rgba(0, 0, 0, 0.16) !important;
+ max-width: 350px !important;
+ border-radius: 10px;
+ background-color: transparent !important;
+ box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.04), 0px 4px 32px rgba(0, 0, 0, 0.16) !important;
}
.introjs-tooltip-header {
- border-radius: 10px 9px 0px 0px !important;
+ border-radius: 10px 9px 0px 0px !important;
}
.introjs-tooltip * {
- color: white;
- background-color: #8685c6;
+ color: white;
+ background-color: #8685c6;
}
.left {
- border-right-color: #8685c6 !important;
- border: 10px;
- background-color: transparent !important;
+ border-right-color: #8685c6 !important;
+ border: 10px;
+ background-color: transparent !important;
}
.bottom {
- border-top-color: #6d6ca6 !important;
- border: 10px;
- background-color: transparent !important;
+ border-top-color: #6d6ca6 !important;
+ border: 10px;
+ background-color: transparent !important;
}
/*li {*/
@@ -130,432 +114,306 @@ p {
/*}*/
.right {
- border-left-color: #8685c6 !important;
- border: 10px;
- background-color: transparent !important;
+ border-left-color: #8685c6 !important;
+ border: 10px;
+ background-color: transparent !important;
}
.introjs-skipbutton {
- margin-top: 6px !important;
- color: rgba(255, 255, 255, 0.5) !important;
+ margin-top: 6px !important;
+ color: rgba(255, 255, 255, 0.5) !important;
}
.MuiPaper-root.MuiAutocomplete-paper {
- background-color: var(--new-ui-main-color); /* Замените #your-color на ваш цвет */
- border: 1px solid var(--new-ui-main-color); /* Замените #your-border-color на цвет бордюра */
- box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.15); /* Измените тень, если необходимо */
-}
-
-/* Изменение цвета полоски сверху выпадающего списка */
-.MuiAutocomplete-listbox:before {
- border-top: 1px solid var(--new-ui-main-color); /* Замените #your-border-color на цвет бордюра */
-}
-
-/* Изменение цвета полоски снизу выпадающего списка */
-.MuiAutocomplete-listbox:after {
- border-bottom: 1px solid var(--new-ui-main-color); /* Замените #your-border-color на цвет бордюра */
-}
+ background-color:var(--new-ui-main-color); /* Замените #your-color на ваш цвет */
+ border: 1px solid var(--new-ui-main-color); /* Замените #your-border-color на цвет бордюра */
+ box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.15); /* Измените тень, если необходимо */
+ }
+
+ /* Изменение цвета полоски сверху выпадающего списка */
+ .MuiAutocomplete-listbox:before {
+ border-top: 1px solid var(--new-ui-main-color); /* Замените #your-border-color на цвет бордюра */
+ }
+
+ /* Изменение цвета полоски снизу выпадающего списка */
+ .MuiAutocomplete-listbox:after {
+ border-bottom: 1px solid var(--new-ui-main-color); /* Замените #your-border-color на цвет бордюра */
+ }
.MuiAutocomplete-popup {
- background-color: var(--new-ui-main-color); /* Замените #your-color на ваш цвет */
-}
-
-/* Изменение цвета элементов в выпадающем списке */
-.MuiAutocomplete-option {
- background-color: var(--new-ui-main-color); /* Замените #your-color на ваш цвет */
- color: var(--new-ui-text-color); /* Замените #your-text-color на цвет текста элементов */
-}
-
-/* Изменение цвета активного элемента в выпадающем списке */
-.MuiAutocomplete-option.Mui-selected {
- background-color: var(
- --new-ui-main-color
- ); /* Замените #your-selected-color на цвет активного элемента */
- color: var(
- --new-ui-main-color
- ); /* Замените #your-selected-text-color на цвет текста активного элемента */
-}
+ background-color: var(--new-ui-main-color); /* Замените #your-color на ваш цвет */
+ }
+
+ /* Изменение цвета элементов в выпадающем списке */
+ .MuiAutocomplete-option {
+ background-color: var(--new-ui-main-color); /* Замените #your-color на ваш цвет */
+ color:var(--new-ui-text-color); /* Замените #your-text-color на цвет текста элементов */
+ }
+
+ /* Изменение цвета активного элемента в выпадающем списке */
+ .MuiAutocomplete-option.Mui-selected {
+ background-color:var(--new-ui-main-color); /* Замените #your-selected-color на цвет активного элемента */
+ color: var(--new-ui-main-color); /* Замените #your-selected-text-color на цвет текста активного элемента */
+ }
.introjs-tooltiptext {
- padding: 6px 20px !important;
- padding-bottom: 15px !important;
- font-size: 15px !important;
- line-height: 150% !important;
+ padding: 6px 20px !important;
+ padding-bottom: 15px !important;
+ font-size: 15px !important;
+ line-height: 150% !important;
}
.introjs-helperLayer {
- border: 1px solid #8685c6 !important;
- border-radius: 20px !important;
- box-shadow: rgba(33, 33, 33, 0.8) 0px 0px 0px 0px, rgba(33, 33, 33, 0.5) 0px 0px 0px 5000px !important;
+ border: 1px solid #8685c6 !important;
+ border-radius: 20px !important;
+ box-shadow: rgba(33, 33, 33, 0.8) 0px 0px 0px 0px, rgba(33, 33, 33, 0.5) 0px 0px 0px 5000px !important;
}
.introjs-tooltipbuttons {
- border-radius: 0px 0px 10px 10px !important;
- border: none !important;
- background-color: #6d6ca6 !important;
+ border-radius: 0px 0px 10px 10px !important;
+ border: none !important;
+ background-color: #6d6ca6 !important;
}
.introjs-tooltipbuttons * {
- background-color: transparent !important;
- border: none !important;
- color: white !important;
- font-size: 14px !important;
- font-weight: 600 !important;
+ background-color: transparent !important;
+ border: none !important;
+ color: white !important;
+ font-size: 14px !important;
+ font-weight: 600 !important;
- text-shadow: none !important;
+ text-shadow: none !important;
}
.introjs-button:focus {
- box-shadow: none !important;
+ box-shadow: none !important;
}
.introjs-tooltip-title {
- margin-top: 5px !important;
- font-weight: 500 !important;
+ margin-top: 5px !important;
+ font-weight: 500 !important;
}
.MuiMenu-paper {
- padding: 0;
-}
-
-/* Примените фиксированную ширину, если необходимо */
-.MuiMenu-paper {
-}
+ padding: 0;
+ }
+
+ /* Примените фиксированную ширину, если необходимо */
+ .MuiMenu-paper {
+
+ }
.pd-30 {
- padding: 30px;
+ padding: 30px;
}
-@media (max-width: 768px) {
- .pd-30 {
- padding: 25px;
- }
+@media (max-width:768px) {
+ .pd-30 {
+ padding: 25px;
+ }
}
.bg-color-block {
- background-color: var(--new-ui-main-color);
+ background-color: var(--new-ui-main-color);
}
.border-radius-main {
- border-radius: 15px;
+ border-radius: 15px;
}
.mt-15 {
- margin-top: 15px;
+ margin-top: 15px;
}
.mt-30 {
- margin-top: 15px;
+ margin-top: 15px;
}
.color-gray {
- color: var(--new-ui-gray-color);
+ color: var(--new-ui-gray-color);
}
.font-16 {
- font-size: 16px;
+ font-size: 16px;
}
.relative {
- position: relative;
+ position: relative;
}
th {
- color: var(--new-ui-text-color) !important;
+ color: var(--new-ui-text-color) !important;
}
.content-center-translate {
- text-align: center;
- position: absolute;
- top: 150px;
- left: 37%;
- transform: translate(0, -50%);
+ text-align: center;
+ position: absolute;
+ top: 150px;
+ left: 37%;
+ transform: translate(0, -50%);
}
-.tutorial-chat-gpt {
- position: relative;
+.tutorial-chat-gpt{
+ position: relative;
}
.title-block {
- letter-spacing: 0.39px;
- color: var(--new-ui-gray-color);
- font-size: 13px !important;
- font-weight: 600;
- text-transform: uppercase;
+ letter-spacing: 0.39px;
+ color: var(--new-ui-gray-color);
+ font-size: 13px !important;
+ font-weight: 600;
+ text-transform: uppercase;
}
.title-struct {
- color: var(--new-ui-text-color);
- font-size: 15px;
- font-style: normal;
- font-weight: 600;
+ color: var(--new-ui-text-color);
+ font-size: 15px;
+ font-style: normal;
+ font-weight: 600;
}
.text {
- color: var(--new-ui-text-color);
- font-size: 15px;
- font-style: normal;
- font-weight: 400;
+ color: var(--new-ui-text-color);
+ font-size: 15px;
+ font-style: normal;
+ font-weight: 400;
}
.title-main-gray {
- color: var(--new-ui-gray-color);
- font-size: 15px;
- font-style: normal;
- font-weight: 400;
+ color: var(--new-ui-gray-color);
+ font-size: 15px;
+ font-style: normal;
+ font-weight: 400;
}
.title-vspomogatel {
- color: var(--new-ui-text-color);
- font-size: 20px;
- font-style: normal;
- font-weight: 600;
- line-height: normal;
+ color: var(--new-ui-text-color);
+ font-size: 20px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: normal;
}
::placeholder {
- color: var(--new-ui-gray-color);
+ color: var(--new-ui-gray-color)
}
textarea {
- border-radius: 10px;
- background-color: transparent;
- border: var(--new-ui-border);
- color: var(--new-ui-text-color);
- padding: 10px;
- font-size: 15px;
- font-family: inherit;
+ border-radius: 10px;
+ background-color: transparent;
+ border: var(--new-ui-border);
+ color: var(--new-ui-text-color);
+ padding: 10px;
+ font-size: 15px;
+ font-family: inherit;
}
.rdw-option-wrapper {
- border: none !important;
+ border: none !important;
}
.rdw-option-wrapper:hover {
- box-shadow: none !important;
+ box-shadow: none !important;
}
.rdw-option-wrapper {
- background-color: transparent !important;
- max-width: 900px;
+ background-color: transparent !important;
+ max-width: 900px;
}
.rdw-editor-toolbar {
background-color: transparent !important;
- padding: 20px 0 !important;
+ padding-bottom: 15px !important;
border: none !important;
- border-bottom: 1px solid var(--copy-border) !important;
- border-top: 1px solid var(--copy-border) !important;
+ border-bottom: 1px solid #EFF0F2 !important;
}
.rdw-dropdown-wrapper {
background-color: transparent !important;
border: 2px solid var(--new-ui-bg-app-color) !important;
border-radius: 10px !important;
- padding: 0 !important;
+ padding: 10px !important;
height: 36px !important;
min-width: 40px !important;
}
-.rdw-dropdown-selectedtext{
- padding: 0 16px 0 12px !important;
-}
-
.rdw-dropdown-wrapper:hover {
- box-shadow: none !important;
+ box-shadow: none !important;
}
.rdw-editor-wrapper {
- color: var(--new-ui-text-color);
+ color: var(--new-ui-text-color);
}
.rdw-dropdown-wrapper {
- background-color: transparent !important;
- position: relative;
+ background-color: transparent !important;
+ position: relative;
}
.rdw-dropdown-optionwrapper {
- border: none !important;
- border-radius: 10px !important;
width: 100% !important;
- margin-top: 12px !important;
+ margin-top: 15px !important;
overflow: hidden;
color: inherit !important;
- background-color: var(--background-color-main) !important;
overflow-y: hidden !important;
}
.rdw-block-dropdown {
- width: 150px !important;
+ width: 150px !important;
}
.rdw-dropdown-optionwrapper > li {
- color: var(--new-ui-text-color) !important;
- padding: 0 16px 0 12px !important;
-}
-
-.rdw-dropdown-optionwrapper > li:hover{
- background-color:var(--new-ui-gray-color) !important
-}
-.rdw-dropdownoption-active{
- background: var(--new-ui-gray-color) !important
+ color: inherit !important;
}
.rdw-dropdown-optionwrapper:hover {
- border: none !important;
- box-shadow: none !important;
+ box-shadow: none;
color: inherit !important;
}
-.rdw-dropdown-carettoclose{
- border-radius: 5px !important;
- border-bottom-color: var(--new-ui-gray-color) !important;
-}
-
-.rdw-dropdown-carettoopen{
- border-radius: 5px !important;
- border-top-color: var(--new-ui-gray-color) !important;
-}
-
-.rdw-text-align-wrapper{
- margin: 0 !important;
-}
-
-.rdw-list-wrapper{
- margin: 0 !important;
-}
-
-.rdw-history-wrapper{
- margin: 0 !important;
-}
-
-.rdw-block-wrapper{
- margin: 0 !important;
-}
-
.border-bottom-1px-gray {
- border-bottom: 1px solid #eff0f2 !important;
+ border-bottom: 1px solid #EFF0F2 !important;
}
.pointer {
- cursor: pointer;
+ cursor: pointer;
}
.air-color {
- background-color: var(--air-color);
+ background-color: var(--air-color);
}
-[contenteditable='true']:focus {
- outline: none;
- border: 1px solid var(--air-color) !important;
+[contenteditable="true"]:focus {
+ outline: none;
+ border: 1px solid var(--air-color) !important;
}
/*scroll styles*/
-.smallScroll::-webkit-scrollbar {
- height: 5px;
- width: 2px;
+.smallScroll::-webkit-scrollbar{
+ height: 5px;
+ width: 2px;
}
.smallScroll::-webkit-scrollbar-track {
background: initial;
- /*margin: 21px 0;*/
- margin: 5px 0;
+ margin: 21px 0;
}
.smallScroll::-webkit-scrollbar-thumb {
- background-color: rgba(217, 217, 217, 0.49);
- border-radius: 5px;
+ background-color: rgba(217, 217, 217, 0.49);
+ border-radius: 5px;
}
-.height {
- height: calc(400px + (1024 - 400) * ((100vh - 400px) / (1024 - 400)));
+.height{
+ height: calc(400px + (1024 - 400) * ((100vh - 400px) / (1024 - 400)));
}
-.rotate-180 {
- transform: rotate(180deg);
- transition: all;
- transition-duration: 250ms;
+.rotate-180{
+ transform: rotate(180deg);
+ transition: all;
+ transition-duration: 250ms;
}
.rotate-0{
transform: rotate(0deg);
transition: all;
transition-duration: 250ms;
-}
-
-
-/*COPY*/
-.toolbarClassName{
- align-items: center;
- gap: 15px;
-}
-.wrapperClassName{
-
-}
-
-.editorClassName{
- border: 1px solid transparent;
- transition: border-color 0.3s;
- cursor: text;
-}
-
-.editorClassName div:focus{
- outline: none !important;
- border-color: transparent !important;
-}
-
-.editorClassName div .public-DraftStyleDefault-block{
- display: inline-block;
- padding:0 1px;
- margin: 0.5em 0 !important;
-}
-
-.public-DraftEditor-content{
- overflow-y: scroll;
- max-height: calc(75vh - 200px) ;
-
- @media (max-width: 768px) {
- max-height: calc(70vh - 200px) ;
- }
-
-}
-
-
-.public-DraftEditor-content::-webkit-scrollbar{
- height: 5px;
- width: 2px;
-}
-
-.public-DraftEditor-content::-webkit-scrollbar-track {
- background: initial;
- margin: 21px 0;
-}
-
-.public-DraftEditor-content::-webkit-scrollbar-thumb {
- background-color: rgba(217, 217, 217, 0.49);
- border-radius: 5px;
-}
-
-.inline{
- gap:3px;
- margin: 0 !important;
-}
-
-.inline-btn{
- width: 12px;
- height: 25px !important;
- margin: 0 !important;
- padding: 0 !important;
-}
-
-.rdw-option-active{
- background: rgba(229, 229, 229, 0.18) !important;
- -webkit-box-shadow: inset 0 0 5px #c1c1c1 !important;
- -moz-box-shadow: inset 0 0 5px #c1c1c1 !important;
- box-shadow: inset 0 0 5px #c1c1c1 !important;
- outline: none !important;
-}
-
-.copy-color{
- color:var(--copy-color);
- border-color: var(--copy-border);
-
-}
+}
\ No newline at end of file
@@ -1,4 +1,4 @@
-import React, { useCallback, useEffect } from 'react'
+import React, { useCallback } from 'react'
import { useDispatch } from 'react-redux'
import { Box, Collapse, Stack, Typography } from '@mui/material'
import { useRouter } from 'next/router'
@@ -49,7 +49,6 @@ const Page: React.FC = ({ deviceType, deviceOs }) => {
const desktop = deviceType === 'desktop'
const { data } = useSession()
const router = useRouter()
-
const {
chats,
currentChat,
@@ -62,11 +61,7 @@ const Page: React.FC = ({ deviceType, deviceOs }) => {
isTryRename,
setIsTryRename,
} = useChats(modelType)
- const { messages, sendMessage, loading, getMessagesPagination, deleteMessage } = useModel(
- currentChat,
- showError,
- modelType
- )
+ const { messages, sendMessage, loading, getMessagesPagination, deleteMessage } = useModel(currentChat, showError, modelType)
const includeParams = useAppSelector((state) => state.params.params)
const dispatch = useDispatch()
@@ -74,7 +69,7 @@ const Page: React.FC = ({ deviceType, deviceOs }) => {
const deleteMessageMemo = useCallback(deleteMessage, [currentChat, messages])
React.useEffect(() => {
- if (data?.access) {
+ if (data?.access && !botParams) {
model_api.getBotParams(router.asPath.split('/')[2], data.access).then((res) => {
setBotParams(res)
setModelType(res.slug)
@@ -83,55 +78,35 @@ const Page: React.FC = ({ deviceType, deviceOs }) => {
dispatch(
setParametres(
res.parameters.reduce(
- (a, v) =>
- v.versions.includes(res.versions[0].slug)
- ? { ...a, [v.key]: v.values.default }
- : { ...a },
+ (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 }),
- {}
- )
- )
- )
+ dispatch(setParametres(res.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {})))
}
})
}
- }, [data?.access, router.query])
+ }, [data?.access])
const resetParams = () => {
if (botParams) {
dispatch(setParametres({}))
- if (botParams.versions?.length !== 0) {
+ 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 },
+ (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 }),
- {}
- )
- )
- )
+ dispatch(setParametres(botParams.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {})))
}
}
}
@@ -143,23 +118,13 @@ const Page: React.FC = ({ deviceType, deviceOs }) => {
dispatch(
setParametres(
botParams.parameters.reduce(
- (a, v) =>
- v.versions.includes(version)
- ? { ...a, [v.key]: v.values.default }
- : { ...a },
+ (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 }),
- {}
- )
- )
- )
+ dispatch(setParametres(botParams.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {})))
}
}
}
@@ -205,11 +170,7 @@ const Page: React.FC = ({ deviceType, deviceOs }) => {
}
return (
-
+
@@ -247,20 +208,10 @@ const Page: React.FC = ({ deviceType, deviceOs }) => {
handleClickChatSetting={handleClickChatSetting}
/>
{desktop && (
-
+
{botParams?.versions && botParams.versions.length !== 0 && (
<>
-
+
ВЕРСИИ
= ({ deviceType, deviceOs }) => {
setParams(!params)
}}
>
-
+
ПАРАМЕТРЫ
)}
{!desktop && (
-
+
- {botParams?.versions &&
- botParams.versions.length !== 0 && (
- <>
-
- ВЕРСИИ
-
-
- >
- )}
+ {botParams?.versions && botParams.versions.length !== 0 && (
+ <>
+
+ ВЕРСИИ
+
+
+ >
+ )}
{botParams && botParams.parameters?.length > 0 ? (
<>
= ({ deviceType, deviceOs }) => {
>
ПАРАМЕТРЫ
-
-
+
+
>
) : (
-
+
Параметры отсутствуют
)}
@@ -1,6 +1,6 @@
.card {
background-color: var(--new-ui-main-color);
- width: 330px;
+ width: 381px;
height: 227px;
border-radius: 15px;
margin-right: 20px;
@@ -9,36 +9,6 @@
cursor: pointer;
padding: 30px;
box-sizing: border-box;
- border: 1px solid var(--new-ui-main-color);
-
- .colorBox{
- width: 50px;
- height: 50px;
- border-radius: 100%;
- background-color: #313138;
- }
-
- .colorBox[data-theme='light']{
- background-color: #EFF0F2;
- }
-
- &:hover{
- transition: all;
- transition-duration: 250ms;
- background-color:var(--cards-hover);
- border-color: #8280FF;
-
- .colorBox[data-theme='light']{
- transition-duration: 250ms;
- background-color: #E7E7FF;
- }
-
- .colorBox[data-theme='dark']{
- transition-duration: 250ms;
- background-color: #222233;
- }
-
- }
@media (max-width:768px) {
width: 100%;
@@ -47,14 +17,13 @@
margin-top: 20px;
.title {
- font-size: 15px;
font-weight: 600;
}
.text {
color: var(--new-ui-gray-color);
font-weight: 400;
- margin-top: 10px;
+ margin-top: 6px;
font-size: 15px;
}
}
@@ -1,32 +1,44 @@
import React from 'react'
import { Avatar, Box, Typography } from '@mui/material'
+import Image from 'next/image'
import Link from 'next/link'
import styles from './card.module.scss'
export type CardProps = {
- theme: 'dark' | 'light'
title: string
- icon: string | null
- text: string | null
+ icon: string
+ changeFavorite: (uid: string) => Promise
+ isFavorite: boolean
+ text: string
link: string
uid: string
+ companies: string
}
-const Card = ({ text, icon, title, link, theme }: CardProps) => {
+const Card = ({ changeFavorite, isFavorite, text, icon, title, link, uid, companies }: CardProps) => {
return (
- {icon ? (
-
- ) : (
-
- )}
+
+ {
+ e.preventDefault()
+ changeFavorite(uid)
+ }}
+ src={isFavorite ? '/svg/sub_menu/favourite.svg' : '/svg/sub_menu/favourite_off.svg'}
+ width={25}
+ height={25}
+ alt={''}
+ />
{title}
{text}
+
+ {companies}
+
@@ -0,0 +1,235 @@
+import * as React from 'react'
+import { useState } from 'react'
+import { Stack, Typography } from '@mui/material'
+import Box from '@mui/material/Box'
+import Button from '@mui/material/Button'
+import dynamic from 'next/dynamic'
+import Image from 'next/image'
+import { getSession } from 'next-auth/react'
+
+import { toEditorState } from '@/src/domains/copywrite/lib/helper'
+import { useCopy } from '@/src/features/use-copy/use-copy'
+import { languages, target_audiences, tovs, useTemplate } from '@/src/features/use-copy/use-template'
+import { Layout } from '@/src/main/layout'
+import { Input, Loader, TooltipCustom } from '@/src/shared'
+import { api } from '@/src/shared/api/endpoints'
+import { getTypeDevice } from '@/src/shared/lib/helpers'
+import { Message } from '@/src/shared/lib/types/model'
+import { IDalleProps } from '@/src/shared/lib/types/types-dalle'
+import { SelectUI } from '@/src/shared/ui/select'
+
+import Title from '../../features/title/title'
+
+import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
+
+const toolbarOptions = {
+ options: ['inline', 'blockType', 'list', 'textAlign', 'history'],
+ inline: {
+ options: ['bold', 'italic', 'underline'],
+ },
+ blockType: {
+ options: ['Normal', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'Blockquote'],
+ },
+ fontSize: {
+ options: [12, 14, 16, 18, 24, 30, 36],
+ },
+ fontFamily: {
+ options: ['Arial', 'Georgia', 'Impact', 'Tahoma', 'Times New Roman', 'Verdana'],
+ },
+ list: {
+ options: ['unordered', 'ordered'],
+ },
+ textAlign: {
+ options: ['left', 'center', 'right'],
+ },
+}
+
+export async function getServerSideProps(context: any): Promise<{ props: IDalleProps }> {
+ const device = getTypeDevice(context)
+
+ const { req } = context
+
+ const session = await getSession({ req })
+
+ const token = session?.access || null
+
+ const favorites = await api.getFavoritesModel(token, session)
+
+ return {
+ props: {
+ device,
+ token,
+ favorites,
+ },
+ }
+}
+
+const Create: React.FC = ({ device, token, favorites }) => {
+ const desktop = device === 'desktop'
+
+ const [showGeneration, setShowGeneration] = useState(false)
+
+ const [isCopy, setIsCopy] = useState(false)
+
+ const copy = (text: string) => {
+ navigator.clipboard.writeText(text)
+ setIsCopy(true)
+ }
+
+ const { currentTemplate, generations, pickGeneration, setPickGeneration, createEmpty } = useCopy()
+
+ const {
+ tov,
+ lang,
+ setLang,
+ setTov,
+ setTargetAudiences,
+ targetAudiences,
+ setResourceUrls,
+ resource_urls,
+ setTheme,
+ theme,
+ keywords,
+ setKeywords,
+ createText,
+ text,
+ clearSetting,
+ isLoading,
+ content,
+ setContent,
+ onEditorChange,
+ } = useTemplate(currentTemplate)
+
+ const onSetGeneration = (message: Message) => {
+ setPickGeneration(message)
+ onEditorChange(toEditorState(message.content))
+ setShowGeneration(false)
+ }
+
+ const Editor = dynamic(() => import('react-draft-wysiwyg').then((res) => res.Editor), { ssr: false })
+
+ const EditorWrap = (): JSX.Element | null => {
+ if (showGeneration) {
+ if (!generations || generations.length === 0) {
+ return null
+ }
+
+ //@ts-ignore
+ return generations.map((el) => (
+ onSetGeneration(el)}
+ display='flex'
+ justifyContent='space-between'
+ className='border-bottom-1px-gray'
+ sx={{ cursor: 'pointer' }}
+ padding='10px'
+ key={el.uid}
+ >
+ {el.content.slice(0, 60)}...
+
+ copy(el.content)} src={'/svg/copy.svg'} width={22} height={22} alt={'copy'} />
+
+
+ ))
+ }
+
+ return (
+
+ )
+ }
+
+ return (
+
+
+
+
+
+
+ {!showGeneration && (
+ setShowGeneration(true)}>
+ Мои генерации
+
+ )}
+ {
+ onEditorChange(toEditorState(''))
+ setShowGeneration(false)
+ }}
+ >
+ Пустой шаблон
+
+
+
+
+
+
+ Настройки генерации
+
+ Ваш запрос
+
+
+ setTov(e.target.value)} list={tovs} />
+
+
+ setLang(e.target.value)} list={Object.keys(languages)} />
+
+
+ setTargetAudiences(e.target.value)}
+ list={target_audiences}
+ />
+
+
+ Тема
+ setTheme(e.target.value)} />
+
+
+ Ключевые слова (через запятую)
+ setKeywords(e.target.value.split(','))} />
+
+
+ Ресурсы (ссылки, через запятую)
+ setResourceUrls(e.target.value.split(','))} />
+
+
+
+ Сбросить настройки
+
+
+
+ {isLoading ? (
+
+
+
+ ) : (
+
+ Сгенерировать
+
+ )}
+
+
+
+
+ )
+}
+
+export default Create
@@ -0,0 +1,79 @@
+import * as React from 'react'
+import { useEffect } from 'react'
+import { Typography } from '@mui/material'
+import Box from '@mui/material/Box'
+import { getSession, useSession } from 'next-auth/react'
+
+import { loadTemplates } from '@/src/features/use-copy/copy-slice'
+import { Layout } from '@/src/main/layout'
+import { useAppDispatch, useAppSelector } from '@/src/main/store/store'
+import { api } from '@/src/shared/api/endpoints'
+import { getTypeDevice } from '@/src/shared/lib/helpers'
+import { IDalleProps } from '@/src/shared/lib/types/types-dalle'
+
+import Card from './card'
+
+export async function getServerSideProps(context: any): Promise<{ props: IDalleProps }> {
+ const device = getTypeDevice(context)
+
+ const { req } = context
+
+ const session = await getSession({ req })
+
+ const token = session?.access || null
+
+ const favorites = await api.getFavoritesModel(token, session)
+
+ return {
+ props: {
+ device,
+ token,
+ favorites,
+ },
+ }
+}
+
+const CopyPage: React.FC = ({ device, token, favorites }) => {
+ const desktop = device === 'desktop'
+
+ const { data } = useSession()
+
+ const templates = useAppSelector((state) => state.copy.templates)
+
+ const dispatch = useAppDispatch()
+
+ useEffect(() => {
+ if (data?.access) {
+ dispatch(loadTemplates(data.access))
+ }
+ }, [data?.access])
+
+ return (
+
+ Копирайтинг
+
+ {templates?.map((el) => {
+ return (
+ {}}
+ link={`/copy/create?id=${el.id}`}
+ isFavorite={false}
+ text={el.description}
+ title={el.title}
+ uid={el.id.toString()}
+ companies={''}
+ />
+ )
+ })}
+
+
+ )
+}
+
+export default CopyPage
@@ -1,180 +0,0 @@
-import * as React from 'react'
-import { useEffect, useState } from 'react'
-import { useDispatch } from 'react-redux'
-import { Box, Stack, Typography } from '@mui/material'
-import Image from 'next/image'
-import Link from 'next/link'
-import { useRouter } from 'next/router'
-import { useSession } from 'next-auth/react'
-
-import Title from '@/src/features/title/title'
-import { setTextInputContent } from '@/src/features/use-copy/copy-store'
-import { Layout } from '@/src/main/layout'
-import { useAppSelector } from '@/src/main/store/store'
-import { Error, useShowData } from '@/src/shared'
-import { getTypeDevice } from '@/src/shared/lib/helpers'
-import { getDeviceOs } from '@/src/shared/lib/helpers/get-type-device'
-import { useBeforeUnload } from '@/src/shared/lib/hooks'
-import { useChangeRouter } from '@/src/shared/lib/hooks/use-change-router'
-import { Device, DeviceOs, IFuncProps } from '@/src/shared/lib/types/entities'
-import { MobileSettingsDrawer } from '@/src/shared/ui/mobile-settings-drawer'
-import { SettingsBlockMock } from '@/src/shared/ui/mocks/settings-block-mock'
-import { CopyEndpoints } from '@/src/widgets/copy/api/copy-endpoints'
-import { editorEndpoints } from '@/src/widgets/copy/api/editor-endpoints'
-import { DraftRequestBody, EditorCopywrite } from '@/src/widgets/copy/api/models'
-import { CopyButton } from '@/src/widgets/copy/ui/buttons/copy-button'
-import { MobileButtons } from '@/src/widgets/copy/ui/buttons/mobile-buttons'
-import { EditorWrap } from '@/src/widgets/copy/ui/editor-wrap'
-import styles from '@/src/widgets/copy/ui/styles/copywrite.module.scss'
-
-import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css'
-
-export async function getServerSideProps(context: any): Promise<{ props: { device: Device; deviceOs: DeviceOs } }> {
- const device = getTypeDevice(context)
- const deviceOs = getDeviceOs(context)
- return { props: { device, deviceOs } }
-}
-
-export default function Index({ device, deviceOs }: IFuncProps) {
- const desktop = device === 'desktop'
- const theme = useAppSelector((state) => state.theme.theme)
- const input_content = useAppSelector((state) => state.copy.input_content)
- const [isSettings, setIsSettings] = useState(false)
- const [copywrite, setCopywrite] = useState(null)
- const { push, query } = useRouter()
- const { error, showError } = useShowData()
- const { data } = useSession()
- const dispatch = useDispatch()
- const [isGenerateStart, setIsGenerateStart] = useState(false)
-
- const settingsHandler = (value: boolean) => {
- setIsSettings(value)
- }
-
- const startGenerateHandler = () => {
- setIsGenerateStart(true)
- if (data?.access && query['uuid'] !== undefined) {
- const uuid = query['uuid']
- const req_body = {
- input_content: input_content,
- }
- editorEndpoints.UpdateCopywriteContent(uuid, req_body, data?.access).then(() => {
- CopyEndpoints.GenerateResponse(uuid, data?.access).then(() => {
- setIsGenerateStart(false)
- addQueryParams('resp')
- })
- })
- }
- }
-
- async function addNewUuid(uuid: string) {
- await push({
- pathname: '/copywriting/editor',
- query: { uuid },
- })
- }
-
- async function addQueryParams(mode: 'query' | 'resp') {
- await push({
- pathname: `/copywriting/my/${query['uuid']}`,
- query: { mode },
- })
- }
-
- const createDraftHandler = () => {
- let req_body: DraftRequestBody = {
- type: 'self',
- }
- CopyEndpoints.CreateDraft(req_body, 'self', data?.access).then((res) => {
- if (res) addNewUuid(res?.id)
- })
- }
-
- const saveEditorValue = (content: string) => {
- if (data?.access && query['uuid'] !== undefined) {
- const uuid = query['uuid']
- const req_body = {
- input_content: content,
- }
- editorEndpoints.UpdateCopywriteContent(uuid, req_body, data?.access)
- }
- }
-
- useEffect(() => {
- if (copywrite !== null) {
- dispatch(setTextInputContent(copywrite.input_content ?? ''))
- }
- }, [copywrite])
-
- useEffect(() => {
- if (query['uuid'] !== undefined) {
- if (data?.access) {
- CopyEndpoints.GetCopywrite(query['uuid'], 'self', data.access).then((res) => {
- if (res !== null) {
- setCopywrite(res as EditorCopywrite)
- } else {
- createDraftHandler()
- }
- })
- }
- } else {
- createDraftHandler()
- }
- }, [query, data?.access])
-
- return (
-
-
-
-
-
-
-
-
-
- Мои генерации
-
-
-
- {/* copyText('123')} />*/}
- {/**/}
-
-
- {copywrite && (
-
- )}
-
-
-
-
- Сгенерировать
-
-
-
-
- {!desktop && }
-
-
-
- )
-}
@@ -1,184 +0,0 @@
-import * as React from 'react'
-import { useEffect, useState } from 'react'
-import { Box, Stack } from '@mui/material'
-import { useRouter } from 'next/router'
-import { useSession } from 'next-auth/react'
-
-import Title from '@/src/features/title/title'
-import { addOutputContent, setDefaultVariables, setNewOutputContent, setOverrideVariables } from '@/src/features/use-copy/copy-store'
-import { Layout } from '@/src/main/layout'
-import { useAppDispatch } from '@/src/main/store/store'
-import { Error, useShowData } from '@/src/shared'
-import { getTypeDevice } from '@/src/shared/lib/helpers'
-import { getDeviceOs } from '@/src/shared/lib/helpers/get-type-device'
-import { Device, DeviceOs, IParams } from '@/src/shared/lib/types/entities'
-import { MobileSettingsDrawer } from '@/src/shared/ui/mobile-settings-drawer'
-import { SettingsBlockMock } from '@/src/shared/ui/mocks/settings-block-mock'
-import { CopyEndpoints } from '@/src/widgets/copy/api/copy-endpoints'
-import { editorEndpoints } from '@/src/widgets/copy/api/editor-endpoints'
-import { Copywrite, DraftRequestBody, EditorCopywrite, TemplateType } from '@/src/widgets/copy/api/models'
-import { CopyButton } from '@/src/widgets/copy/ui/buttons/copy-button'
-import { MobileButtons } from '@/src/widgets/copy/ui/buttons/mobile-buttons'
-import { GenerationBlock } from '@/src/widgets/copy/ui/generation/generation-block'
-import styles from '@/src/widgets/copy/ui/styles/copywrite.module.scss'
-
-export async function getServerSideProps(context: any): Promise<{
- props: { device: Device; deviceOs: DeviceOs; uuid: string }
-}> {
- const device = getTypeDevice(context)
- const deviceOs = getDeviceOs(context)
- const { uuid } = context.params
-
- return { props: { device, deviceOs, uuid } }
-}
-
-export default function Index({ device, deviceOs, uuid }: IParams) {
- const desktop = device === 'desktop'
- const [templateType, setTemplateType] = useState('template')
- const [editor, setEditor] = useState(null)
- const [copywrite, setCopywrite] = useState(null)
- const [tab, setTab] = useState<'query' | 'resp' | null>(null)
- const [isSettings, setIsSettings] = useState(false)
- const dispatch = useAppDispatch()
- const { push, query } = useRouter()
- const { error, showError } = useShowData()
- const { data } = useSession()
-
- const startGenerateHandler = () => {
- if (data?.access) {
- CopyEndpoints.GenerateResponse(uuid, data?.access).then(() => addQueryParams('resp'))
- }
- }
-
- const settingsHandler = (value: boolean) => {
- setIsSettings(value)
- }
-
- const handleChangeTab = async (tab: 'query' | 'resp') => {
- setTab(tab)
- await addQueryParams(tab)
- }
-
- async function addQueryParams(mode: 'query' | 'resp') {
- await push({
- pathname: `/copywriting/my/${uuid}`,
- query: { mode },
- })
- }
-
- async function addNewUuid(uuid: string) {
- await push({
- pathname: `/copywriting/my/${uuid}`,
- })
- }
-
- const createDraftHandler = () => {
- let req_body: DraftRequestBody = {
- type: 'template',
- initial: {
- template_id: uuid,
- },
- }
- CopyEndpoints.CreateDraft(req_body, 'template', data?.access).then((res) => {
- if (res) addNewUuid(res?.id)
- })
- }
-
- useEffect(() => {
- if (query['mode'] !== undefined && tab !== query['mode']) {
- handleChangeTab(query['mode'] as 'query' | 'resp')
- }
- }, [query])
-
- useEffect(() => {
- if (uuid && data?.access) {
- CopyEndpoints.GetCopywrite(uuid, 'template', data.access).then((res) => {
- if (res !== null) {
- if (res.type === 'template') {
- setCopywrite(res as Copywrite)
- // @ts-ignore
- dispatch(setDefaultVariables(res.template.variables))
- // @ts-ignore
- dispatch(setOverrideVariables(res.overriden_variables))
- } else {
- setEditor(res as EditorCopywrite)
- }
- setTemplateType(res.type)
- if (res.output_content !== null) {
- dispatch(setNewOutputContent(res.output_content))
- }
- } else {
- createDraftHandler()
- }
- })
- }
- }, [uuid, data?.access])
-
- useEffect(() => {
- if (editor?.draft || copywrite?.draft) {
- const socket = new WebSocket(`${editorEndpoints.webSocket.url}/copywrite/copywrites/${uuid}/`)
-
- socket.onopen = function (event) {
- dispatch(setNewOutputContent(''))
- }
-
- socket.onmessage = function (event) {
- const event_data = JSON.parse(event.data).event_data
- dispatch(addOutputContent(event_data.chunk))
-
- if (event_data.end) {
- return socket.close()
- }
- }
-
- socket.onerror = function (error) {
- showError('Произошла ошибка генерации, перезагрузите страницу')
- }
- }
- }, [copywrite, editor])
-
- return (
-
-
-
-
- {editor || copywrite ? (
-
- ) : (
- <>>
- )}
-
- {!tab && (
-
-
-
- Сгенерировать
-
-
- )}
-
-
- {!desktop && !tab && }
-
-
- )
-}
@@ -1,75 +0,0 @@
-import * as React from 'react'
-import { useEffect, useState } from 'react'
-import { Box } from '@mui/material'
-import Link from 'next/link'
-import { useSession } from 'next-auth/react'
-
-import Title from '@/src/features/title/title'
-import { Layout } from '@/src/main/layout'
-import { useAppSelector } from '@/src/main/store/store'
-import { getTypeDevice } from '@/src/shared/lib/helpers'
-import { getDeviceOs } from '@/src/shared/lib/helpers/get-type-device'
-import { Device, DeviceOs, IFuncProps } from '@/src/shared/lib/types/entities'
-import { CopyEndpoints } from '@/src/widgets/copy/api/copy-endpoints'
-import { Copywrite, ShortCopywrite } from '@/src/widgets/copy/api/models'
-import { MyCopywrite } from '@/src/widgets/copy/ui/my-copywrite'
-import styles from '@/src/widgets/copy/ui/styles/copywrite.module.scss'
-
-export async function getServerSideProps(context: any): Promise<{ props: { device: Device; deviceOs: DeviceOs } }> {
- const device = getTypeDevice(context)
- const deviceOs = getDeviceOs(context)
- return { props: { device, deviceOs } }
-}
-
-export default function Index({ device, deviceOs }: IFuncProps) {
- const desktop = device === 'desktop'
- const { data } = useSession()
- const [copywritesList, setCopywritesList] = useState(null)
-
- const changeFavouriteHandler = (id: string, favourite: boolean) => {
- if (!favourite) {
- CopyEndpoints.MarkAsFavourite(id, data?.access).then(() => {
- CopyEndpoints.ListCopywrites(data?.access).then((res) => {
- if (res) setCopywritesList(res)
- })
- })
- } else {
- CopyEndpoints.DeleteFavourite(id, data?.access).then(() => {
- CopyEndpoints.ListCopywrites(data?.access).then((res) => {
- if (res) setCopywritesList(res)
- })
- })
- }
- }
-
- useEffect(() => {
- if (data?.access) {
- CopyEndpoints.ListCopywrites(data?.access).then((res) => {
- if (res) setCopywritesList(res)
- })
- }
- }, [data?.access])
-
- return (
-
-
-
-
-
-
-
-
-
-
- Создать копирайт
-
-
-
-
-
- )
-}
@@ -1,111 +0,0 @@
-import * as React from 'react'
-import { useEffect, useState } from 'react'
-import { Tab, Tabs } from '@mui/material'
-import Box from '@mui/material/Box'
-import { useSession } from 'next-auth/react'
-
-import Title from '@/src/features/title/title'
-import { Layout } from '@/src/main/layout'
-import { useAppSelector } from '@/src/main/store/store'
-import { getTypeDevice } from '@/src/shared/lib/helpers'
-import { Device } from '@/src/shared/lib/types/entities'
-import { IDalleProps } from '@/src/shared/lib/types/types-dalle'
-import { Template, TemplateCategory } from '@/src/widgets/copy/api/models'
-import { templatesApi } from '@/src/widgets/copy/api/template-endpoints'
-import styles from '@/src/widgets/copy/ui/styles/templates.module.scss'
-
-import Card from '../../../widgets/copy/ui/card/card'
-
-export async function getServerSideProps(context: any): Promise<{ props: { device: Device } }> {
- const device = getTypeDevice(context)
- return {
- props: {
- device,
- },
- }
-}
-
-const Templates: React.FC = ({ device }) => {
- const desktop = device === 'desktop'
- const { data } = useSession()
- const theme = useAppSelector((state) => state.theme.theme)
- const [tab, setTab] = useState(null)
- const [templateList, setTemplateList] = useState(null)
- const [categoriesList, setCategoriesList] = useState(null)
- const staticTemplate = templatesApi.staticTemplate
-
- const handleChangeTab = (e: React.SyntheticEvent, value: string) => {
- setTab(value)
- }
-
- useEffect(() => {
- if (data?.access) {
- templatesApi.ListTemplateCategories(data.access).then((res) => {
- setCategoriesList(res)
- if (res) setTab(res[0].slug)
- })
- }
- }, [data?.access])
-
- useEffect(() => {
- if (data?.access && tab) {
- templatesApi.ListTemplates(data.access, tab).then((res) => {
- if (res) setTemplateList(res)
- })
- }
- }, [data?.access, tab])
-
- return (
-
-
-
- {categoriesList?.map((el) => (
-
- ))}
-
-
-
- {templateList?.map((el) => {
- return (
-
- )
- })}
-
-
-
- )
-}
-
-export default Templates
@@ -8,6 +8,7 @@ import { useRouter } from 'next/router'
import { useSession } from 'next-auth/react'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
+import { Setting } from '@/src/domains/images-bots/babes/types'
import BotParamsMap from '@/src/features/bot-params/bot-params-map'
import Title from '@/src/features/title/title'
import { ChatSelect } from '@/src/main/components/chat_select'
@@ -23,8 +24,6 @@ import { IModel } from '@/src/shared/api/models/models'
import { getTypeDevice } from '@/src/shared/lib/helpers'
import { getDeviceOs } from '@/src/shared/lib/helpers/get-type-device'
import { useShowData } from '@/src/shared/lib/hooks'
-import { ArrowDownScroll } from '@/src/shared/ui/icon-components/scroll-down-arrow'
-import { Setting } from '@/src/widgets/images/api/types'
import { ImageMessagesList } from '@/src/widgets/messages/image-messages-list'
export async function getServerSideProps(context: any): Promise<{ props: any }> {
@@ -52,16 +51,10 @@ const Images: React.FC = ({ deviceType, deviceOs }) => {
const [version, setVersion] = React.useState('')
const [modelType, setModelType] = React.useState('')
const [params, setParams] = React.useState(false)
+ const refScroll = useRef(null)
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)
@@ -73,29 +66,20 @@ const Images: React.FC = ({ deviceType, deviceOs }) => {
dispatch(
setParametres(
res.parameters.reduce(
- (a, v) =>
- v.versions.includes(res.versions[0].slug)
- ? { ...a, [v.key]: v.values.default }
- : { ...a },
+ (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 }),
- {}
- )
- )
- )
+ dispatch(setParametres(res.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {})))
}
})
.catch((err) => {})
- }, [data?.access, router.query])
+ }, [data?.access])
+ const { messages, loading, createImage, isComplete } = useModelImages(showError, modelType, deviceType)
const onLoadImage = (event: React.ChangeEvent) => {
if (event.target.files) {
setImage(event.target.files[0])
@@ -119,24 +103,14 @@ const Images: React.FC = ({ deviceType, deviceOs }) => {
dispatch(
setParametres(
botParams.parameters.reduce(
- (a, v) =>
- v.versions.includes(botParams.versions[0].slug)
- ? { ...a, [v.key]: v.values.default }
- : { ...a },
+ (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 }),
- {}
- )
- )
- )
+ dispatch(setParametres(botParams.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {})))
}
}
}
@@ -148,23 +122,13 @@ const Images: React.FC = ({ deviceType, deviceOs }) => {
dispatch(
setParametres(
botParams.parameters.reduce(
- (a, v) =>
- v.versions.includes(version)
- ? { ...a, [v.key]: v.values.default }
- : { ...a },
+ (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 }),
- {}
- )
- )
- )
+ dispatch(setParametres(botParams.parameters.reduce((a, v) => ({ ...a, [v.key]: v.values.default }), {})))
}
}
}
@@ -207,7 +171,7 @@ const Images: React.FC = ({ deviceType, deviceOs }) => {
React.useEffect(() => {
if (isComplete) {
if (!desktop) {
- const block = refScrollMobile.current
+ const block = refScroll.current
if (block) {
//@ts-ignore
block.scrollTop = block.scrollHeight
@@ -218,55 +182,18 @@ const Images: React.FC = ({ deviceType, deviceOs }) => {
}
}, [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)
- }
- }, [])
+ if (!desktop && messages !== null) {
+ const block = refScroll.current
- React.useEffect(() => {
- const block = deviceType === 'desktop' ? window : refScrollMobile.current
- if (block) {
- if (messages != undefined && !isPaginating) {
- setChatScrollHeight(block.scrollHeight)
- const time = setTimeout(() => {
+ const time = setTimeout(() => {
+ if (block) {
//@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)
- }
+ block.scrollTop = block.scrollHeight
+ }
+ }, 250)
+ return () => clearTimeout(time)
}
- setIsPaginating(false)
}, [messages])
return (
@@ -277,11 +204,7 @@ const Images: React.FC = ({ deviceType, deviceOs }) => {
justifyContent='space-between'
alignItems='start'
flexDirection={desktop ? 'row' : 'column-reverse'}
- sx={{
- marginBottom: desktop ? 0 : 3,
- width: desktop ? '97%' : '100%',
- marginTop: desktop ? 3 : '15px',
- }}
+ sx={{ marginBottom: desktop ? 0 : 3, width: desktop ? '97%' : '100%', marginTop: desktop ? 3 : '15px' }}
>
= ({ deviceType, deviceOs }) => {
/>
)}
-
-
+
+
>
) : (
- {scrollBottom > 500 && (
- {
- const block = refScrollMobile.current
-
- block.scrollTo({
- top: block.scrollHeight,
- behavior: 'smooth', // добавляем плавную прокрутку
- })
- }}
- >
-
-
- )}
= ({ deviceType, deviceOs }) => {
overflowX: 'hidden',
}}
className={'smallScroll'}
- onScroll={handleMobileScroll}
>
-
+
{botParams && (
@@ -387,21 +274,10 @@ const Images: React.FC = ({ deviceType, deviceOs }) => {
)}
{desktop && (
-
+
{botParams?.versions && botParams.versions.length !== 0 ? (
<>
-
+
ВЕРСИИ
= ({ deviceType, deviceOs }) => {
setParams(!params)
}}
>
-
+
ПАРАМЕТРЫ
)}
@@ -520,26 +369,11 @@ const Images: React.FC = ({ deviceType, deviceOs }) => {
>
ПАРАМЕТРЫ
-
-
+
+
>
) : (
-
- Параметры отсутствуют
-
+ Параметры отсутствуют
)}
@@ -22,7 +22,6 @@ axios.defaults.httpsAgent = new https.Agent({
const inter = Raleway({ subsets: ['latin'] })
function App({ Component, pageProps: { session, ...pageProps } }: AppProps) {
-
return (
<>