'use client';
import { useChat } from '@ai-sdk/react';
import { DefaultChatTransport } from 'ai';
import { useState, useRef } from 'react';
import Image from 'next/image';
export default function Chat() {
const [files, setFiles] = useState<FileList | undefined>();
const fileInputRef = useRef<HTMLInputElement>(null);
const { messages, input, handleInputChange, sendMessage } = useChat({
transport: new DefaultChatTransport({ api: '/api/chat' }),
});
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const fileParts = files
? await convertFilesToDataURLs(files)
: [];
sendMessage({
role: 'user',
parts: [{ type: 'text', text: input }, ...fileParts],
});
setFiles(undefined);
if (fileInputRef.current) fileInputRef.current.value = '';
};
return (
<div>
{messages.map(m => (
<div key={m.id}>
{m.role}:
{m.parts.map((part, i) => {
if (part.type === 'text') return <span key={i}>{part.text}</span>;
if (part.type === 'file' && part.mediaType?.startsWith('image/'))
return <Image key={i} src={part.url} width={300} height={300} alt="" />;
})}
</div>
))}
<form onSubmit={handleSubmit}>
<input
type="file"
accept="image/*"
onChange={e => setFiles(e.target.files || undefined)}
ref={fileInputRef}
/>
<input
value={input}
onChange={handleInputChange}
placeholder="Say something..."
/>
<button type="submit">Send</button>
</form>
</div>
);
}
async function convertFilesToDataURLs(files: FileList) {
return Promise.all(
Array.from(files).map(
file =>
new Promise<{ type: 'file'; mediaType: string; url: string }>(
(resolve, reject) => {
const reader = new FileReader();
reader.onload = () =>
resolve({
type: 'file',
mediaType: file.type,
url: reader.result as string,
});
reader.onerror = reject;
reader.readAsDataURL(file);
},
),
),
);
}