Improve sidebar, new chat, and share dialog (#190)
This commit is contained in:
parent
35e83dc87e
commit
be90a40427
23 changed files with 598 additions and 217 deletions
109
components/chat-share-dialog.tsx
Normal file
109
components/chat-share-dialog.tsx
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
'use client'
|
||||
|
||||
import * as React from 'react'
|
||||
import Link from 'next/link'
|
||||
import { type DialogProps } from '@radix-ui/react-dialog'
|
||||
import { toast } from 'react-hot-toast'
|
||||
|
||||
import { ServerActionResult, type Chat } from '@/lib/types'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { badgeVariants } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle
|
||||
} from '@/components/ui/dialog'
|
||||
import { IconSpinner } from '@/components/ui/icons'
|
||||
import { useCopyToClipboard } from '@/lib/hooks/use-copy-to-clipboard'
|
||||
|
||||
interface ChatShareDialogProps extends DialogProps {
|
||||
chat: Pick<Chat, 'id' | 'title' | 'messages'>
|
||||
shareChat: (id: string) => ServerActionResult<Chat>
|
||||
onCopy: () => void
|
||||
}
|
||||
|
||||
export function ChatShareDialog({
|
||||
chat,
|
||||
shareChat,
|
||||
onCopy,
|
||||
...props
|
||||
}: ChatShareDialogProps) {
|
||||
const { copyToClipboard } = useCopyToClipboard({ timeout: 1000 })
|
||||
const [isSharePending, startShareTransition] = React.useTransition()
|
||||
|
||||
const copyShareLink = React.useCallback(
|
||||
async (chat: Chat) => {
|
||||
if (!chat.sharePath) {
|
||||
return toast.error('Could not copy share link to clipboard')
|
||||
}
|
||||
|
||||
const url = new URL(window.location.href)
|
||||
url.pathname = chat.sharePath
|
||||
copyToClipboard(url.toString())
|
||||
onCopy()
|
||||
toast.success('Share link copied to clipboard', {
|
||||
style: {
|
||||
borderRadius: '10px',
|
||||
background: '#333',
|
||||
color: '#fff',
|
||||
fontSize: '14px'
|
||||
},
|
||||
iconTheme: {
|
||||
primary: 'white',
|
||||
secondary: 'black'
|
||||
}
|
||||
})
|
||||
},
|
||||
[copyToClipboard, onCopy]
|
||||
)
|
||||
|
||||
return (
|
||||
<Dialog {...props}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Share link to chat</DialogTitle>
|
||||
<DialogDescription>
|
||||
Anyone with the URL will be able to view the shared chat.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="p-4 space-y-1 text-sm border rounded-md">
|
||||
<div className="font-medium">{chat.title}</div>
|
||||
<div className="text-muted-foreground">
|
||||
{chat.messages.length} messages
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter className="items-center">
|
||||
<Button
|
||||
disabled={isSharePending}
|
||||
onClick={() => {
|
||||
// @ts-ignore
|
||||
startShareTransition(async () => {
|
||||
const result = await shareChat(chat.id)
|
||||
|
||||
if (result && 'error' in result) {
|
||||
toast.error(result.error)
|
||||
return
|
||||
}
|
||||
|
||||
copyShareLink(result)
|
||||
})
|
||||
}}
|
||||
>
|
||||
{isSharePending ? (
|
||||
<>
|
||||
<IconSpinner className="mr-2 animate-spin" />
|
||||
Copying...
|
||||
</>
|
||||
) : (
|
||||
<>Copy link</>
|
||||
)}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue