1
0
Fork 0

refactor(event-log): extract shared formatType helper and restyle ledger entries

- Move the event type formatter into its own util for reuse
- Reflow ledger rows into a stacked two-line layout with a type chip
This commit is contained in:
Jason Fraley 2026-08-11 23:25:41 -04:00
parent 9bf16980cc
commit 66816e2182
2 changed files with 27 additions and 26 deletions

View file

@ -4,6 +4,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { Item, ItemContent, ItemHeader, ItemTitle, ItemDescription } from "@/components/ui/item"; import { Item, ItemContent, ItemHeader, ItemTitle, ItemDescription } from "@/components/ui/item";
import { BookOpenTextIcon, ScrollTextIcon } from "lucide-react"; import { BookOpenTextIcon, ScrollTextIcon } from "lucide-react";
import { useGameTick } from "@/hooks/useGameTick"; import { useGameTick } from "@/hooks/useGameTick";
import { formatType } from "@/utils/event-log/formatType";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuCheckboxItem, DropdownMenuCheckboxItem,
@ -22,14 +23,6 @@ interface LogEntry {
data?: Record<string, unknown>; data?: Record<string, unknown>;
} }
function formatType(type: string) {
return type
.replace(":", " ")
.split(" ")
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
.join(" ");
}
export function EventLedger({ export function EventLedger({
structureId, structureId,
targetCollection, targetCollection,
@ -189,9 +182,6 @@ export function EventLedger({
typeof entry.actor === "object" && entry.actor ? entry.actor.username : null; typeof entry.actor === "object" && entry.actor ? entry.actor.username : null;
const isYou = actorId != null && actorId === currentUserId; const isYou = actorId != null && actorId === currentUserId;
const actorLabel = isYou ? "You" : actorName; const actorLabel = isYou ? "You" : actorName;
const displayMessage = actorLabel
? entry.message.charAt(0).toLowerCase() + entry.message.slice(1)
: entry.message;
const isNarrative = entry.system === false; const isNarrative = entry.system === false;
return ( return (
<div key={entry.id}> <div key={entry.id}>
@ -201,22 +191,22 @@ export function EventLedger({
{isNarrative && ( {isNarrative && (
<BookOpenTextIcon className="size-4 text-amber-400 shrink-0 mt-0.5" /> <BookOpenTextIcon className="size-4 text-amber-400 shrink-0 mt-0.5" />
)} )}
<span className="text-xs text-muted-foreground shrink-0 w-16 text-right tabular-nums pt-0.5"> <div className="flex-1 min-w-0 flex flex-col gap-0.5">
{time.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} <div className="flex items-center gap-2 text-xs text-muted-foreground">
</span> <span className="tabular-nums shrink-0">
<span className={`flex-1 min-w-0 ${isNarrative ? "text-amber-100/90" : ""}`}> {time.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}
{actorLabel && (
<span
className={`font-medium ${isYou ? "text-foreground" : "text-muted-foreground"}`}
>
{actorLabel}
</span> </span>
)}{" "} {actorLabel && (
{displayMessage} <span className={`font-medium ${isYou ? "text-foreground" : ""}`}>
</span> {actorLabel}
<span className="text-xs text-muted-foreground capitalize shrink-0 pt-0.5"> </span>
{formatType(entry.type)} )}
</span> <span className="capitalize">{formatType(entry.type)}</span>
</div>
<span className={`min-w-0 ${isNarrative ? "text-amber-100/90" : ""}`}>
{entry.message}
</span>
</div>
</div> </div>
{index < filtered.length - 1 && <div className="border-t border-border" />} {index < filtered.length - 1 && <div className="border-t border-border" />}
</div> </div>

View file

@ -0,0 +1,11 @@
/**
* Formats an event type slug (e.g. "structure:resize") into a human-readable
* label ("Structure Resize") for display in event log UIs.
*/
export function formatType(type: string) {
return type
.replace(":", " ")
.split(" ")
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
.join(" ");
}