-
{formatedDate} мин. назад
+
{formatedDate}
{model}
@@ -1,3 +1,4 @@
export * from './types'
export * from './api'
export * from './ui'
+export * from './model'
@@ -0,0 +1 @@
+export * from './use-messages-filters'
\ No newline at end of file
@@ -0,0 +1,16 @@
+import { Message } from '#/entities/message'
+import { useState } from 'react'
+
+export function useMessagesFilters(messages: Message[]) {
+ const [value, setValue] = useState('')
+
+ const filteredMessages = messages.filter((message) => {
+ return message.content.toLowerCase().includes(value.toLowerCase())
+ })
+
+ return {
+ filteredMessages,
+ value,
+ setValue
+ }
+}
@@ -0,0 +1 @@
+export * from './message-fast-choice-menu'
@@ -0,0 +1,75 @@
+.menu {
+ display: flex;
+ flex-direction: column;
+ gap: 15px;
+ padding: 10px;
+ border-radius: 15px;
+ border: 1px solid rgba($color: #a4aab5, $alpha: 0.2);
+ background: var(--new-ui-element-bg);
+ width: fit-content;
+ transition: all 0.6s ease-in-out;
+
+ &:hover {
+ width: 280px !important;
+ .menu__new {
+ span {
+ display: inline-block;
+ }
+ }
+
+ .menu__input {
+ display: inline-block;
+ width: 150px !important;
+ }
+
+ .menu__inputbox {
+ justify-content: flex-end;
+ }
+ }
+
+ &__new {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 7px;
+ padding: 10px 15px;
+ span {
+ display: none;
+ color: var(--new-ui-gray-color);
+ }
+ }
+
+ &__inputbox {
+ display: flex;
+ align-items: center;
+ justify-content: center !important;
+ gap: 5px;
+ padding: 5px 7px;
+ }
+
+ &__input {
+ outline: none;
+ border: none;
+ background: transparent;
+ color: var(--text-color-main);
+ display: none;
+ &::placeholder {
+ color: var(--new-ui-gray-color);
+ }
+ }
+}
+
+.list {
+ height: 350px;
+ overflow-y: scroll;
+
+ &__empty {
+ color: var(--new-ui-gray-color);
+ text-align: center;
+ }
+}
+
+.loader {
+ text-align: center;
+ // width: max-content;
+}
@@ -0,0 +1,64 @@
+import React, { MouseEventHandler, useState } from 'react'
+import styles from './message-fast-choice-menu.module.scss'
+import { c, Loader } from '#/shared'
+import { Message } from '#/entities/message'
+import PlusSvg from '#/assets/svg/plus.svg?react'
+import Image from 'next/image'
+import { MessageItem } from './message-item'
+import SearchSvg from '#/assets/svg/search.svg?react'
+import { useMessagesFilters } from '../model'
+
+export interface MessageFastChoiceMenuProps {
+ messages: Message[]
+ loading: boolean
+}
+
+export const MessageFastChoiceMenu = ({ messages, loading }: MessageFastChoiceMenuProps) => {
+ const { filteredMessages, value, setValue } = useMessagesFilters(messages)
+
+ const [hovered, setHovered] = useState(false)
+
+ return (
+ setHovered(true)}
+ onMouseLeave={() => setHovered(false)}
+ className={styles.menu}
+ >
+
+
+ {loading && (
+
+
+
+ )}
+ {!filteredMessages.length && !loading && (
+ - Ничего не найдено
+ )}
+ {filteredMessages.map((message) => (
+ -
+ {}}
+ {...message}
+ />
+
+ ))}
+
+
+
+
+ setValue(e.target.value)}
+ className={styles.menu__input}
+ placeholder='Поиск генераций'
+ type='text'
+ />
+
+
+ )
+}
@@ -0,0 +1,58 @@
+.item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 7px;
+ border-radius: 10px;
+ transition: width 0.6s ease-in-out;
+
+ &_hovered {
+ .item__desc {
+ display: block;
+ opacity: 1;
+ }
+
+ .item__right {
+ opacity: 1;
+ display: block;
+ }
+ }
+
+ &:hover {
+ background-color: var(--new-ui-bg-app-color);
+ }
+
+ &__desc {
+ opacity: 0;
+ transition: opacity 0.6s ease-in-out;
+ display: none;
+ }
+
+ &__left {
+ display: flex;
+ gap: 7px;
+ align-items: center;
+ }
+
+ &__right {
+ padding-right: 10px;
+ opacity: 0;
+ transition: opacity 0.6s ease-in-out;
+ display: none;
+ }
+
+ &__img {
+ border-radius: 5px;
+ object-fit: cover;
+ }
+
+ &__content {
+ font-weight: 500;
+ font-size: 14px;
+ }
+
+ &__time {
+ font-size: 11px;
+ color: var(--new-ui-gray-color);
+ }
+}
@@ -0,0 +1,48 @@
+import { Message, useMessageTime } from '#/entities/message'
+import Image from 'next/image'
+import React from 'react'
+
+import styles from './message-item.module.scss'
+import { c } from '#/shared'
+import TrashSvg from '#/assets/svg/trash.svg?react'
+
+interface MessageItemProps extends Message {
+ deleteMessage: () => void
+ className?: string
+ hovered?: boolean
+}
+
+export const MessageItem = ({
+ created_at,
+ className,
+ file,
+ hovered,
+ content,
+ deleteMessage,
+}: MessageItemProps) => {
+ const { formatedDate } = useMessageTime(created_at)
+
+ return (
+
+
+

+
+
{formatedDate}
+
{content}
+
+
+
+
+
+
+
+ )
+}
@@ -0,0 +1,2 @@
+export * from './ui'
+export * from './model'
@@ -1,5 +1,18 @@
export function formatAndSortDates(inputArray: { date: string; value: number }[]) {
- const monthNames = ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек']
+ const monthNames = [
+ 'янв',
+ 'фев',
+ 'мар',
+ 'апр',
+ 'май',
+ 'июн',
+ 'июл',
+ 'авг',
+ 'сен',
+ 'окт',
+ 'ноя',
+ 'дек',
+ ]
const formattedData = inputArray.map((item: any) => {
const date = new Date(item.date)
@@ -23,14 +36,14 @@ export function formatAndSortDates(inputArray: { date: string; value: number }[]
}
export function formatDate(
- date: string | number | Date,
- options: Intl.DateTimeFormatOptions,
- lang?: string
+ date: string | number | Date,
+ options: Intl.DateTimeFormatOptions,
+ lang?: string
) {
- if (typeof date !== "object") {
- date = new Date(typeof date === "number" ? date : Date.parse(date))
- }
+ if (typeof date !== 'object') {
+ date = new Date(typeof date === 'number' ? date : Date.parse(date))
+ }
- const formatter = Intl.DateTimeFormat("ru", options)
- return formatter.format(date)
+ const formatter = Intl.DateTimeFormat('ru', options)
+ return formatter.format(date)
}
@@ -12,16 +12,23 @@
transform: translateX(-50%);
z-index: 3;
+ @media screen and (max-width: 1200px) {
+ top: 30px;
+ }
+}
- @media screen and (max-width: 1200px) {
- top: 30px;
- }
+.popup {
+ position: absolute;
+ top: 50%;
+ right: 20px;
+ transform: translateY(-50%);
+ z-index: 2;
}
.messages {
z-index: 2;
- height: calc(100dvh - 20px - 20px - 40px - 25px);
- overflow-y: scroll;
+ height: calc(100dvh - 20px - 20px - 40px - 25px);
+ overflow-y: scroll;
}
.input {
@@ -49,7 +56,7 @@
var(--new-ui-bg-app-color) 30%,
rgba(255, 255, 255, 0) 100%
);
- z-index: 1;
+ z-index: 1;
&_top {
top: 0px;
}
@@ -13,9 +13,10 @@ import { useImageBot } from '#/entities/model-entity/model/use-image-bot'
import { ImageModelsPopup, ImageModelsSelect } from '#/widgets/image-models-popup'
import { ImageInput } from '#/features/image-models-input'
-import { useRef } from 'react'
+import { useEffect, useRef } from 'react'
import { useMessagesStore } from '#/widgets/messages'
import { ImagesEmpty } from '#/widgets/image-messages'
+import { MessageFastChoiceMenu } from '#/features/message-fast-choice-menu'
const ImageModelPage: NextPageWithLayout = () => {
const { query } = useRouter()
@@ -36,7 +37,7 @@ const ImageModelPage: NextPageWithLayout = () => {
await Promise.all([fetchBotParams()])
}
- React.useEffect(() => {
+ useEffect(() => {
onFetch()
}, [session, query])
@@ -67,6 +68,10 @@ const ImageModelPage: NextPageWithLayout = () => {
+
+
+
+
@@ -61,7 +61,7 @@ export const ImageMessagesList = ({ className, container }: MessagesListProps) =
setChosenImage(message.file as string)
}}
>
-
+
))}