mirror of
https://github.com/StanGirard/quivr.git
synced 2024-12-24 20:03:41 +03:00
remove blank scrollbars and use predefined components (#452)
* style(chat and brains dropdown): remove blank scrollbars and use predefined components * style(chat): use custom scrollbar style by using scrollbar class
This commit is contained in:
parent
b444761622
commit
315411facd
@ -9,7 +9,7 @@ import { ChatProvider } from "./context/ChatContext";
|
||||
export default function ChatPage() {
|
||||
return (
|
||||
<main className="flex flex-col w-full pt-10">
|
||||
<section className="flex flex-col flex-1 items-center w-full h-full min-h-screen">
|
||||
<section className="flex flex-col flex-1 items-center w-full h-full min-h-[70vh]">
|
||||
<PageHeading
|
||||
title="Chat with your brain"
|
||||
subtitle="Talk to a language model about your uploaded data"
|
||||
|
@ -12,7 +12,7 @@ export const ChatMessages = (): JSX.Element => {
|
||||
|
||||
return (
|
||||
<Card
|
||||
className="p-5 max-w-3xl w-full flex flex-col mb-8 overflow-y-auto"
|
||||
className="p-5 max-w-3xl w-full flex flex-col mb-8 overflow-y-auto scrollbar"
|
||||
ref={chatListRef}
|
||||
>
|
||||
<div className="flex-1">
|
||||
|
@ -26,7 +26,7 @@ export const ChatsList = (): JSX.Element => {
|
||||
setOpen(false);
|
||||
}
|
||||
}}
|
||||
className="lg:sticky fixed top-0 left-0 bottom-0 overflow-visible z-30 border-r border-black/10 dark:border-white/25 bg-white dark:bg-black"
|
||||
className="flex flex-col lg:sticky fixed top-16 left-0 bottom-0 lg:h-[90vh] overflow-visible z-30 border-r border-black/10 dark:border-white/25 bg-white dark:bg-black"
|
||||
>
|
||||
<motion.div
|
||||
animate={{
|
||||
@ -36,18 +36,11 @@ export const ChatsList = (): JSX.Element => {
|
||||
? "10px 10px 16px rgba(0, 0, 0, 0)"
|
||||
: "10px 10px 16px rgba(0, 0, 0, 0.5)",
|
||||
}}
|
||||
className={cn("overflow-hidden")}
|
||||
className={cn("overflow-hidden flex flex-col flex-1")}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
flex: 1,
|
||||
height: "90vh",
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-col flex-1">
|
||||
<NewChatButton />
|
||||
<div style={{ flex: 1, overflow: "scroll", height: "100%" }}>
|
||||
<div className="flex-1 overflow-auto scrollbar h-full">
|
||||
{allChats.map((chat) => (
|
||||
<ChatsListItem
|
||||
key={chat.chat_id}
|
||||
|
@ -19,7 +19,7 @@ const Layout = ({ children }: LayoutProps): JSX.Element => {
|
||||
|
||||
return (
|
||||
<ChatsProvider>
|
||||
<div className="relative h-full w-full flex items-start">
|
||||
<div className="relative h-full w-full flex justify-stretch items-stretch">
|
||||
<ChatsList />
|
||||
{children}
|
||||
</div>
|
||||
|
@ -3,9 +3,12 @@ import { useEffect, useRef, useState } from "react";
|
||||
import { FaBrain } from "react-icons/fa";
|
||||
import { IoMdAdd } from "react-icons/io";
|
||||
|
||||
import Button from "@/lib/components/ui/Button";
|
||||
import Field from "@/lib/components/ui/Field";
|
||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||
import { useEventTracking } from "@/services/analytics/useEventTracking";
|
||||
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { MdCheck } from "react-icons/md";
|
||||
|
||||
export const BrainsDropDown = (): JSX.Element => {
|
||||
const [showDropdown, setShowDropdown] = useState(false);
|
||||
@ -17,7 +20,7 @@ export const BrainsDropDown = (): JSX.Element => {
|
||||
|
||||
const toggleDropdown = () => {
|
||||
setShowDropdown((prevState) => !prevState);
|
||||
void track("SHOW_BRAINS_DROPDOWN")
|
||||
void track("SHOW_BRAINS_DROPDOWN");
|
||||
};
|
||||
|
||||
const handleCreateBrain = () => {
|
||||
@ -27,7 +30,7 @@ export const BrainsDropDown = (): JSX.Element => {
|
||||
|
||||
void createBrain(newBrainName);
|
||||
setNewBrainName(""); // Reset the new brain name input
|
||||
void track("BRAIN_CREATED")
|
||||
void track("BRAIN_CREATED");
|
||||
};
|
||||
|
||||
const handleClickOutside = (event: MouseEvent) => {
|
||||
@ -40,9 +43,9 @@ export const BrainsDropDown = (): JSX.Element => {
|
||||
};
|
||||
|
||||
const changeBrains = (value: string) => {
|
||||
void track("CHANGE_BRAIN")
|
||||
setNewBrainName(value)
|
||||
}
|
||||
void track("CHANGE_BRAIN");
|
||||
setNewBrainName(value);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
@ -63,42 +66,58 @@ export const BrainsDropDown = (): JSX.Element => {
|
||||
>
|
||||
<FaBrain className="w-6 h-6" />
|
||||
</button>
|
||||
{showDropdown && (
|
||||
<div className="absolute overflow-scroll right-0 mt-2 w-96 h-52 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg shadow-lg">
|
||||
{/* Option to create a new brain */}
|
||||
<div className="px-4 py-2">
|
||||
<div className="flex items-center">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Add a new brain"
|
||||
value={newBrainName}
|
||||
onChange={(e) => changeBrains(e.target.value)}
|
||||
className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="flex-shrink-0 ml-2 px-3 py-2 text-sm font-medium leading-5 text-white transition-colors duration-200 transform bg-blue-600 border border-transparent rounded-lg hover:bg-blue-500 focus:outline-none focus:bg-blue-500"
|
||||
onClick={handleCreateBrain}
|
||||
>
|
||||
<IoMdAdd className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/* List of brains */}
|
||||
{allBrains.map((brain) => (
|
||||
<button
|
||||
key={brain.id}
|
||||
type="button"
|
||||
className={`block w-full text-left px-4 py-2 text-sm leading-5 ${
|
||||
currentBrain?.id === brain.id ? "bg-blue-100" : ""
|
||||
} text-gray-900 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 focus:bg-gray-100 dark:focus:bg-gray-700 focus:outline-none`}
|
||||
onClick={() => setActiveBrain({ ...brain })}
|
||||
<AnimatePresence>
|
||||
{showDropdown && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -32, height: "0" }}
|
||||
animate={{
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
height: "13rem",
|
||||
}}
|
||||
exit={{ opacity: 0, y: -32, height: "0" }}
|
||||
transition={{ duration: 0.2, ease: "easeInOut" }}
|
||||
className="absolute right-0 mt-2 w-96 flex flex-col bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg shadow-lg"
|
||||
>
|
||||
{/* Option to create a new brain */}
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
handleCreateBrain();
|
||||
}}
|
||||
className="flex items-center gap-2 p-2"
|
||||
>
|
||||
{brain.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<Field
|
||||
name="brainname"
|
||||
placeholder="Add a new brain"
|
||||
autoFocus
|
||||
onChange={(e) => changeBrains(e.target.value)}
|
||||
/>
|
||||
<Button type="submit" className="px-2 py-2">
|
||||
<IoMdAdd className="w-5 h-5" />
|
||||
</Button>
|
||||
</form>
|
||||
<div className="overflow-auto scrollbar flex flex-col h-full">
|
||||
{/* List of brains */}
|
||||
{allBrains.map((brain) => (
|
||||
<button
|
||||
key={brain.id}
|
||||
type="button"
|
||||
className={`flex items-center gap-2 w-full text-left px-4 py-2 text-sm leading-5 text-gray-900 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 focus:bg-gray-100 dark:focus:bg-gray-700 focus:outline-none`}
|
||||
onClick={() => setActiveBrain({ ...brain })}
|
||||
>
|
||||
<span className="flex-1">{brain.name}</span>
|
||||
<span>
|
||||
{currentBrain?.id === brain.id && (
|
||||
<MdCheck className="text-xl" width={32} height={32} />
|
||||
)}
|
||||
</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user