From 543267516eb2766e6108752ff3101a882b6dec95 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Thu, 31 Oct 2024 15:39:07 +0530 Subject: [PATCH] Use geist icons and group history by ranges (#471) --- components/custom/app-sidebar.tsx | 38 ++-- components/custom/chat-header.tsx | 7 +- components/custom/icons.tsx | 102 +++++++---- components/custom/model-selector.tsx | 2 +- components/custom/sidebar-history.tsx | 239 ++++++++++++++++++++----- components/custom/sidebar-toggle.tsx | 20 ++- components/custom/sidebar-user-nav.tsx | 4 +- tailwind.config.ts | 1 - 8 files changed, 306 insertions(+), 107 deletions(-) diff --git a/components/custom/app-sidebar.tsx b/components/custom/app-sidebar.tsx index 43e4675..971fb75 100644 --- a/components/custom/app-sidebar.tsx +++ b/components/custom/app-sidebar.tsx @@ -1,10 +1,9 @@ 'use client'; -import { Plus } from 'lucide-react'; import Link from 'next/link'; import { type User } from 'next-auth'; -import { VercelIcon } from '@/components/custom/icons'; +import { PlusIcon, VercelIcon } from '@/components/custom/icons'; import { SidebarHistory } from '@/components/custom/sidebar-history'; import { SidebarUserNav } from '@/components/custom/sidebar-user-nav'; import { Button } from '@/components/ui/button'; @@ -23,9 +22,6 @@ import { SidebarGroupContent, SidebarHeader, SidebarMenu, - SidebarMenuAction, - SidebarMenuButton, - SidebarMenuItem, useSidebar, } from '@/components/ui/sidebar'; import { BetterTooltip } from '@/components/ui/tooltip'; @@ -37,31 +33,33 @@ export function AppSidebar({ user }: { user: User | undefined }) { - - - setOpenMobile(false)}> - - Chatbot - - - - - +
+ setOpenMobile(false)} + className="flex flex-row gap-3 items-center" + > + Chatbot + + + - +
- + + + - + +
diff --git a/components/custom/icons.tsx b/components/custom/icons.tsx index dbfa9e8..3d0626a 100644 --- a/components/custom/icons.tsx +++ b/components/custom/icons.tsx @@ -5,7 +5,7 @@ export const BotIcon = () => { strokeLinejoin="round" viewBox="0 0 16 16" width="16" - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width="16" - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width="16" - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width="16" - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { x="0px" y="0px" viewBox="0 0 92.2 65" - style={{ color: "currentcolor", fill: "currentcolor" }} + style={{ color: 'currentcolor', fill: 'currentcolor' }} width="18px" height="18px" > @@ -253,7 +253,7 @@ export const RouteIcon = ({ size = 16 }: { size?: number }) => { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > @@ -367,7 +367,7 @@ export const UploadIcon = ({ size = 16 }: { size?: number }) => { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { height={size} viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} className="-rotate-45" > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > { strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > ( strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > ( strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > ( strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > ( strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > ( strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > ( strokeLinejoin="round" viewBox="0 0 16 16" width={size} - style={{ color: "currentcolor" }} + style={{ color: 'currentcolor' }} > ( > ); + +export const SidebarLeftIcon = ({ size = 16 }: { size?: number }) => ( + + + +); + +export const PlusIcon = ({ size = 16 }: { size?: number }) => ( + + + +); diff --git a/components/custom/model-selector.tsx b/components/custom/model-selector.tsx index 17c3bca..d2bb3ff 100644 --- a/components/custom/model-selector.tsx +++ b/components/custom/model-selector.tsx @@ -34,7 +34,7 @@ export function ModelSelector({ svg]:!size-5 md:[&>svg]:!size-4', + 'px-2 w-fit data-[state=open]:bg-accent data-[state=open]:text-accent-foreground md:h-8 [&>svg]:!size-5 md:[&>svg]:!size-4', className )} > diff --git a/components/custom/sidebar-history.tsx b/components/custom/sidebar-history.tsx index 2e75834..ede893b 100644 --- a/components/custom/sidebar-history.tsx +++ b/components/custom/sidebar-history.tsx @@ -1,5 +1,6 @@ 'use client'; +import { isToday, isYesterday, subMonths, subWeeks } from 'date-fns'; import Link from 'next/link'; import { useParams, usePathname, useRouter } from 'next/navigation'; import { type User } from 'next-auth'; @@ -41,6 +42,54 @@ import { import { Chat } from '@/db/schema'; import { fetcher, getTitleFromChat } from '@/lib/utils'; +type GroupedChats = { + today: Chat[]; + yesterday: Chat[]; + lastWeek: Chat[]; + lastMonth: Chat[]; + older: Chat[]; +}; + +const ChatItem = ({ + chat, + isActive, + onDelete, + setOpenMobile, +}: { + chat: Chat; + isActive: boolean; + onDelete: (chatId: string) => void; + setOpenMobile: (open: boolean) => void; +}) => ( + + + setOpenMobile(false)}> + {getTitleFromChat(chat)} + + + + + + + More + + + + onDelete(chat.id)} + > + + Delete + + + + +); + export function SidebarHistory({ user }: { user: User | undefined }) { const { setOpenMobile } = useSidebar(); const { id } = useParams(); @@ -87,7 +136,9 @@ export function SidebarHistory({ user }: { user: User | undefined }) { if (!user) { return ( - History +
+ Today +
@@ -101,7 +152,9 @@ export function SidebarHistory({ user }: { user: User | undefined }) { if (isLoading) { return ( - History +
+ Today +
{[44, 32, 28, 64, 52].map((item) => ( @@ -128,13 +181,15 @@ export function SidebarHistory({ user }: { user: User | undefined }) { if (history?.length === 0) { return ( - History +
+ Today +
- No chats found + No previous chats @@ -143,48 +198,152 @@ export function SidebarHistory({ user }: { user: User | undefined }) { ); } + const groupChatsByDate = (chats: Chat[]): GroupedChats => { + const now = new Date(); + const oneWeekAgo = subWeeks(now, 1); + const oneMonthAgo = subMonths(now, 1); + + return chats.reduce( + (groups, chat) => { + const chatDate = new Date(chat.createdAt); + + if (isToday(chatDate)) { + groups.today.push(chat); + } else if (isYesterday(chatDate)) { + groups.yesterday.push(chat); + } else if (chatDate > oneWeekAgo) { + groups.lastWeek.push(chat); + } else if (chatDate > oneMonthAgo) { + groups.lastMonth.push(chat); + } else { + groups.older.push(chat); + } + + return groups; + }, + { + today: [], + yesterday: [], + lastWeek: [], + lastMonth: [], + older: [], + } as GroupedChats + ); + }; + return ( <> - History {history && - history.map((chat) => ( - - - setOpenMobile(false)} - > - {getTitleFromChat(chat)} - - - - - - - More - - - - { - setDeleteId(chat.id); - setShowDeleteDialog(true); - }} - > - - Delete - - - - - ))} + (() => { + const groupedChats = groupChatsByDate(history); + + return ( + <> + {groupedChats.today.length > 0 && ( + <> +
+ Today +
+ {groupedChats.today.map((chat) => ( + { + setDeleteId(chatId); + setShowDeleteDialog(true); + }} + setOpenMobile={setOpenMobile} + /> + ))} + + )} + + {groupedChats.yesterday.length > 0 && ( + <> +
+ Yesterday +
+ {groupedChats.yesterday.map((chat) => ( + { + setDeleteId(chatId); + setShowDeleteDialog(true); + }} + setOpenMobile={setOpenMobile} + /> + ))} + + )} + + {groupedChats.lastWeek.length > 0 && ( + <> +
+ Last 7 days +
+ {groupedChats.lastWeek.map((chat) => ( + { + setDeleteId(chatId); + setShowDeleteDialog(true); + }} + setOpenMobile={setOpenMobile} + /> + ))} + + )} + + {groupedChats.lastMonth.length > 0 && ( + <> +
+ Last 30 days +
+ {groupedChats.lastMonth.map((chat) => ( + { + setDeleteId(chatId); + setShowDeleteDialog(true); + }} + setOpenMobile={setOpenMobile} + /> + ))} + + )} + + {groupedChats.older.length > 0 && ( + <> +
+ Older +
+ {groupedChats.older.map((chat) => ( + { + setDeleteId(chatId); + setShowDeleteDialog(true); + }} + setOpenMobile={setOpenMobile} + /> + ))} + + )} + + ); + })()}
diff --git a/components/custom/sidebar-toggle.tsx b/components/custom/sidebar-toggle.tsx index 536c98f..6bf5b1c 100644 --- a/components/custom/sidebar-toggle.tsx +++ b/components/custom/sidebar-toggle.tsx @@ -1,20 +1,26 @@ import { ComponentProps } from 'react'; -import { SidebarTrigger } from '@/components/ui/sidebar'; +import { SidebarTrigger, useSidebar } from '@/components/ui/sidebar'; import { BetterTooltip } from '@/components/ui/tooltip'; import { cn } from '@/lib/utils'; +import { SidebarLeftIcon } from './icons'; +import { Button } from '../ui/button'; + export function SidebarToggle({ className, }: ComponentProps) { + const { toggleSidebar } = useSidebar(); + return ( - svg]:!size-5 md:[&>svg]:!size-4', - className - )} - /> + ); } diff --git a/components/custom/sidebar-user-nav.tsx b/components/custom/sidebar-user-nav.tsx index cfda981..8b1bd55 100644 --- a/components/custom/sidebar-user-nav.tsx +++ b/components/custom/sidebar-user-nav.tsx @@ -20,6 +20,7 @@ import { export function SidebarUserNav({ user }: { user: User }) { const { setTheme, theme } = useTheme(); + return ( @@ -42,6 +43,7 @@ export function SidebarUserNav({ user }: { user: User }) { className="w-[--radix-popper-anchor-width]" > setTheme(theme === 'dark' ? 'light' : 'dark')} > {`Toggle ${theme === 'light' ? 'dark' : 'light'} mode`} @@ -49,7 +51,7 @@ export function SidebarUserNav({ user }: { user: User }) {