VayuChat-v2 / src /ChatMessage.tsx
Nipun's picture
Deploy React Vite Gemini 3.5 VayuChat (#1)
72606cb
Raw
History Blame
2.32 kB
import { lazy, Suspense } from "react";
import { ResultTable } from "./ResultTable";
import { DatabaseIcon, WindIcon } from "./icons";
import type { ConversationMessage } from "./types";
const AnalysisChart = lazy(() =>
import("./AnalysisChart").then((module) => ({
default: module.AnalysisChart,
})),
);
export function ChatMessage({ message }: { message: ConversationMessage }) {
if (message.role === "user") {
return (
<article className="message message--user">
<div className="user-bubble">{message.content}</div>
</article>
);
}
return (
<article className={`message message--assistant ${message.error ? "has-error" : ""}`}>
<div className="assistant-avatar">
<WindIcon />
</div>
<div className="assistant-body">
<div className="assistant-meta">
<strong>VayuChat</strong>
<span>Gemini 3.5 Flash-Lite</span>
</div>
{message.error ? (
<div className="answer-error" role="alert">
<strong>Analysis stopped</strong>
<p>{message.error}</p>
</div>
) : (
<>
<p className="answer-lead">{message.result?.answer ?? message.content}</p>
{message.result?.key_points.length ? (
<ul className="key-points">
{message.result.key_points.map((point) => (
<li key={point}>{point}</li>
))}
</ul>
) : null}
{message.result ? (
<Suspense fallback={<div className="chart-loading" aria-hidden="true" />}>
<AnalysisChart result={message.result} />
</Suspense>
) : null}
{message.result ? <ResultTable result={message.result} /> : null}
{message.result?.method_note || message.result?.query ? (
<details className="method-details">
<summary>
<DatabaseIcon />
How this was calculated
</summary>
{message.result.method_note ? <p>{message.result.method_note}</p> : null}
{message.result.query ? <pre>{message.result.query}</pre> : null}
</details>
) : null}
</>
)}
</div>
</article>
);
}