Use geist icons and group history by ranges (#471)
This commit is contained in:
parent
dce1314084
commit
543267516e
8 changed files with 306 additions and 107 deletions
|
|
@ -1,10 +1,9 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Plus } from 'lucide-react';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { type User } from 'next-auth';
|
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 { SidebarHistory } from '@/components/custom/sidebar-history';
|
||||||
import { SidebarUserNav } from '@/components/custom/sidebar-user-nav';
|
import { SidebarUserNav } from '@/components/custom/sidebar-user-nav';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
|
|
@ -23,9 +22,6 @@ import {
|
||||||
SidebarGroupContent,
|
SidebarGroupContent,
|
||||||
SidebarHeader,
|
SidebarHeader,
|
||||||
SidebarMenu,
|
SidebarMenu,
|
||||||
SidebarMenuAction,
|
|
||||||
SidebarMenuButton,
|
|
||||||
SidebarMenuItem,
|
|
||||||
useSidebar,
|
useSidebar,
|
||||||
} from '@/components/ui/sidebar';
|
} from '@/components/ui/sidebar';
|
||||||
import { BetterTooltip } from '@/components/ui/tooltip';
|
import { BetterTooltip } from '@/components/ui/tooltip';
|
||||||
|
|
@ -37,31 +33,33 @@ export function AppSidebar({ user }: { user: User | undefined }) {
|
||||||
<Sidebar className="group-data-[side=left]:border-r-0">
|
<Sidebar className="group-data-[side=left]:border-r-0">
|
||||||
<SidebarHeader>
|
<SidebarHeader>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem>
|
<div className="flex flex-row justify-between items-center">
|
||||||
<SidebarMenuButton asChild>
|
<Link
|
||||||
<Link href="/" onClick={() => setOpenMobile(false)}>
|
href="/"
|
||||||
<span className="text-lg font-semibold font-mono tracking-tighter">
|
onClick={() => setOpenMobile(false)}
|
||||||
Chatbot
|
className="flex flex-row gap-3 items-center"
|
||||||
</span>
|
>
|
||||||
|
<span className="text-lg font-semibold px-2">Chatbot</span>
|
||||||
</Link>
|
</Link>
|
||||||
</SidebarMenuButton>
|
<BetterTooltip content="New Chat" align="start">
|
||||||
<BetterTooltip content="New Chat">
|
<Button variant="ghost" className="p-2 h-fit">
|
||||||
<SidebarMenuAction asChild>
|
|
||||||
<Link href="/" onClick={() => setOpenMobile(false)}>
|
<Link href="/" onClick={() => setOpenMobile(false)}>
|
||||||
<Plus />
|
<PlusIcon />
|
||||||
</Link>
|
</Link>
|
||||||
</SidebarMenuAction>
|
</Button>
|
||||||
</BetterTooltip>
|
</BetterTooltip>
|
||||||
</SidebarMenuItem>
|
</div>
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
</SidebarHeader>
|
</SidebarHeader>
|
||||||
<SidebarContent>
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
<SidebarHistory user={user} />
|
<SidebarHistory user={user} />
|
||||||
|
</SidebarGroup>
|
||||||
</SidebarContent>
|
</SidebarContent>
|
||||||
<SidebarFooter className="gap-0">
|
<SidebarFooter className="gap-0">
|
||||||
<SidebarGroup>
|
<SidebarGroup>
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<Card className="p-4 flex flex-col gap-4 relative rounded-md border-none shadow-none hover:shadow transition-shadow">
|
<Card className="p-4 flex flex-col gap-4 relative rounded-lg shadow-none border-none">
|
||||||
<a
|
<a
|
||||||
href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot&env=AUTH_SECRET,OPENAI_API_KEY&envDescription=Learn%20more%20about%20how%20to%20get%20the%20API%20Keys%20for%20the%20application&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot%2Fblob%2Fmain%2F.env.example&demo-title=AI%20Chatbot&demo-description=An%20Open-Source%20AI%20Chatbot%20Template%20Built%20With%20Next.js%20and%20the%20AI%20SDK%20by%20Vercel.&demo-url=https%3A%2F%2Fchat.vercel.ai&stores=[{%22type%22:%22postgres%22},{%22type%22:%22blob%22}]"
|
href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot&env=AUTH_SECRET,OPENAI_API_KEY&envDescription=Learn%20more%20about%20how%20to%20get%20the%20API%20Keys%20for%20the%20application&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fai-chatbot%2Fblob%2Fmain%2F.env.example&demo-title=AI%20Chatbot&demo-description=An%20Open-Source%20AI%20Chatbot%20Template%20Built%20With%20Next.js%20and%20the%20AI%20SDK%20by%20Vercel.&demo-url=https%3A%2F%2Fchat.vercel.ai&stores=[{%22type%22:%22postgres%22},{%22type%22:%22blob%22}]"
|
||||||
className="absolute inset-0 rounded-lg outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring"
|
className="absolute inset-0 rounded-lg outline-none focus-visible:ring-2 focus-visible:ring-sidebar-ring"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
import { Plus } from 'lucide-react';
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
import { ModelSelector } from '@/components/custom/model-selector';
|
import { ModelSelector } from '@/components/custom/model-selector';
|
||||||
|
|
@ -6,9 +5,11 @@ import { SidebarToggle } from '@/components/custom/sidebar-toggle';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { BetterTooltip } from '@/components/ui/tooltip';
|
import { BetterTooltip } from '@/components/ui/tooltip';
|
||||||
|
|
||||||
|
import { PlusIcon } from './icons';
|
||||||
|
|
||||||
export function ChatHeader({ selectedModelId }: { selectedModelId: string }) {
|
export function ChatHeader({ selectedModelId }: { selectedModelId: string }) {
|
||||||
return (
|
return (
|
||||||
<header className="flex h-16 sticky top-0 bg-background md:h-12 items-center px-2 md:px-2 z-10">
|
<header className="flex h-16 sticky top-0 bg-background md:h-12 items-center px-2 md:px-2 gap-2">
|
||||||
<SidebarToggle />
|
<SidebarToggle />
|
||||||
<BetterTooltip content="New Chat">
|
<BetterTooltip content="New Chat">
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -17,7 +18,7 @@ export function ChatHeader({ selectedModelId }: { selectedModelId: string }) {
|
||||||
asChild
|
asChild
|
||||||
>
|
>
|
||||||
<Link href="/">
|
<Link href="/">
|
||||||
<Plus />
|
<PlusIcon />
|
||||||
<span className="md:sr-only">New Chat</span>
|
<span className="md:sr-only">New Chat</span>
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export const BotIcon = () => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width="16"
|
width="16"
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -25,7 +25,7 @@ export const UserIcon = () => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width="16"
|
width="16"
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -44,7 +44,7 @@ export const AttachmentIcon = () => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width="16"
|
width="16"
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -63,7 +63,7 @@ export const VercelIcon = ({ size = 17 }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -82,7 +82,7 @@ export const GitIcon = () => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width="16"
|
width="16"
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<g clipPath="url(#clip0_872_3147)">
|
<g clipPath="url(#clip0_872_3147)">
|
||||||
<path
|
<path
|
||||||
|
|
@ -108,7 +108,7 @@ export const BoxIcon = ({ size = 16 }: { size: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -127,7 +127,7 @@ export const HomeIcon = ({ size = 16 }: { size: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -146,7 +146,7 @@ export const GPSIcon = ({ size = 16 }: { size: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
d="M1 6L15 1L10 15L7.65955 8.91482C7.55797 8.65073 7.34927 8.44203 7.08518 8.34045L1 6Z"
|
d="M1 6L15 1L10 15L7.65955 8.91482C7.55797 8.65073 7.34927 8.44203 7.08518 8.34045L1 6Z"
|
||||||
|
|
@ -167,7 +167,7 @@ export const InvoiceIcon = ({ size = 16 }: { size: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -186,7 +186,7 @@ export const LogoOpenAI = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
d="M14.9449 6.54871C15.3128 5.45919 15.1861 4.26567 14.5978 3.27464C13.7131 1.75461 11.9345 0.972595 10.1974 1.3406C9.42464 0.481584 8.3144 -0.00692594 7.15045 7.42132e-05C5.37487 -0.00392587 3.79946 1.1241 3.2532 2.79113C2.11256 3.02164 1.12799 3.72615 0.551837 4.72468C-0.339497 6.24071 -0.1363 8.15175 1.05451 9.45178C0.686626 10.5413 0.813308 11.7348 1.40162 12.7258C2.28637 14.2459 4.06498 15.0279 5.80204 14.6599C6.5743 15.5189 7.68504 16.0074 8.849 15.9999C10.6256 16.0044 12.2015 14.8754 12.7478 13.2069C13.8884 12.9764 14.873 12.2718 15.4491 11.2733C16.3394 9.75728 16.1357 7.84774 14.9454 6.54771L14.9449 6.54871ZM8.85001 14.9544C8.13907 14.9554 7.45043 14.7099 6.90468 14.2604C6.92951 14.2474 6.97259 14.2239 7.00046 14.2069L10.2293 12.3668C10.3945 12.2743 10.4959 12.1008 10.4949 11.9133V7.42173L11.8595 8.19925C11.8742 8.20625 11.8838 8.22025 11.8858 8.23625V11.9558C11.8838 13.6099 10.5263 14.9509 8.85001 14.9544ZM2.32133 12.2028C1.9651 11.5958 1.8369 10.8843 1.95902 10.1938C1.98284 10.2078 2.02489 10.2333 2.05479 10.2503L5.28366 12.0903C5.44733 12.1848 5.65003 12.1848 5.81421 12.0903L9.75604 9.84429V11.3993C9.75705 11.4153 9.74945 11.4308 9.73678 11.4408L6.47295 13.3004C5.01915 14.1264 3.1625 13.6354 2.32184 12.2028H2.32133ZM1.47155 5.24819C1.82626 4.64017 2.38619 4.17516 3.05305 3.93366C3.05305 3.96116 3.05152 4.00966 3.05152 4.04366V7.72424C3.05051 7.91124 3.15186 8.08475 3.31654 8.17725L7.25838 10.4228L5.89376 11.2003C5.88008 11.2093 5.86285 11.2108 5.84765 11.2043L2.58331 9.34327C1.13255 8.51426 0.63494 6.68272 1.47104 5.24869L1.47155 5.24819ZM12.6834 7.82274L8.74157 5.57669L10.1062 4.79968C10.1199 4.79068 10.1371 4.78918 10.1523 4.79568L13.4166 6.65522C14.8699 7.48373 15.3681 9.31827 14.5284 10.7523C14.1732 11.3593 13.6138 11.8243 12.9474 12.0663V8.27575C12.9489 8.08875 12.8481 7.91574 12.6839 7.82274H12.6834ZM14.0414 5.8057C14.0176 5.7912 13.9756 5.7662 13.9457 5.7492L10.7168 3.90916C10.5531 3.81466 10.3504 3.81466 10.1863 3.90916L6.24442 6.15521V4.60017C6.2434 4.58417 6.251 4.56867 6.26367 4.55867L9.52751 2.70063C10.9813 1.87311 12.84 2.36563 13.6781 3.80066C14.0323 4.40667 14.1605 5.11618 14.0404 5.8057H14.0414ZM5.50257 8.57726L4.13744 7.79974C4.12275 7.79274 4.11312 7.77874 4.11109 7.76274V4.04316C4.11211 2.38713 5.47368 1.0451 7.15197 1.0461C7.86189 1.0461 8.54902 1.2921 9.09476 1.74011C9.06993 1.75311 9.02737 1.77661 8.99899 1.79361L5.77012 3.63365C5.60493 3.72615 5.50358 3.89916 5.50459 4.08666L5.50257 8.57626V8.57726ZM6.24391 7.00022L7.99972 5.9997L9.75553 6.99972V9.00027L7.99972 10.0003L6.24391 9.00027V7.00022Z"
|
d="M14.9449 6.54871C15.3128 5.45919 15.1861 4.26567 14.5978 3.27464C13.7131 1.75461 11.9345 0.972595 10.1974 1.3406C9.42464 0.481584 8.3144 -0.00692594 7.15045 7.42132e-05C5.37487 -0.00392587 3.79946 1.1241 3.2532 2.79113C2.11256 3.02164 1.12799 3.72615 0.551837 4.72468C-0.339497 6.24071 -0.1363 8.15175 1.05451 9.45178C0.686626 10.5413 0.813308 11.7348 1.40162 12.7258C2.28637 14.2459 4.06498 15.0279 5.80204 14.6599C6.5743 15.5189 7.68504 16.0074 8.849 15.9999C10.6256 16.0044 12.2015 14.8754 12.7478 13.2069C13.8884 12.9764 14.873 12.2718 15.4491 11.2733C16.3394 9.75728 16.1357 7.84774 14.9454 6.54771L14.9449 6.54871ZM8.85001 14.9544C8.13907 14.9554 7.45043 14.7099 6.90468 14.2604C6.92951 14.2474 6.97259 14.2239 7.00046 14.2069L10.2293 12.3668C10.3945 12.2743 10.4959 12.1008 10.4949 11.9133V7.42173L11.8595 8.19925C11.8742 8.20625 11.8838 8.22025 11.8858 8.23625V11.9558C11.8838 13.6099 10.5263 14.9509 8.85001 14.9544ZM2.32133 12.2028C1.9651 11.5958 1.8369 10.8843 1.95902 10.1938C1.98284 10.2078 2.02489 10.2333 2.05479 10.2503L5.28366 12.0903C5.44733 12.1848 5.65003 12.1848 5.81421 12.0903L9.75604 9.84429V11.3993C9.75705 11.4153 9.74945 11.4308 9.73678 11.4408L6.47295 13.3004C5.01915 14.1264 3.1625 13.6354 2.32184 12.2028H2.32133ZM1.47155 5.24819C1.82626 4.64017 2.38619 4.17516 3.05305 3.93366C3.05305 3.96116 3.05152 4.00966 3.05152 4.04366V7.72424C3.05051 7.91124 3.15186 8.08475 3.31654 8.17725L7.25838 10.4228L5.89376 11.2003C5.88008 11.2093 5.86285 11.2108 5.84765 11.2043L2.58331 9.34327C1.13255 8.51426 0.63494 6.68272 1.47104 5.24869L1.47155 5.24819ZM12.6834 7.82274L8.74157 5.57669L10.1062 4.79968C10.1199 4.79068 10.1371 4.78918 10.1523 4.79568L13.4166 6.65522C14.8699 7.48373 15.3681 9.31827 14.5284 10.7523C14.1732 11.3593 13.6138 11.8243 12.9474 12.0663V8.27575C12.9489 8.08875 12.8481 7.91574 12.6839 7.82274H12.6834ZM14.0414 5.8057C14.0176 5.7912 13.9756 5.7662 13.9457 5.7492L10.7168 3.90916C10.5531 3.81466 10.3504 3.81466 10.1863 3.90916L6.24442 6.15521V4.60017C6.2434 4.58417 6.251 4.56867 6.26367 4.55867L9.52751 2.70063C10.9813 1.87311 12.84 2.36563 13.6781 3.80066C14.0323 4.40667 14.1605 5.11618 14.0404 5.8057H14.0414ZM5.50257 8.57726L4.13744 7.79974C4.12275 7.79274 4.11312 7.77874 4.11109 7.76274V4.04316C4.11211 2.38713 5.47368 1.0451 7.15197 1.0461C7.86189 1.0461 8.54902 1.2921 9.09476 1.74011C9.06993 1.75311 9.02737 1.77661 8.99899 1.79361L5.77012 3.63365C5.60493 3.72615 5.50358 3.89916 5.50459 4.08666L5.50257 8.57626V8.57726ZM6.24391 7.00022L7.99972 5.9997L9.75553 6.99972V9.00027L7.99972 10.0003L6.24391 9.00027V7.00022Z"
|
||||||
|
|
@ -204,7 +204,7 @@ export const LogoGoogle = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
d="M8.15991 6.54543V9.64362H12.4654C12.2763 10.64 11.709 11.4837 10.8581 12.0509L13.4544 14.0655C14.9671 12.6692 15.8399 10.6182 15.8399 8.18188C15.8399 7.61461 15.789 7.06911 15.6944 6.54552L8.15991 6.54543Z"
|
d="M8.15991 6.54543V9.64362H12.4654C12.2763 10.64 11.709 11.4837 10.8581 12.0509L13.4544 14.0655C14.9671 12.6692 15.8399 10.6182 15.8399 8.18188C15.8399 7.61461 15.789 7.06911 15.6944 6.54552L8.15991 6.54543Z"
|
||||||
|
|
@ -234,7 +234,7 @@ export const LogoAnthropic = () => {
|
||||||
x="0px"
|
x="0px"
|
||||||
y="0px"
|
y="0px"
|
||||||
viewBox="0 0 92.2 65"
|
viewBox="0 0 92.2 65"
|
||||||
style={{ color: "currentcolor", fill: "currentcolor" }}
|
style={{ color: 'currentcolor', fill: 'currentcolor' }}
|
||||||
width="18px"
|
width="18px"
|
||||||
height="18px"
|
height="18px"
|
||||||
>
|
>
|
||||||
|
|
@ -253,7 +253,7 @@ export const RouteIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -272,7 +272,7 @@ export const FileIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -291,7 +291,7 @@ export const LoaderIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<g clipPath="url(#clip0_2393_1490)">
|
<g clipPath="url(#clip0_2393_1490)">
|
||||||
<path d="M8 0V4" stroke="currentColor" strokeWidth="1.5"></path>
|
<path d="M8 0V4" stroke="currentColor" strokeWidth="1.5"></path>
|
||||||
|
|
@ -367,7 +367,7 @@ export const UploadIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -386,7 +386,7 @@ export const MenuIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -405,7 +405,7 @@ export const PencilEditIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -424,7 +424,7 @@ export const CheckedSquare = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -443,7 +443,7 @@ export const UncheckedSquare = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<rect
|
<rect
|
||||||
x="1"
|
x="1"
|
||||||
|
|
@ -465,7 +465,7 @@ export const MoreIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -484,7 +484,7 @@ export const TrashIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -503,7 +503,7 @@ export const InfoIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -522,7 +522,7 @@ export const ArrowUpIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -540,7 +540,7 @@ export const StopIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
height={size}
|
height={size}
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -559,7 +559,7 @@ export const PaperclipIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
className="-rotate-45"
|
className="-rotate-45"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
|
|
@ -579,7 +579,7 @@ export const MoreHorizontalIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -598,7 +598,7 @@ export const MessageIcon = ({ size = 16 }: { size?: number }) => {
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -616,7 +616,7 @@ export const CrossIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -633,7 +633,7 @@ export const UndoIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -650,7 +650,7 @@ export const RedoIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -667,7 +667,7 @@ export const DeltaIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -684,7 +684,7 @@ export const PenIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -701,7 +701,7 @@ export const SummarizeIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
width={size}
|
width={size}
|
||||||
style={{ color: "currentcolor" }}
|
style={{ color: 'currentcolor' }}
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
|
|
@ -711,3 +711,37 @@ export const SummarizeIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const SidebarLeftIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
|
<svg
|
||||||
|
height={size}
|
||||||
|
strokeLinejoin="round"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width={size}
|
||||||
|
style={{ color: 'currentcolor' }}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M6.245 2.5H14.5V12.5C14.5 13.0523 14.0523 13.5 13.5 13.5H6.245V2.5ZM4.995 2.5H1.5V12.5C1.5 13.0523 1.94772 13.5 2.5 13.5H4.995V2.5ZM0 1H1.5H14.5H16V2.5V12.5C16 13.8807 14.8807 15 13.5 15H2.5C1.11929 15 0 13.8807 0 12.5V2.5V1Z"
|
||||||
|
fill="currentColor"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const PlusIcon = ({ size = 16 }: { size?: number }) => (
|
||||||
|
<svg
|
||||||
|
height={size}
|
||||||
|
strokeLinejoin="round"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
width={size}
|
||||||
|
style={{ color: 'currentcolor' }}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M8.75 1.75V1H7.25V1.75V6.75H2.25H1.5V8.25H2.25H7.25V13.25V14H8.75V13.25V8.25H13.75H14.5V6.75H13.75H8.75V1.75Z"
|
||||||
|
fill="currentColor"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export function ModelSelector({
|
||||||
<DropdownMenuTrigger
|
<DropdownMenuTrigger
|
||||||
asChild
|
asChild
|
||||||
className={cn(
|
className={cn(
|
||||||
'w-fit data-[state=open]:bg-accent data-[state=open]:text-accent-foreground md:h-8 [&>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
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import { isToday, isYesterday, subMonths, subWeeks } from 'date-fns';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useParams, usePathname, useRouter } from 'next/navigation';
|
import { useParams, usePathname, useRouter } from 'next/navigation';
|
||||||
import { type User } from 'next-auth';
|
import { type User } from 'next-auth';
|
||||||
|
|
@ -41,6 +42,54 @@ import {
|
||||||
import { Chat } from '@/db/schema';
|
import { Chat } from '@/db/schema';
|
||||||
import { fetcher, getTitleFromChat } from '@/lib/utils';
|
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;
|
||||||
|
}) => (
|
||||||
|
<SidebarMenuItem>
|
||||||
|
<SidebarMenuButton asChild isActive={isActive}>
|
||||||
|
<Link href={`/chat/${chat.id}`} onClick={() => setOpenMobile(false)}>
|
||||||
|
<span>{getTitleFromChat(chat)}</span>
|
||||||
|
</Link>
|
||||||
|
</SidebarMenuButton>
|
||||||
|
<DropdownMenu modal={true}>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<SidebarMenuAction
|
||||||
|
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground mr-0.5"
|
||||||
|
showOnHover={!isActive}
|
||||||
|
>
|
||||||
|
<MoreHorizontalIcon />
|
||||||
|
<span className="sr-only">More</span>
|
||||||
|
</SidebarMenuAction>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent side="bottom" align="end">
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="cursor-pointer text-destructive focus:bg-destructive/15 focus:text-destructive dark:text-red-500"
|
||||||
|
onSelect={() => onDelete(chat.id)}
|
||||||
|
>
|
||||||
|
<TrashIcon />
|
||||||
|
<span>Delete</span>
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
</SidebarMenuItem>
|
||||||
|
);
|
||||||
|
|
||||||
export function SidebarHistory({ user }: { user: User | undefined }) {
|
export function SidebarHistory({ user }: { user: User | undefined }) {
|
||||||
const { setOpenMobile } = useSidebar();
|
const { setOpenMobile } = useSidebar();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
|
@ -87,7 +136,9 @@ export function SidebarHistory({ user }: { user: User | undefined }) {
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return (
|
return (
|
||||||
<SidebarGroup>
|
<SidebarGroup>
|
||||||
<SidebarGroupLabel>History</SidebarGroupLabel>
|
<div className="px-2 py-1 text-xs text-sidebar-foreground/50">
|
||||||
|
Today
|
||||||
|
</div>
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<div className="text-zinc-500 h-dvh w-full flex flex-row justify-center items-center text-sm gap-2">
|
<div className="text-zinc-500 h-dvh w-full flex flex-row justify-center items-center text-sm gap-2">
|
||||||
<InfoIcon />
|
<InfoIcon />
|
||||||
|
|
@ -101,7 +152,9 @@ export function SidebarHistory({ user }: { user: User | undefined }) {
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<SidebarGroup>
|
<SidebarGroup>
|
||||||
<SidebarGroupLabel>History</SidebarGroupLabel>
|
<div className="px-2 py-1 text-xs text-sidebar-foreground/50">
|
||||||
|
Today
|
||||||
|
</div>
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
{[44, 32, 28, 64, 52].map((item) => (
|
{[44, 32, 28, 64, 52].map((item) => (
|
||||||
|
|
@ -128,13 +181,15 @@ export function SidebarHistory({ user }: { user: User | undefined }) {
|
||||||
if (history?.length === 0) {
|
if (history?.length === 0) {
|
||||||
return (
|
return (
|
||||||
<SidebarGroup>
|
<SidebarGroup>
|
||||||
<SidebarGroupLabel>History</SidebarGroupLabel>
|
<div className="px-2 py-1 text-xs text-sidebar-foreground/50">
|
||||||
|
Today
|
||||||
|
</div>
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
<SidebarMenuButton>
|
<SidebarMenuButton>
|
||||||
<InfoIcon />
|
<InfoIcon />
|
||||||
<span>No chats found</span>
|
<span>No previous chats</span>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
|
|
@ -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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<SidebarGroup>
|
<SidebarGroup>
|
||||||
<SidebarGroupLabel>History</SidebarGroupLabel>
|
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
{history &&
|
{history &&
|
||||||
history.map((chat) => (
|
(() => {
|
||||||
<SidebarMenuItem key={chat.id}>
|
const groupedChats = groupChatsByDate(history);
|
||||||
<SidebarMenuButton asChild isActive={chat.id === id}>
|
|
||||||
<Link
|
return (
|
||||||
href={`/chat/${chat.id}`}
|
<>
|
||||||
onClick={() => setOpenMobile(false)}
|
{groupedChats.today.length > 0 && (
|
||||||
>
|
<>
|
||||||
<span>{getTitleFromChat(chat)}</span>
|
<div className="px-2 py-1 text-xs text-sidebar-foreground/50">
|
||||||
</Link>
|
Today
|
||||||
</SidebarMenuButton>
|
</div>
|
||||||
<DropdownMenu modal={true}>
|
{groupedChats.today.map((chat) => (
|
||||||
<DropdownMenuTrigger asChild>
|
<ChatItem
|
||||||
<SidebarMenuAction
|
key={chat.id}
|
||||||
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
|
chat={chat}
|
||||||
showOnHover={chat.id !== id}
|
isActive={chat.id === id}
|
||||||
>
|
onDelete={(chatId) => {
|
||||||
<MoreHorizontalIcon />
|
setDeleteId(chatId);
|
||||||
<span className="sr-only">More</span>
|
|
||||||
</SidebarMenuAction>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent side="bottom" align="end">
|
|
||||||
<DropdownMenuItem
|
|
||||||
className="text-destructive focus:bg-destructive/15 focus:text-destructive"
|
|
||||||
onSelect={() => {
|
|
||||||
setDeleteId(chat.id);
|
|
||||||
setShowDeleteDialog(true);
|
setShowDeleteDialog(true);
|
||||||
}}
|
}}
|
||||||
>
|
setOpenMobile={setOpenMobile}
|
||||||
<TrashIcon />
|
/>
|
||||||
<span>Delete</span>
|
|
||||||
</DropdownMenuItem>
|
|
||||||
</DropdownMenuContent>
|
|
||||||
</DropdownMenu>
|
|
||||||
</SidebarMenuItem>
|
|
||||||
))}
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{groupedChats.yesterday.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div className="px-2 py-1 text-xs text-sidebar-foreground/50 mt-6">
|
||||||
|
Yesterday
|
||||||
|
</div>
|
||||||
|
{groupedChats.yesterday.map((chat) => (
|
||||||
|
<ChatItem
|
||||||
|
key={chat.id}
|
||||||
|
chat={chat}
|
||||||
|
isActive={chat.id === id}
|
||||||
|
onDelete={(chatId) => {
|
||||||
|
setDeleteId(chatId);
|
||||||
|
setShowDeleteDialog(true);
|
||||||
|
}}
|
||||||
|
setOpenMobile={setOpenMobile}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{groupedChats.lastWeek.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div className="px-2 py-1 text-xs text-sidebar-foreground/50 mt-6">
|
||||||
|
Last 7 days
|
||||||
|
</div>
|
||||||
|
{groupedChats.lastWeek.map((chat) => (
|
||||||
|
<ChatItem
|
||||||
|
key={chat.id}
|
||||||
|
chat={chat}
|
||||||
|
isActive={chat.id === id}
|
||||||
|
onDelete={(chatId) => {
|
||||||
|
setDeleteId(chatId);
|
||||||
|
setShowDeleteDialog(true);
|
||||||
|
}}
|
||||||
|
setOpenMobile={setOpenMobile}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{groupedChats.lastMonth.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div className="px-2 py-1 text-xs text-sidebar-foreground/50 mt-6">
|
||||||
|
Last 30 days
|
||||||
|
</div>
|
||||||
|
{groupedChats.lastMonth.map((chat) => (
|
||||||
|
<ChatItem
|
||||||
|
key={chat.id}
|
||||||
|
chat={chat}
|
||||||
|
isActive={chat.id === id}
|
||||||
|
onDelete={(chatId) => {
|
||||||
|
setDeleteId(chatId);
|
||||||
|
setShowDeleteDialog(true);
|
||||||
|
}}
|
||||||
|
setOpenMobile={setOpenMobile}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{groupedChats.older.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div className="px-2 py-1 text-xs text-sidebar-foreground/50 mt-6">
|
||||||
|
Older
|
||||||
|
</div>
|
||||||
|
{groupedChats.older.map((chat) => (
|
||||||
|
<ChatItem
|
||||||
|
key={chat.id}
|
||||||
|
chat={chat}
|
||||||
|
isActive={chat.id === id}
|
||||||
|
onDelete={(chatId) => {
|
||||||
|
setDeleteId(chatId);
|
||||||
|
setShowDeleteDialog(true);
|
||||||
|
}}
|
||||||
|
setOpenMobile={setOpenMobile}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
</SidebarGroupContent>
|
</SidebarGroupContent>
|
||||||
</SidebarGroup>
|
</SidebarGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,26 @@
|
||||||
import { ComponentProps } from 'react';
|
import { ComponentProps } from 'react';
|
||||||
|
|
||||||
import { SidebarTrigger } from '@/components/ui/sidebar';
|
import { SidebarTrigger, useSidebar } from '@/components/ui/sidebar';
|
||||||
import { BetterTooltip } from '@/components/ui/tooltip';
|
import { BetterTooltip } from '@/components/ui/tooltip';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
import { SidebarLeftIcon } from './icons';
|
||||||
|
import { Button } from '../ui/button';
|
||||||
|
|
||||||
export function SidebarToggle({
|
export function SidebarToggle({
|
||||||
className,
|
className,
|
||||||
}: ComponentProps<typeof SidebarTrigger>) {
|
}: ComponentProps<typeof SidebarTrigger>) {
|
||||||
|
const { toggleSidebar } = useSidebar();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BetterTooltip content="Toggle Sidebar" align="start">
|
<BetterTooltip content="Toggle Sidebar" align="start">
|
||||||
<SidebarTrigger
|
<Button
|
||||||
className={cn(
|
onClick={toggleSidebar}
|
||||||
'size-10 md:size-8 [&>svg]:!size-5 md:[&>svg]:!size-4',
|
variant="ghost"
|
||||||
className
|
className="md:px-2 md:h-fit"
|
||||||
)}
|
>
|
||||||
/>
|
<SidebarLeftIcon />
|
||||||
|
</Button>
|
||||||
</BetterTooltip>
|
</BetterTooltip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import {
|
||||||
|
|
||||||
export function SidebarUserNav({ user }: { user: User }) {
|
export function SidebarUserNav({ user }: { user: User }) {
|
||||||
const { setTheme, theme } = useTheme();
|
const { setTheme, theme } = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
<SidebarMenuItem>
|
<SidebarMenuItem>
|
||||||
|
|
@ -42,6 +43,7 @@ export function SidebarUserNav({ user }: { user: User }) {
|
||||||
className="w-[--radix-popper-anchor-width]"
|
className="w-[--radix-popper-anchor-width]"
|
||||||
>
|
>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
|
className="cursor-pointer"
|
||||||
onSelect={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
|
onSelect={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
|
||||||
>
|
>
|
||||||
{`Toggle ${theme === 'light' ? 'dark' : 'light'} mode`}
|
{`Toggle ${theme === 'light' ? 'dark' : 'light'} mode`}
|
||||||
|
|
@ -49,7 +51,7 @@ export function SidebarUserNav({ user }: { user: User }) {
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem asChild>
|
<DropdownMenuItem asChild>
|
||||||
<button
|
<button
|
||||||
className="w-full "
|
className="w-full cursor-pointer"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
signOut({
|
signOut({
|
||||||
redirectTo: '/',
|
redirectTo: '/',
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,5 @@ const config: Config = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')],
|
plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')],
|
||||||
safelist: ['w-32', 'w-44', 'w-52'],
|
|
||||||
};
|
};
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue