feat: chats list on the left of the client chat

This commit is contained in:
2025-04-16 13:58:02 +04:00
parent f28df5a074
commit d347c09199
12 changed files with 201 additions and 15 deletions

View File

@@ -7,7 +7,12 @@ import MessageInput from "./components/MessageInput/MessageInput.tsx";
import { Virtuoso } from "react-virtuoso";
import { Stack } from "@mantine/core";
const Chat = () => {
type Props = {
height?: number | string;
padding?: number | string;
}
const Chat = ({ height = "96vh", padding = 0 }: Props) => {
const {
messages,
lastMessage,
@@ -45,7 +50,7 @@ const Chat = () => {
);
}
return (
<Stack mb={"xs"} mr={"xs"}>
<Stack mt={"xs"} mr={"xs"} ml={padding}>
{dateComponent}
<Message
key={`${sessionData.id}${index}`}
@@ -59,14 +64,14 @@ const Chat = () => {
if (messages.length === 0) {
return (
<Stack h={"96vh"} justify={"flex-end"}>
<MessageInput />
<Stack h={height} justify={"flex-end"}>
<MessageInput inputMargin={padding} />
</Stack>
);
}
return (
<Stack h={"96vh"}>
<Stack h={height}>
<Virtuoso
data={messages}
followOutput={onFollowOutputHandler}
@@ -78,7 +83,7 @@ const Chat = () => {
increaseViewportBy={200}
alignToBottom
/>
<MessageInput />
<MessageInput inputMargin={padding} />
</Stack>
);
};

View File

@@ -0,0 +1,12 @@
.chats-list-item {
cursor: pointer;
}
.chats-list-item-selected {
@mixin dark {
background-color: var(--mantine-color-dark-6);
}
@mixin light {
background-color: var(--mantine-color-gray-3);
}
}

View File

@@ -0,0 +1,50 @@
import { Center, List, Text } from "@mantine/core";
import { ChatSchema, ChatsListItemSchema } from "../../../../client";
import { IconBriefcase, IconGrid3x3 } from "@tabler/icons-react";
import classNames from "classnames";
import styles from "./ChatsList.module.css";
type Props = {
chats: ChatsListItemSchema[];
onChatSelect: (chat: ChatSchema) => void;
selectedChat: ChatSchema | null;
}
const ChatsList = ({ chats, onChatSelect, selectedChat }: Props) => {
const clientChat = chats.find(chat => chat.clientId);
chats = chats.filter(chat => !chat.clientId);
const chatItem = (chat: ChatsListItemSchema, isGeneral: boolean) => {
return (
<List.Item
p={"sm"}
onClick={() => onChatSelect(chat)}
key={chat.id}
icon={(
<Center>
{isGeneral ? (
<IconGrid3x3 />
) : (
<IconBriefcase />
)}
</Center>
)}
className={classNames(
styles["chats-list-item"],
selectedChat?.id === chat.id && styles["chats-list-item-selected"],
)}
>
<Text>{chat.name}</Text>
</List.Item>
);
};
return (
<List center>
{clientChat && chatItem(clientChat, true)}
{chats.map(chat => chatItem(chat, false))}
</List>
);
};
export default ChatsList;

View File

@@ -6,7 +6,11 @@ import SelectedFile from "../SelectedFile/SelectedFile.tsx";
import React, { useRef } from "react";
const MessageInput = () => {
type Props = {
inputMargin?: number | string;
}
const MessageInput = ({ inputMargin }: Props) => {
const formRef = useRef<HTMLFormElement>(null);
const {
@@ -26,7 +30,7 @@ const MessageInput = () => {
}
};
const getFiles = files.map(file => (
const filesList = files.map(file => (
<SelectedFile key={file.name} file={file} />
));
@@ -34,8 +38,12 @@ const MessageInput = () => {
<form ref={formRef} onSubmit={form.onSubmit(values => submitMessage(values))}>
<Stack gap={"xs"}>
<Divider />
{getFiles}
<Group wrap={"nowrap"} align={"flex-end"}>
{filesList.length > 0 && (
<Stack mx={inputMargin}>
{filesList}
</Stack>
)}
<Group wrap={"nowrap"} align={"flex-end"} mx={inputMargin}>
{chat?.tgGroup?.tgInviteLink && (
<ActionIconCopy
onCopiedLabel={"Ссылка на чат скопирована в буфер обмена"}