Add Phase 1 MVP: D&D text-adventure server
FastAPI + Postgres backend with fastapi-users auth, games/characters CRUD, and a WebSocket chat endpoint where an x.ai Grok DM narrates play, rolls dice, and maintains character sheets via tool calls. React + Tailwind frontend covers registration/login, game list and creation, participation-code join flow, character viewer, and a real-time chat session view. Docker Compose skeleton (Postgres + backend) included; Caddy/frontend container wiring is deferred to the deploy milestone. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
import { Message } from "../api/games";
|
||||
|
||||
function senderLabel(message: Message): string {
|
||||
if (message.sender_type === "dm") return "Dungeon Master";
|
||||
if (message.sender_type === "system") return "System";
|
||||
if (message.character_name) return `${message.player_name} (${message.character_name})`;
|
||||
return message.player_name ?? "Spieler";
|
||||
}
|
||||
|
||||
export default function TranscriptPane({ messages }: { messages: Message[] }) {
|
||||
const bottomRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
bottomRef.current?.scrollIntoView({ block: "end" });
|
||||
}, [messages]);
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col gap-3 overflow-y-auto p-4">
|
||||
{messages.map((m) => (
|
||||
<div key={m.id} className={m.sender_type === "system" ? "text-red-400 italic" : m.sender_type === "dm" ? "text-slate-100" : "text-slate-300"}>
|
||||
<span
|
||||
className={
|
||||
m.sender_type === "dm"
|
||||
? "font-semibold text-amber-400"
|
||||
: m.sender_type === "system"
|
||||
? "font-semibold text-red-400"
|
||||
: "font-semibold text-sky-400"
|
||||
}
|
||||
>
|
||||
{senderLabel(m)}:
|
||||
</span>{" "}
|
||||
<span className="whitespace-pre-wrap">{m.content}</span>
|
||||
</div>
|
||||
))}
|
||||
<div ref={bottomRef} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user