Template
119 lines
3.4 KiB
TypeScript
119 lines
3.4 KiB
TypeScript
'use client';
|
|
|
|
import type { ChatStatus } from 'ai';
|
|
import { ChatInput, type PromptInputMessage } from './ChatInput';
|
|
import { Suggestion } from '@/components/ai-elements/suggestion';
|
|
import { RiOpenaiLine } from '@remixicon/react';
|
|
import { Shimmer } from '@/components/ai-elements/shimmer';
|
|
|
|
export interface PromptSuggestion {
|
|
key: string;
|
|
value: string;
|
|
}
|
|
|
|
interface ChatPromptProps {
|
|
value: string;
|
|
onChange: (value: string) => void;
|
|
onSubmit: (message: PromptInputMessage) => void;
|
|
status?: ChatStatus;
|
|
suggestions?: PromptSuggestion[];
|
|
webSearchEnabled?: boolean;
|
|
}
|
|
|
|
const defaultSuggestions: PromptSuggestion[] = [
|
|
{
|
|
key: 'Latest AI news',
|
|
value:
|
|
'What are the latest developments in AI in 2026? Search for recent news.',
|
|
},
|
|
{
|
|
key: 'Research a company',
|
|
value: 'Research OpenAI: their latest products, funding, and news.',
|
|
},
|
|
{
|
|
key: 'Fact check',
|
|
value:
|
|
'What is the current population of the world and how is it changing?',
|
|
},
|
|
{
|
|
key: 'Compare topics',
|
|
value:
|
|
'Compare the latest iPhone vs Samsung Galaxy flagship models with sources.',
|
|
},
|
|
];
|
|
|
|
const offlineSuggestions: PromptSuggestion[] = [
|
|
{
|
|
key: 'Explain a concept',
|
|
value: 'Explain retrieval-augmented generation in plain language.',
|
|
},
|
|
{
|
|
key: 'Compare approaches',
|
|
value: 'Compare REST and GraphQL, including when to choose each.',
|
|
},
|
|
{
|
|
key: 'Draft an outline',
|
|
value: 'Draft an outline for a practical guide to evaluating AI agents.',
|
|
},
|
|
{
|
|
key: 'Brainstorm ideas',
|
|
value: 'Brainstorm useful AI agent ideas for a small business.',
|
|
},
|
|
];
|
|
|
|
export function ChatPrompt({
|
|
value,
|
|
onChange,
|
|
onSubmit,
|
|
status = 'ready',
|
|
suggestions,
|
|
webSearchEnabled = false,
|
|
}: ChatPromptProps) {
|
|
const displayedSuggestions =
|
|
suggestions ?? (webSearchEnabled ? defaultSuggestions : offlineSuggestions);
|
|
|
|
const handleSuggestionClick = (suggestion: string) => {
|
|
onChange(suggestion);
|
|
};
|
|
|
|
return (
|
|
<div className="flex h-screen flex-col items-center justify-center gap-6 bg-muted p-4">
|
|
<div className="space-y-3 text-center">
|
|
<div className="flex items-center justify-center gap-2 text-primary">
|
|
<div className="flex items-center justify-center size-12 rounded-xl bg-black">
|
|
<RiOpenaiLine className="size-6 text-white animate-pulse" />
|
|
</div>
|
|
</div>
|
|
<Shimmer as="h1" className="text-3xl font-bold tracking-tight">
|
|
ChatGPT Agent
|
|
</Shimmer>
|
|
<p className="text-muted-foreground max-w-md mx-auto">
|
|
{webSearchEnabled
|
|
? "Ask anything — I'll search the web in real time to find accurate, up-to-date answers with sources."
|
|
: 'Ask anything — I can help research, explain, compare, and summarize.'}
|
|
</p>
|
|
</div>
|
|
|
|
<div className="w-full max-w-2xl">
|
|
<ChatInput
|
|
value={value}
|
|
onChange={onChange}
|
|
onSubmit={onSubmit}
|
|
status={status}
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex flex-wrap justify-center gap-2">
|
|
{displayedSuggestions.map((suggestion) => (
|
|
<Suggestion
|
|
key={suggestion.key}
|
|
className="bg-background text-foreground dark:bg-background dark:text-foreground"
|
|
suggestion={suggestion.key}
|
|
onClick={() => handleSuggestionClick(suggestion.value)}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|