Faisal Amir 424b00338e
feat: revamp thread screen (#802)
* Make thread screen as default screen

* Blank state when user have not any model

* Cleanup topbar thread screen

* Improve style right panel

* Add instructions right panel

* Styling thread list history

* Resolve conflict

* Default title new thread

* Fix trigger panel sidebar

* Make default right panel false when no activethread

* Fix CI test

* chore: assistant instruction with system prompt

* Fix title and blank state explore the hub

* Claenup style thread screen and add buble message for assitant

* Remove unused import

* Styling more menus on thread list and right panel, and make max height textarea 400 pixel

* Finished revamp ui thread

* Finished system monitor UI

* Style box running models

* Make animate right panel more smooth

* Add status arround textarea for starting model info

* Temporary disable hide left panel

* chore: system resource monitoring update

* copy nits

* chore: typo

* Reverse icon chevron accordion

* Move my models into setting page

---------

Co-authored-by: Louis <louis@jan.ai>
Co-authored-by: 0xSage <n@pragmatic.vc>
2023-12-04 10:55:47 +07:00

100 lines
3.0 KiB
TypeScript

import { ReactNode, useState, useRef } from 'react'
import {
ChevronDownIcon,
MoreVerticalIcon,
FolderOpenIcon,
Code2Icon,
} from 'lucide-react'
import { twMerge } from 'tailwind-merge'
import { useClickOutside } from '@/hooks/useClickOutside'
interface Props {
children: ReactNode
title: string
onRevealInFinderClick: (type: string) => void
onViewJsonClick: (type: string) => void
}
export default function CardSidebar({
children,
title,
onRevealInFinderClick,
onViewJsonClick,
}: Props) {
const [show, setShow] = useState(true)
const [more, setMore] = useState(false)
const [menu, setMenu] = useState<HTMLDivElement | null>(null)
const [toggle, setToggle] = useState<HTMLDivElement | null>(null)
useClickOutside(() => setMore(false), null, [menu, toggle])
return (
<div
className={twMerge(
'flex w-full flex-col rounded-lg border border-border',
show && 'border border-border'
)}
>
<div
className={twMerge(
'relative flex items-center rounded-t-md bg-zinc-200 dark:bg-zinc-600/10',
show && 'border-b border-border'
)}
>
<button
onClick={() => setShow(!show)}
className="flex w-full flex-1 items-center space-x-2 px-3 py-2"
>
<ChevronDownIcon
className={twMerge(
'h-5 w-5 flex-none rotate-180 text-gray-400',
show && 'rotate-0'
)}
/>
<span className="font-bold">{title}</span>
</button>
<div
ref={setToggle}
className="cursor-pointer bg-zinc-200 p-2 dark:bg-zinc-600/10"
onClick={() => setMore(!more)}
>
<MoreVerticalIcon className="h-5 w-5" />
</div>
{more && (
<div
className="absolute right-0 top-8 z-20 w-52 overflow-hidden rounded-lg border border-border bg-background shadow-lg"
ref={setMenu}
>
<div
className="flex cursor-pointer items-center space-x-2 px-4 py-2 hover:bg-secondary"
onClick={() => {
onRevealInFinderClick(title)
setMore(false)
}}
>
<FolderOpenIcon size={16} className="text-muted-foreground" />
<span className="text-bold text-black dark:text-muted-foreground">
Reveal in Finder
</span>
</div>
<div
className="flex cursor-pointer items-center space-x-2 px-4 py-2 hover:bg-secondary"
onClick={() => {
onViewJsonClick(title)
setMore(false)
}}
>
<Code2Icon size={16} className="text-muted-foreground" />
<span className="text-bold text-black dark:text-muted-foreground">
View as JSON
</span>
</div>
</div>
)}
</div>
{show && <div className="flex flex-col gap-2 p-2">{children}</div>}
</div>
)
}