@@ -0,0 +1,5 @@ + + + \ No newline at end of file @@ -6,6 +6,7 @@ export interface IShortModel { description: string slug: string image: string + blocked: boolean actual_stat: { generation_time: string tokens_cost: string @@ -4,10 +4,18 @@ import { useMemo, useState } from 'react' export function useImageModelsPopup() { const { bots, fetchBots, setBots } = useImagesBots() - const [popupOpen, setPopupOpen] = useState(false) + const [popupOpen, setPopupOpen] = useState(false) + + const fileteredModels = useMemo( + () => + bots.sort((a, b) => + a.blocked && !b.blocked ? 1 : !a.blocked && b.blocked ? -1 : 0 + ), + [bots] + ) const averageTokenCost = useMemo(() => { - if (!bots.length) return 0 + if (!bots.length) return 0 const prices = bots.filter((item) => item.actual_stat).map((item) => item.actual_stat) @@ -21,7 +29,8 @@ export function useImageModelsPopup() { setBots, fetchBots, averageTokenCost, - popupOpen, - setPopupOpen + popupOpen, + fileteredModels, + setPopupOpen, } } @@ -1,11 +1,27 @@ .container { position: relative; - @media (max-width: 768px) { - position: static; - } + @media (max-width: 768px) { + position: static; + } } +.wrapper { + background: rgba($color: #000000, $alpha: 0.4); + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 104; + visibility: hidden; + opacity: 0; + transition: all 0.3s ease-in-out; + &_open { + visibility: visible; + opacity: 1; + } +} .select { padding: 0px 18px; background: rgba(#8280ff, 0.1); @@ -19,8 +35,8 @@ &__arrow { padding-top: 5px; @media (max-width: 768px) { - width: 15px; - height: 15px; + width: 15px; + height: 15px; } } @@ -45,16 +61,16 @@ visibility: hidden; opacity: 0; transition: all 0.3s ease-in-out; - border: 1px solid #40404e4b; - max-height: 70vh; - overflow-y: scroll; + border: 1px solid #40404e4b; + max-height: 70vh; + overflow-y: scroll; + top: calc(100% + 10px); - - @media (max-width: 768px) { - left: 0; - right: 0; - width: fit-content; - } + @media (max-width: 768px) { + left: 0; + right: 0; + width: fit-content; + } &_open { visibility: visible; @@ -13,7 +13,8 @@ interface ImageModelsPopupProps { } export const ImageModelsPopup = ({ model }: ImageModelsPopupProps) => { - const { bots, fetchBots, averageTokenCost, popupOpen, setPopupOpen } = useImageModelsPopup() + const { fileteredModels, fetchBots, averageTokenCost, popupOpen, setPopupOpen } = + useImageModelsPopup() const { push } = useRouter() @@ -36,10 +37,14 @@ export const ImageModelsPopup = ({ model }: ImageModelsPopupProps) => { height={20} /> +
setPopupOpen(false)} + className={c(styles.wrapper, popupOpen ? styles.wrapper_open : null)} + >
- {bots.map((item) => ( + {fileteredModels.map((item) => ( { setPopupOpen(false) @@ -7,21 +7,39 @@ gap: 22px; justify-content: space-between; max-width: 500px; - transition: background-color 0.3s ease; + transition: background-color 0.3s ease; + position: relative; - &:hover{ - background-color: rgba($color: #a4aab5, $alpha: 0.1); - } + &:hover { + background-color: rgba($color: #a4aab5, $alpha: 0.1); + } + + @media (max-width: 768px) { + // max-width: calc(100% - 100px) !important; + width: 100%; + // max-width: unset; + } - @media (max-width: 768px) { - // max-width: calc(100% - 100px) !important; - width: 100%; - // max-width: unset; - } + &__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; + span { + color: white; + font-weight: 600; + padding-left: 8px; + } + } &__title { font-weight: 600; font-size: 18px; - margin-bottom: 4px; + margin-bottom: 4px; } &__description { @@ -39,7 +57,7 @@ padding: 4px 6px; font-size: 13px; display: flex; - align-items: center; + align-items: center; gap: 2px; background-color: rgba($color: #a4aab5, $alpha: 0.1); color: white; @@ -6,7 +6,7 @@ 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 { CostZones } from '../types' +import LockSvg from '@/src/assets/svg/lock.svg?react' interface ImagePopupModelProps extends IShortModel { active: boolean @@ -26,11 +26,10 @@ export const costZoneColors: CostZone[] = [ ] export const ImagePopupModel = ({ - uid, title, description, slug, - image, + blocked, actual_stat, active, averageTokenCost, @@ -49,14 +48,21 @@ export const ImagePopupModel = ({ 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 ( -
setActive(slug)} className={styles.model}> +
!blocked && setActive(slug)} className={styles.model}> + {blocked && ( +
+ + Недоступно в текущем тарифе +
+ )} +

{title}

{description}

@@ -68,7 +74,10 @@ export const ImagePopupModel = ({ {formatedTime}
-
+
{Number(actual_stat.tokens_cost)}