Files
demo/frontend-starter/components/galerie/beispiele/chat.tsx
T
AdminandClaude Opus 5.5 78c8b702f0 Galerie aller shadcn/ui-Komponenten auf der Startseite
- Alle 63 Komponenten aus dem shadcn-Register installiert (Stil base-luma)
- Galerie unter components/galerie mit 7 Kategorien und Sprungnavigation
- Inhaltsbreite auf max-w-6xl erweitert
- shadcn-Hauptfarbe auf E&P-Tiefblau, größter Radius eckig
- App-Titel "UI-Galerie"

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-05 18:07:19 +00:00

263 lines
8.4 KiB
TypeScript

"use client";
import { CalendarDaysIcon, FileTextIcon, SearchIcon, XIcon } from "lucide-react";
import { Eintrag } from "@/components/galerie/eintrag";
import {
Attachment,
AttachmentAction,
AttachmentActions,
AttachmentContent,
AttachmentDescription,
AttachmentGroup,
AttachmentMedia,
AttachmentTitle,
} from "@/components/ui/attachment";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Bubble, BubbleContent, BubbleGroup } from "@/components/ui/bubble";
import {
CodeBlock,
CodeBlockActions,
CodeBlockContent,
CodeBlockCopyButton,
CodeBlockHeader,
CodeBlockLine,
CodeBlockTitle,
} from "@/components/ui/code-block";
import { Marker, MarkerContent, MarkerIcon } from "@/components/ui/marker";
import {
Message,
MessageAvatar,
MessageContent,
MessageGroup,
MessageHeader,
} from "@/components/ui/message";
import {
MessageScroller,
MessageScrollerButton,
MessageScrollerContent,
MessageScrollerItem,
MessageScrollerProvider,
MessageScrollerViewport,
} from "@/components/ui/message-scroller";
import {
Questionnaire,
QuestionnaireActions,
QuestionnaireChoice,
QuestionnaireChoices,
QuestionnaireInput,
QuestionnaireItem,
QuestionnaireNext,
QuestionnairePrevious,
QuestionnaireProgress,
QuestionnaireSubmit,
QuestionnaireTitle,
} from "@/components/ui/questionnaire";
import { Spinner } from "@/components/ui/spinner";
import { toast } from "@/components/ui/toast";
import {
Trace,
TraceCollapsible,
TraceCollapsibleContent,
TraceCollapsibleTrigger,
TraceDescription,
TraceIcon,
TraceLine,
TraceTitle,
} from "@/components/ui/trace";
import { useHighlightedCode } from "@/hooks/use-highlighted-code";
const BEISPIELCODE = `export function Begruessung({ name }: { name: string }) {
return <p>Willkommen, {name}!</p>
}`;
const VERLAUF = [
{ id: "1", von: "kunde", text: "Hallo, ist die Island-Reise im Juli noch frei?" },
{ id: "2", von: "service", text: "Ja, es gibt noch 4 Plätze." },
{ id: "3", von: "kunde", text: "Super! Ist der Flug inklusive?" },
{ id: "4", von: "service", text: "Ja, ab Frankfurt oder München." },
{ id: "5", von: "kunde", text: "Dann buche ich für zwei Personen." },
{ id: "6", von: "service", text: "Gern, ich schicke Ihnen das Angebot." },
];
function CodeBeispiel() {
const zeilen = useHighlightedCode(BEISPIELCODE, "tsx");
return (
<CodeBlock size="sm">
<CodeBlockHeader>
<CodeBlockTitle>begruessung.tsx</CodeBlockTitle>
<CodeBlockActions>
<CodeBlockCopyButton value={BEISPIELCODE} />
</CodeBlockActions>
</CodeBlockHeader>
<CodeBlockContent lineNumbers>
{zeilen.map((zeile, index) => (
<CodeBlockLine key={index}>{zeile}</CodeBlockLine>
))}
</CodeBlockContent>
</CodeBlock>
);
}
export function ChatBeispiele() {
return (
<>
<Eintrag name="Attachment">
<AttachmentGroup>
<Attachment>
<AttachmentMedia>
<FileTextIcon />
</AttachmentMedia>
<AttachmentContent>
<AttachmentTitle>Reiseplan.pdf</AttachmentTitle>
<AttachmentDescription>240 KB</AttachmentDescription>
</AttachmentContent>
<AttachmentActions>
<AttachmentAction aria-label="Entfernen">
<XIcon />
</AttachmentAction>
</AttachmentActions>
</Attachment>
<Attachment state="uploading">
<AttachmentMedia>
<Spinner />
</AttachmentMedia>
<AttachmentContent>
<AttachmentTitle>Pass.jpg</AttachmentTitle>
<AttachmentDescription>Wird hochgeladen …</AttachmentDescription>
</AttachmentContent>
</Attachment>
</AttachmentGroup>
</Eintrag>
<Eintrag name="Bubble">
<BubbleGroup className="w-full">
<Bubble variant="muted">
<BubbleContent>Wann geht der Transfer zum Hotel?</BubbleContent>
</Bubble>
<Bubble align="end">
<BubbleContent>Direkt nach der Landung, gegen 14 Uhr.</BubbleContent>
</Bubble>
</BubbleGroup>
</Eintrag>
<Eintrag name="Message">
<MessageGroup className="w-full">
<Message>
<MessageAvatar>
<Avatar size="sm">
<AvatarFallback>EP</AvatarFallback>
</Avatar>
</MessageAvatar>
<MessageContent>
<MessageHeader>Service</MessageHeader>
<Bubble variant="muted">
<BubbleContent>Wie kann ich helfen?</BubbleContent>
</Bubble>
</MessageContent>
</Message>
<Message align="end">
<MessageContent>
<Bubble>
<BubbleContent>Ich möchte meine Reise umbuchen.</BubbleContent>
</Bubble>
</MessageContent>
</Message>
</MessageGroup>
</Eintrag>
<Eintrag name="Message Scroller">
<MessageScrollerProvider>
<MessageScroller className="h-48 border">
<MessageScrollerViewport>
<MessageScrollerContent className="gap-3 p-3">
{VERLAUF.map((nachricht) => (
<MessageScrollerItem key={nachricht.id} messageId={nachricht.id}>
<Bubble
variant={nachricht.von === "service" ? "muted" : "default"}
align={nachricht.von === "service" ? "start" : "end"}
>
<BubbleContent>{nachricht.text}</BubbleContent>
</Bubble>
</MessageScrollerItem>
))}
</MessageScrollerContent>
</MessageScrollerViewport>
<MessageScrollerButton />
</MessageScroller>
</MessageScrollerProvider>
</Eintrag>
<Eintrag name="Marker">
<div className="flex w-full flex-col gap-3">
<Marker variant="separator">
<MarkerContent>Heute</MarkerContent>
</Marker>
<Marker>
<MarkerIcon>
<CalendarDaysIcon />
</MarkerIcon>
<MarkerContent>Reise wurde auf den 12. Juli verschoben</MarkerContent>
</Marker>
</div>
</Eintrag>
<Eintrag name="Trace">
<Trace>
<TraceLine>
<TraceIcon>
<SearchIcon />
</TraceIcon>
<TraceTitle>Hotels in Reykjavík gesucht</TraceTitle>
<TraceDescription>1,2 s</TraceDescription>
</TraceLine>
<TraceLine status="running">
<TraceTitle>Preise werden verglichen</TraceTitle>
</TraceLine>
<TraceCollapsible>
<TraceCollapsibleTrigger>
<TraceLine>
<TraceTitle>3 Angebote gefunden</TraceTitle>
</TraceLine>
</TraceCollapsibleTrigger>
<TraceCollapsibleContent>Hotel Borg, Hotel Klettur, Center Hotel Plaza</TraceCollapsibleContent>
</TraceCollapsible>
</Trace>
</Eintrag>
<Eintrag name="Code Block">
<CodeBeispiel />
</Eintrag>
<Eintrag name="Questionnaire" breit>
<Questionnaire
onSubmit={(event) => {
event.preventDefault();
toast.add({ title: "Danke!", description: "Ihre Antworten sind angekommen.", type: "success" });
}}
>
<QuestionnaireProgress />
<QuestionnaireItem name="reiseart" required>
<QuestionnaireTitle>Wie reisen Sie am liebsten?</QuestionnaireTitle>
<QuestionnaireChoices>
<QuestionnaireChoice value="rund">Rundreise</QuestionnaireChoice>
<QuestionnaireChoice value="kreuz">Kreuzfahrt</QuestionnaireChoice>
<QuestionnaireChoice value="stadt">Städtereise</QuestionnaireChoice>
</QuestionnaireChoices>
</QuestionnaireItem>
<QuestionnaireItem name="wunsch">
<QuestionnaireTitle>Haben Sie besondere Wünsche?</QuestionnaireTitle>
<QuestionnaireInput placeholder="z. B. Fensterplatz" />
</QuestionnaireItem>
<QuestionnaireActions>
<QuestionnairePrevious>Zurück</QuestionnairePrevious>
<QuestionnaireNext>Weiter</QuestionnaireNext>
<QuestionnaireSubmit>Absenden</QuestionnaireSubmit>
</QuestionnaireActions>
</Questionnaire>
</Eintrag>
</>
);
}