parthib07's picture
Upload 199 files
212c959 verified
import * as ScrollArea from '@radix-ui/react-scroll-area'
import { AnimatePresence, motion } from 'framer-motion'
import { PanelLeftClose, Search, SquarePen } from 'lucide-react'
import Button from '../UI/Button'
import SessionItem from './SessionItem'
export default function Sidebar({
open,
sessions,
loading,
currentSessionId,
searchValue,
onSearchChange,
onSelectSession,
onDeleteSession,
onNewSession,
onClose,
}) {
return (
<>
<AnimatePresence>
{open ? (
<motion.div
className="fixed inset-0 z-30 bg-black/35 lg:hidden"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
onClick={onClose}
/>
) : null}
</AnimatePresence>
<aside
className={`fixed inset-y-0 left-0 z-40 flex w-[min(18rem,88vw)] max-w-[288px] flex-col border-r border-border bg-panel transition-transform duration-300 ${
open ? 'translate-x-0' : '-translate-x-full'
}`}
>
<div className="space-y-3 border-b border-border p-3">
<div className="flex items-center justify-between gap-2">
<p className="truncate px-1 text-sm font-semibold text-foreground">OwnGPT</p>
<button
type="button"
onClick={onClose}
className="rounded-lg p-2 text-muted-foreground transition hover:bg-secondary hover:text-foreground lg:hidden"
aria-label="Close sidebar"
>
<PanelLeftClose className="h-4 w-4" />
</button>
</div>
<Button variant="ghost" className="w-full justify-start" onClick={onNewSession}>
<SquarePen className="h-4 w-4" />
New chat
</Button>
<label className="field flex h-10 items-center gap-2 rounded-lg px-3">
<Search className="h-4 w-4 text-muted-foreground" />
<input
value={searchValue}
onChange={(event) => onSearchChange(event.target.value)}
placeholder="Search chats"
className="w-full bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground"
/>
</label>
</div>
<div className="px-4 pb-2 pt-3">
<p className="text-xs font-medium text-muted-foreground">Chats</p>
</div>
<ScrollArea.Root className="flex-1 overflow-hidden px-2">
<ScrollArea.Viewport className="h-full w-full">
<div className="space-y-0.5 pb-3">
{loading ? (
Array.from({ length: 6 }).map((_, index) => (
<div
key={index}
className="h-10 animate-pulse rounded-lg bg-secondary"
/>
))
) : sessions.length ? (
sessions.map((session) => (
<SessionItem
key={session.session_id}
session={session}
active={session.session_id === currentSessionId}
onSelect={onSelectSession}
onDelete={onDeleteSession}
/>
))
) : (
<div className="px-3 py-4 text-sm text-muted-foreground">
No chats yet
</div>
)}
</div>
</ScrollArea.Viewport>
<ScrollArea.Scrollbar orientation="vertical" className="w-2.5 bg-transparent p-0.5">
<ScrollArea.Thumb className="rounded-full bg-border/80" />
</ScrollArea.Scrollbar>
</ScrollArea.Root>
</aside>
</>
)
}