+
setPopupOpen((prev) => !prev)} className={c(styles.select)}>
+
+ {model ? model.title : 'Загрузка...'}
+
+
+
+
setPopupOpen(false)}
+ className={c(styles.wrapper, popupOpen ? styles.wrapper_open : null)}
+ >
+
+ {fileteredModels.map((item) => (
+ {
+ setPopupOpen(false)
+ push(`/images/${slug}`)
+ }}
+ {...item}
+ key={item.uid}
+ />
+ ))}
+
+
+ >
+ )
+}
@@ -0,0 +1,99 @@
+.model {
+ // font-family: Inter;
+ padding: 15px 20px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 22px;
+ justify-content: space-between;
+ max-width: 500px;
+ transition: background-color 0.3s ease;
+ position: relative;
+
+ &:hover {
+ background-color: rgba($color: #a4aab5, $alpha: 0.1);
+ }
+
+ @media (max-width: 768px) {
+ // max-width: calc(100% - 100px) !important;
+ width: 100%;
+ // max-width: unset;
+ }
+
+ &_blocked {
+ &:hover {
+ background-color: transparent;
+ }
+ }
+
+ &__blocked {
+ background-color: rgba($color: #000000, $alpha: 0.7);
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding-right: 10px;
+ span {
+ color: white;
+ font-weight: 600;
+ padding-left: 8px;
+ }
+ }
+
+ &__locked {
+ background-color: rgba($color: #000000, $alpha: 0.7);
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding-right: 10px;
+ span {
+ color: white;
+ font-weight: 600;
+ padding-left: 8px;
+ }
+ }
+ &__title {
+ font-weight: 600;
+ font-size: 18px;
+ margin-bottom: 4px;
+ }
+
+ &__description {
+ font-size: 14px;
+ color: #a4aab5;
+ margin-bottom: 7px;
+ }
+
+ &__badges {
+ display: flex;
+ gap: 10px;
+ }
+
+ &__badge {
+ padding: 4px 6px;
+ font-size: 13px;
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ background-color: rgba($color: #a4aab5, $alpha: 0.1);
+ color: white;
+ font-weight: 500;
+ border-radius: 5px;
+ }
+
+ &__time {
+ gap: 6px;
+ color: var(--new-ui-gray-color);
+ }
+ &__cost {
+ }
+}
@@ -0,0 +1,118 @@
+import { IShortModel } from '@/src/entities/model-entity'
+import React, { useMemo } from 'react'
+
+import styles from './image-popup-model.module.scss'
+import { c, formatDate } from '@/src/shared/lib/helpers'
+import SuccessRoundedSvg from '@/src/assets/svg/success-rounded.svg?react'
+import ClockSvg from '@/src/assets/svg/clock.svg?react'
+import LightningSvg from '@/src/assets/svg/lightning.svg?react'
+import LockSvg from '@/src/assets/svg/lock.svg?react'
+import BlockedSvg from '@/src/assets/svg/blocked.svg?react'
+import { useAppSelector } from '@/src/main/store/store'
+
+interface ImagePopupModelProps extends IShortModel {
+ active: boolean
+ setActive: (slug: string) => void
+ averageTokenCost: number
+}
+
+export interface CostZone {
+ remainder: number
+ color: string
+}
+
+export const costZoneColors: CostZone[] = [
+ { remainder: -20, color: '#1EB034' },
+ { remainder: 20, color: '#B0891E' },
+ { remainder: 1000, color: '#B01E1E' },
+]
+
+export const ImagePopupModel = ({
+ title,
+ description,
+ slug,
+ blocked,
+ actual_stat,
+ active,
+ averageTokenCost,
+ setActive,
+}: ImagePopupModelProps) => {
+ const user = useAppSelector((state) => state.user)
+
+ const accessed_models = useMemo(
+ () => (user.payment_plan ? user.payment_plan.plan.accessed_models : []),
+ [user]
+ )
+
+ const isAccess = useMemo(
+ () => accessed_models && accessed_models.includes(slug),
+ [accessed_models]
+ )
+
+ // жесткий костыль))) - временный
+ const formatedTime = useMemo(() => {
+ if (!actual_stat) return null
+
+ const seconds = Number(actual_stat.generation_time.split(':')[2])
+
+ const range = Math.ceil(seconds - seconds / 3)
+
+ return `${range} - ${seconds} сек.`
+ }, [actual_stat])
+
+ const costZone = useMemo(() => {
+ if (!actual_stat) return null
+
+ const remainder = Number(actual_stat.tokens_cost) - averageTokenCost
+
+ return costZoneColors.find((item) => item.remainder > remainder)
+ }, [actual_stat, averageTokenCost])
+
+ return (
+ {
+ if (blocked || !isAccess) return
+ setActive(slug)
+ }}
+ className={c(styles.model, blocked && styles.model_blocked)}
+ >
+ {blocked ? (
+
+
+ Модель недоступна
+
+ ) : (
+ !isAccess && (
+
+
+ Недоступно в текущем тарифе
+
+ )
+ )}
+
+
+
{title}
+
{description}
+
+ {actual_stat && (
+
+
+
+ {formatedTime}
+
+
+
+
+ {Number(actual_stat.tokens_cost)}
+
+
+ )}
+
+
+ {active &&
}
+
+ )
+}
@@ -0,0 +1,2 @@
+export * from './image-models-popup'
+export * from './image-popup-model'
\ No newline at end of file
@@ -0,0 +1 @@
+export * from './types'
\ No newline at end of file
@@ -0,0 +1,14 @@
+import { Message, MessageSend } from '@/src/entities/message'
+import { API_URL } from '@/src/shared/lib/constants'
+import { IMessageRequest } from '@/src/shared/lib/types/types-gpt'
+import axios, { AxiosError, AxiosResponse } from 'axios'
+
+export async function getImagesGalery(token?: string, offset?: number, limit = 10) {
+ return await axios.get