File size: 2,617 Bytes
a8e1cb0
3ba9c0c
a8e1cb0
 
 
3ba9c0c
a8e1cb0
 
3ba9c0c
a8e1cb0
 
 
 
 
 
 
 
 
3ba9c0c
 
a8e1cb0
 
 
3ba9c0c
 
 
a8e1cb0
 
 
 
3ba9c0c
a8e1cb0
 
3ba9c0c
a8e1cb0
 
 
 
 
3ba9c0c
a8e1cb0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3ba9c0c
a8e1cb0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3ba9c0c
a8e1cb0
 
 
 
3ba9c0c
a8e1cb0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3ba9c0c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
'use client';

import * as React from 'react';
import { type DialogProps } from '@radix-ui/react-dialog';
import { toast } from 'react-hot-toast';

import { ServerActionResult, type Chat } from '@/lib/types';
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>
	);
}