Skip to content

Commit b9a7f8a

Browse files
feat: improve sidebar UI with distinct sections and better empty states
- Add distinct backgrounds for Projects and Chats sections - Projects section now has darker background (bg-left-panel-fg/5) while Chats has ighter background (bg-left-panel-fg/3) - Add proper spacing and padding between sections - Fix empty state logic to show "No threads yet" when all threads are in projects
1 parent 839672b commit b9a7f8a

File tree

1 file changed

+102
-98
lines changed

1 file changed

+102
-98
lines changed

web-app/src/containers/LeftPanel.tsx

Lines changed: 102 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,13 @@ const LeftPanel = () => {
403403
</div>
404404

405405
{filteredProjects.length > 0 && !(IS_IOS || IS_ANDROID) && (
406-
<div className="space-y-1 py-1">
407-
<div className="flex items-center justify-between mb-2">
408-
<span className="block text-xs text-left-panel-fg/50 px-1 font-semibold">
406+
<div className="space-y-1 py-1 bg-left-panel-fg/5 rounded-lg mx-1 mb-3">
407+
<div className="flex items-center justify-between mb-2 px-2 pt-2">
408+
<span className="block text-xs text-left-panel-fg/50 font-semibold">
409409
{t('common:projects.title')}
410410
</span>
411411
</div>
412-
<div className="flex flex-col max-h-[140px] overflow-y-scroll">
412+
<div className="flex flex-col max-h-[140px] overflow-y-scroll px-2 pb-2">
413413
{filteredProjects
414414
.slice()
415415
.sort((a, b) => b.updated_at - a.updated_at)
@@ -495,125 +495,129 @@ const LeftPanel = () => {
495495
<div className="flex flex-col h-full overflow-y-scroll w-[calc(100%+6px)]">
496496
<div className="flex flex-col w-full h-full overflow-y-auto overflow-x-hidden mb-3">
497497
<div className="h-full w-full overflow-y-auto">
498-
{favoritedThreads.length > 0 && (
499-
<>
500-
<div className="flex items-center justify-between mb-2">
501-
<span className="block text-xs text-left-panel-fg/50 px-1 font-semibold sticky top-0">
502-
{t('common:favorites')}
498+
{/* Chats Section with distinct background */}
499+
<div className="bg-left-panel-fg/3 rounded-lg mx-1 mb-3">
500+
{favoritedThreads.length > 0 && (
501+
<>
502+
<div className="flex items-center justify-between mb-2 px-2 pt-2">
503+
<span className="block text-xs text-left-panel-fg/50 font-semibold sticky top-0">
504+
{t('common:favorites')}
505+
</span>
506+
<div className="relative">
507+
<DropdownMenu>
508+
<DropdownMenuTrigger asChild>
509+
<button className="size-6 flex cursor-pointer items-center justify-center rounded hover:bg-left-panel-fg/10 transition-all duration-200 ease-in-out data-[state=open]:bg-left-panel-fg/10">
510+
<IconDots
511+
size={18}
512+
className="text-left-panel-fg/60"
513+
/>
514+
</button>
515+
</DropdownMenuTrigger>
516+
<DropdownMenuContent side="bottom" align="end">
517+
<DropdownMenuItem
518+
onClick={() => {
519+
unstarAllThreads()
520+
toast.success(
521+
t('common:toast.allThreadsUnfavorited.title'),
522+
{
523+
id: 'unfav-all-threads',
524+
description: t(
525+
'common:toast.allThreadsUnfavorited.description'
526+
),
527+
}
528+
)
529+
}}
530+
>
531+
<IconStar size={16} />
532+
<span>{t('common:unstarAll')}</span>
533+
</DropdownMenuItem>
534+
</DropdownMenuContent>
535+
</DropdownMenu>
536+
</div>
537+
</div>
538+
<div className="flex flex-col mb-4 px-2 pb-2">
539+
<ThreadList
540+
threads={favoritedThreads}
541+
isFavoriteSection={true}
542+
/>
543+
{favoritedThreads.length === 0 && (
544+
<p className="text-xs text-left-panel-fg/50 px-1 font-semibold">
545+
{t('chat.status.empty', { ns: 'chat' })}
546+
</p>
547+
)}
548+
</div>
549+
</>
550+
)}
551+
552+
{unFavoritedThreads.length > 0 && (
553+
<div className="flex items-center justify-between mb-2 px-2 pt-2">
554+
<span className="block text-xs text-left-panel-fg/50 font-semibold">
555+
{t('common:recents')}
503556
</span>
504557
<div className="relative">
505558
<DropdownMenu>
506559
<DropdownMenuTrigger asChild>
507-
<button className="size-6 flex cursor-pointer items-center justify-center rounded hover:bg-left-panel-fg/10 transition-all duration-200 ease-in-out data-[state=open]:bg-left-panel-fg/10">
560+
<button
561+
className="size-6 flex cursor-pointer items-center justify-center rounded hover:bg-left-panel-fg/10 transition-all duration-200 ease-in-out data-[state=open]:bg-left-panel-fg/10"
562+
onClick={(e) => {
563+
e.preventDefault()
564+
e.stopPropagation()
565+
}}
566+
>
508567
<IconDots
509568
size={18}
510569
className="text-left-panel-fg/60"
511570
/>
512571
</button>
513572
</DropdownMenuTrigger>
514573
<DropdownMenuContent side="bottom" align="end">
515-
<DropdownMenuItem
516-
onClick={() => {
517-
unstarAllThreads()
518-
toast.success(
519-
t('common:toast.allThreadsUnfavorited.title'),
520-
{
521-
id: 'unfav-all-threads',
522-
description: t(
523-
'common:toast.allThreadsUnfavorited.description'
524-
),
525-
}
526-
)
527-
}}
528-
>
529-
<IconStar size={16} />
530-
<span>{t('common:unstarAll')}</span>
531-
</DropdownMenuItem>
574+
<DeleteAllThreadsDialog
575+
onDeleteAll={deleteAllThreads}
576+
/>
532577
</DropdownMenuContent>
533578
</DropdownMenu>
534579
</div>
535580
</div>
536-
<div className="flex flex-col mb-4">
537-
<ThreadList
538-
threads={favoritedThreads}
539-
isFavoriteSection={true}
540-
/>
541-
{favoritedThreads.length === 0 && (
542-
<p className="text-xs text-left-panel-fg/50 px-1 font-semibold">
543-
{t('chat.status.empty', { ns: 'chat' })}
544-
</p>
545-
)}
546-
</div>
547-
</>
548-
)}
549-
550-
{unFavoritedThreads.length > 0 && (
551-
<div className="flex items-center justify-between mb-2">
552-
<span className="block text-xs text-left-panel-fg/50 px-1 font-semibold">
553-
{t('common:recents')}
554-
</span>
555-
<div className="relative">
556-
<DropdownMenu>
557-
<DropdownMenuTrigger asChild>
558-
<button
559-
className="size-6 flex cursor-pointer items-center justify-center rounded hover:bg-left-panel-fg/10 transition-all duration-200 ease-in-out data-[state=open]:bg-left-panel-fg/10"
560-
onClick={(e) => {
561-
e.preventDefault()
562-
e.stopPropagation()
563-
}}
564-
>
565-
<IconDots
566-
size={18}
567-
className="text-left-panel-fg/60"
568-
/>
569-
</button>
570-
</DropdownMenuTrigger>
571-
<DropdownMenuContent side="bottom" align="end">
572-
<DeleteAllThreadsDialog
573-
onDeleteAll={deleteAllThreads}
574-
/>
575-
</DropdownMenuContent>
576-
</DropdownMenu>
577-
</div>
578-
</div>
579-
)}
581+
)}
580582

581-
{filteredThreads.length === 0 && searchTerm.length > 0 && (
582-
<div className="px-1 mt-2">
583-
<span className="block text-xs text-left-panel-fg/50 px-1 font-semibold mb-2">
584-
{t('common:recents')}
585-
</span>
586-
587-
<div className="flex items-center gap-1 text-left-panel-fg/80">
588-
<IconSearch size={18} />
589-
<h6 className="font-medium text-base">
590-
{t('common:noResultsFound')}
591-
</h6>
592-
</div>
593-
<p className="text-left-panel-fg/60 mt-1 text-xs leading-relaxed">
594-
{t('common:noResultsFoundDesc')}
595-
</p>
596-
</div>
597-
)}
583+
{filteredThreads.length === 0 && searchTerm.length > 0 && (
584+
<div className="px-3 mt-2 pb-2">
585+
<span className="block text-xs text-left-panel-fg/50 px-1 font-semibold mb-2">
586+
{t('common:recents')}
587+
</span>
598588

599-
{Object.keys(threads).length === 0 && !searchTerm && (
600-
<>
601-
<div className="px-1 mt-2">
602589
<div className="flex items-center gap-1 text-left-panel-fg/80">
603-
<IconMessage size={18} />
590+
<IconSearch size={18} />
604591
<h6 className="font-medium text-base">
605-
{t('common:noThreadsYet')}
592+
{t('common:noResultsFound')}
606593
</h6>
607594
</div>
608595
<p className="text-left-panel-fg/60 mt-1 text-xs leading-relaxed">
609-
{t('common:noThreadsYetDesc')}
596+
{t('common:noResultsFoundDesc')}
610597
</p>
611598
</div>
612-
</>
613-
)}
599+
)}
600+
601+
{/* Show "No threads yet" when there are no threads at all OR when all threads are in projects */}
602+
{(Object.keys(threads).length === 0 || (Object.keys(threads).length > 0 && unFavoritedThreads.length === 0 && favoritedThreads.length === 0)) && !searchTerm && (
603+
<>
604+
<div className="px-3 mt-2 pb-2">
605+
<div className="flex items-center gap-1 text-left-panel-fg/80">
606+
<IconMessage size={18} />
607+
<h6 className="font-medium text-base">
608+
{t('common:noThreadsYet')}
609+
</h6>
610+
</div>
611+
<p className="text-left-panel-fg/60 mt-1 text-xs leading-relaxed">
612+
{t('common:noThreadsYetDesc')}
613+
</p>
614+
</div>
615+
</>
616+
)}
614617

615-
<div className="flex flex-col">
616-
<ThreadList threads={unFavoritedThreads} />
618+
<div className="flex flex-col px-2 pb-2">
619+
<ThreadList threads={unFavoritedThreads} />
620+
</div>
617621
</div>
618622
</div>
619623
</div>

0 commit comments

Comments
 (0)