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:
Aditya Nandan 2023-07-02 18:00:11 +05:30 committed by GitHub
parent b444761622
commit 315411facd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 55 deletions

View File

@ -9,7 +9,7 @@ import { ChatProvider } from "./context/ChatContext";
export default function ChatPage() { export default function ChatPage() {
return ( return (
<main className="flex flex-col w-full pt-10"> <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 <PageHeading
title="Chat with your brain" title="Chat with your brain"
subtitle="Talk to a language model about your uploaded data" subtitle="Talk to a language model about your uploaded data"

View File

@ -12,7 +12,7 @@ export const ChatMessages = (): JSX.Element => {
return ( return (
<Card <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} ref={chatListRef}
> >
<div className="flex-1"> <div className="flex-1">

View File

@ -26,7 +26,7 @@ export const ChatsList = (): JSX.Element => {
setOpen(false); 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 <motion.div
animate={{ 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)"
: "10px 10px 16px rgba(0, 0, 0, 0.5)", : "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 /> <NewChatButton />
<div style={{ flex: 1, overflow: "scroll", height: "100%" }}> <div className="flex-1 overflow-auto scrollbar h-full">
{allChats.map((chat) => ( {allChats.map((chat) => (
<ChatsListItem <ChatsListItem
key={chat.chat_id} key={chat.chat_id}

View File

@ -19,7 +19,7 @@ const Layout = ({ children }: LayoutProps): JSX.Element => {
return ( return (
<ChatsProvider> <ChatsProvider>
<div className="relative h-full w-full flex items-start"> <div className="relative h-full w-full flex justify-stretch items-stretch">
<ChatsList /> <ChatsList />
{children} {children}
</div> </div>

View File

@ -3,9 +3,12 @@ import { useEffect, useRef, useState } from "react";
import { FaBrain } from "react-icons/fa"; import { FaBrain } from "react-icons/fa";
import { IoMdAdd } from "react-icons/io"; 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 { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
import { useEventTracking } from "@/services/analytics/useEventTracking"; import { useEventTracking } from "@/services/analytics/useEventTracking";
import { AnimatePresence, motion } from "framer-motion";
import { MdCheck } from "react-icons/md";
export const BrainsDropDown = (): JSX.Element => { export const BrainsDropDown = (): JSX.Element => {
const [showDropdown, setShowDropdown] = useState(false); const [showDropdown, setShowDropdown] = useState(false);
@ -17,7 +20,7 @@ export const BrainsDropDown = (): JSX.Element => {
const toggleDropdown = () => { const toggleDropdown = () => {
setShowDropdown((prevState) => !prevState); setShowDropdown((prevState) => !prevState);
void track("SHOW_BRAINS_DROPDOWN") void track("SHOW_BRAINS_DROPDOWN");
}; };
const handleCreateBrain = () => { const handleCreateBrain = () => {
@ -27,7 +30,7 @@ export const BrainsDropDown = (): JSX.Element => {
void createBrain(newBrainName); void createBrain(newBrainName);
setNewBrainName(""); // Reset the new brain name input setNewBrainName(""); // Reset the new brain name input
void track("BRAIN_CREATED") void track("BRAIN_CREATED");
}; };
const handleClickOutside = (event: MouseEvent) => { const handleClickOutside = (event: MouseEvent) => {
@ -40,9 +43,9 @@ export const BrainsDropDown = (): JSX.Element => {
}; };
const changeBrains = (value: string) => { const changeBrains = (value: string) => {
void track("CHANGE_BRAIN") void track("CHANGE_BRAIN");
setNewBrainName(value) setNewBrainName(value);
} };
useEffect(() => { useEffect(() => {
document.addEventListener("mousedown", handleClickOutside); document.addEventListener("mousedown", handleClickOutside);
@ -63,42 +66,58 @@ export const BrainsDropDown = (): JSX.Element => {
> >
<FaBrain className="w-6 h-6" /> <FaBrain className="w-6 h-6" />
</button> </button>
<AnimatePresence>
{showDropdown && ( {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"> <motion.div
{/* Option to create a new brain */} initial={{ opacity: 0, y: -32, height: "0" }}
<div className="px-4 py-2"> animate={{
<div className="flex items-center"> opacity: 1,
<input y: 0,
type="text" height: "13rem",
placeholder="Add a new brain" }}
value={newBrainName} exit={{ opacity: 0, y: -32, height: "0" }}
onChange={(e) => changeBrains(e.target.value)} transition={{ duration: 0.2, ease: "easeInOut" }}
className="flex-1 px-3 py-2 border border-gray-300 rounded-lg focus:outline-none" 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"
/>
<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}
> >
{/* Option to create a new brain */}
<form
onSubmit={(e) => {
e.preventDefault();
handleCreateBrain();
}}
className="flex items-center gap-2 p-2"
>
<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" /> <IoMdAdd className="w-5 h-5" />
</button> </Button>
</div> </form>
</div> <div className="overflow-auto scrollbar flex flex-col h-full">
{/* List of brains */} {/* List of brains */}
{allBrains.map((brain) => ( {allBrains.map((brain) => (
<button <button
key={brain.id} key={brain.id}
type="button" type="button"
className={`block w-full text-left px-4 py-2 text-sm leading-5 ${ 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`}
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 })} onClick={() => setActiveBrain({ ...brain })}
> >
{brain.name} <span className="flex-1">{brain.name}</span>
<span>
{currentBrain?.id === brain.id && (
<MdCheck className="text-xl" width={32} height={32} />
)}
</span>
</button> </button>
))} ))}
</div> </div>
</motion.div>
)} )}
</AnimatePresence>
</div> </div>
</> </>
); );