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 { BookOpenTextIcon, ScrollTextIcon } from "lucide-react";
import { useGameTick } from "@/hooks/useGameTick";
import { formatType } from "@/utils/event-log/formatType";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
@ -22,14 +23,6 @@ interface LogEntry {
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({
structureId,
targetCollection,
@ -189,9 +182,6 @@ export function EventLedger({
typeof entry.actor === "object" && entry.actor ? entry.actor.username : null;
const isYou = actorId != null && actorId === currentUserId;
const actorLabel = isYou ? "You" : actorName;
const displayMessage = actorLabel
? entry.message.charAt(0).toLowerCase() + entry.message.slice(1)
: entry.message;
const isNarrative = entry.system === false;
return (
<div key={entry.id}>
@ -201,22 +191,22 @@ export function EventLedger({
{isNarrative && (
<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">
{time.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}
</span>
<span className={`flex-1 min-w-0 ${isNarrative ? "text-amber-100/90" : ""}`}>
{actorLabel && (
<span
className={`font-medium ${isYou ? "text-foreground" : "text-muted-foreground"}`}
>
{actorLabel}
<div className="flex-1 min-w-0 flex flex-col gap-0.5">
<div className="flex items-center gap-2 text-xs text-muted-foreground">
<span className="tabular-nums shrink-0">
{time.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}
</span>
)}{" "}
{displayMessage}
</span>
<span className="text-xs text-muted-foreground capitalize shrink-0 pt-0.5">
{formatType(entry.type)}
</span>
{actorLabel && (
<span className={`font-medium ${isYou ? "text-foreground" : ""}`}>
{actorLabel}
</span>
)}
<span className="capitalize">{formatType(entry.type)}</span>
</div>
<span className={`min-w-0 ${isNarrative ? "text-amber-100/90" : ""}`}>
{entry.message}
</span>
</div>
</div>
{index < filtered.length - 1 && <div className="border-t border-border" />}
</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(" ");
}