>
- image: string
+ current: string | null
+ setCurrent?: (value: string | null) => void
+ onSlideFalse?: (...args: any) => any
+ reverse?: boolean
+ images: string[]
}
-export default function FullScreenModal({ modal, setModal, image }: IProps) {
- const isSvg = image.includes('.svg')
+
+export default function FullScreenModal({ modal, setModal, current, images, onSlideFalse, reverse = false }: IProps) {
+ const { imagesWithState, updateImageState, currentImageIndex, initialCount } = useImagesLibrary(
+ images,
+ current,
+ reverse
+ )
+
+ const { swiper, setSwiper, slideNext, slidePrev } = useLibrarySwiper(onSlideFalse, reverse)
+
+ useEffect(() => {
+ if (!(initialCount < images.length && swiper)) return
+
+ if (reverse) {
+ setTimeout(() => swiper.slideTo(initialCount, 1000), 1000)
+ return
+ }
+
+ setTimeout(() => swiper.slideTo(images.length - initialCount - 1, 1000), 1000)
+ }, [images])
return (
setModal(false)}
>
- {!isSvg && image ? (
-
- ) : (
-

+
+ {modal && (
+
setSwiper(swiper)}
+ >
+ {imagesWithState.map(({ image, state }, index) => (
+
+ {!state && }
+ {!image.includes('.svg') ? (
+ e.stopPropagation()}
+ onLoadingComplete={() => {
+ updateImageState(image, true)
+ }}
+ loading='lazy'
+ src={image}
+ width={'1500'}
+ height={'1500'}
+ alt='К сожалению, изображение не загрузилось'
+ className={styles.image_style}
+ />
+ ) : (
+
e.stopPropagation()}
+ onLoad={() => updateImageState(image, true)}
+ alt='К сожалению, изображение не загрузилось'
+ className={styles.image_style}
+ />
+ )}
+
+ ))}
+
)}
+
)
@@ -0,0 +1 @@
+export { default as ImageModal } from './full-screen-modal'
@@ -0,0 +1,92 @@
+.close_block {
+ position: absolute;
+ z-index: 105;
+ cursor: pointer;
+ right: 25px;
+ top: 25px;
+}
+
+.arrow {
+ position: absolute;
+ z-index: 1205;
+ cursor: pointer;
+ top: 50%;
+
+ width: 50px;
+ height: 50px;
+
+ background: transparent;
+ border: none;
+ outline: none;
+
+ svg {
+ fill: white;
+ width: 50px;
+ height: 50px;
+ }
+
+ &_left {
+ transform: translateY(-50%) rotate(90deg);
+ left: -40px;
+ @media screen and (max-width: 768px) {
+ left: -3px;
+ }
+ }
+
+ &_right {
+ transform: translateY(-50%) rotate(-90deg);
+ right: -50px;
+
+ @media screen and (max-width: 768px) {
+ right: -10px;
+ }
+ }
+}
+
+.image_block {
+ position: absolute;
+ padding: 0 20px;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 105;
+ margin: auto;
+ width: fit-content;
+ height: fit-content;
+}
+
+.loader {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.image_style {
+ width: auto;
+ max-width: 70vw;
+ height: 100%;
+ object-fit: contain;
+
+ @media screen and (max-width: 1024px) {
+ width: auto;
+ max-width: 70vw;
+ height: auto;
+ }
+}
+
+.slide {
+ width: 80vw !important;
+ display: flex !important;
+ align-items: center;
+ justify-content: center;
+}
+
+.swiper {
+ position: relative;
+ width: 100%;
+ max-width: 80vw;
+ max-height: 1000px;
+ height: 90vh;
+}
@@ -0,0 +1 @@
+export * from './ui'
@@ -1,30 +0,0 @@
-.close_block {
- position: absolute;
- z-index: 105;
- cursor: pointer;
- right: 25px;
- top: 25px;
-}
-
-.image_block {
- position: absolute;
- padding: 0 20px;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 105;
- margin: auto;
- width: fit-content;
- height: fit-content;
-}
-
-.image_style {
- position: relative;
- width: 100%;
- height: 100%;
- max-width: 960px;
- max-height: 700px;
- border-radius: 15px;
- object-fit: contain;
-}
@@ -4,7 +4,14 @@ import Link from 'next/link'
import styles from '#/shared/styles/chats-bot-pages.module.scss'
-export default function Title(props: any) {
+export interface TitleProps {
+ type: string
+ title: string
+ linkBack?: string
+ rightSlot?: React.ReactNode
+}
+
+export default function Title(props: TitleProps) {
return (
@@ -12,11 +19,19 @@ export default function Title(props: any) {
{' '}
{props.type} •{' '}
- {props.title}
+
+ {props.title}
+
-
- {props.title}
-
+
+
+ {props.title}
+
+
{props.rightSlot}
+
)
}
@@ -0,0 +1,8 @@
+interface ApiKeyDTO {
+ created_at: string // ISO 8601 format
+ name: string
+ key: string
+ expires_at: string | null
+ user: User
+ token_limit: string
+}
@@ -0,0 +1,37 @@
+interface UserDTO {
+ uid: string
+ first_name: string
+ last_name: string
+ username: string
+ created_at: string // ISO 8601 format
+ email: string
+ is_active: boolean
+ is_superuser: boolean
+ is_staff: boolean
+ is_confirmed: boolean
+ is_subscribed_to_emails: boolean
+ show_balance: boolean
+ profile_picture_link: string
+ account_type: string
+ token: {
+ access: string
+ refresh: string
+ }
+ payment_plan: {
+ uid: string
+ plan: {
+ uid: string
+ title: string
+ price: string
+ tokens_per_plan: string
+ duration: string
+ accessed_models: string[]
+ }
+ last_payment_at: string // ISO 8601 date
+ next_payment_at: string // ISO 8601 date
+ current_token_balance: number
+ }
+ referral_code: string | null
+ is_social: boolean
+ social_auth: any[] // Assuming it can hold any type of objects
+}
@@ -21,6 +21,8 @@ axios.defaults.httpsAgent = new https.Agent({
rejectUnauthorized: false,
})
+axios.defaults.validateStatus = (status) => status < 500
+
const inter = Raleway({ subsets: ['latin'] })
export type NextPageWithLayout = NextPage
& {
@@ -35,6 +35,7 @@ export default function Document() {
+