beginning of my ideases

This commit is contained in:
legop3
2026-05-21 01:57:59 -04:00
parent 8727555788
commit bfd1a94030
17 changed files with 90 additions and 48 deletions
@@ -127,8 +127,8 @@ export default function ButtonBoxPanel() {
return (
<section className="panel-section space-y-0.5 text-base">
<header className="panel-muted text-center text-sm">
<p>Button Box</p>
<header className="panel-title-row">
<p className="panel-title-text">Button Box</p>
</header>
<div className="grid grid-cols-4 gap-0.5">
{buttons.map((button) => {
+6
View File
@@ -16,6 +16,7 @@ export default function ChatPanel({
hideSpectatorNotice = false,
fillHeight = false,
allowSpectatorInput = false,
title = 'Chat',
}) {
const role = useSessionSelector((state) => state.session?.role || null);
const currentRoverId = useSessionSelector((state) => state.session?.assignment?.roverId || null);
@@ -106,6 +107,11 @@ export default function ChatPanel({
return (
<section className={`panel-section space-y-0.5 text-base ${fillHeight ? 'flex h-full flex-col overflow-hidden' : ''}`}>
{title ? (
<div className="panel-title-row">
<span className="panel-title-text">{title}</span>
</div>
) : null}
<div className={`surface overflow-y-auto space-y-0.5 px-0 ${listClass}`} ref={listRef}>
{sorted.length === 0 && typingRows.length === 0 ? (
<p className="text-sm text-slate-500">No messages yet.</p>
@@ -256,7 +256,7 @@ export default function HomeAssistantControls() {
if (!ha?.enabled) {
return (
<section className="panel-section space-y-0.5 text-sm text-slate-400">
<p className="text-slate-300">Room Controls</p>
<p className="panel-title-text">Room Controls</p>
<p className="text-slate-500">Not configured on the server.</p>
</section>
);
@@ -265,7 +265,7 @@ export default function HomeAssistantControls() {
if (entities.length === 0) {
return (
<section className="panel-section space-y-0.5 text-sm text-slate-400">
<p className="text-slate-300">Room Controls</p>
<p className="panel-title-text">Room Controls</p>
<p className="text-slate-500">No lights or switches configured.</p>
</section>
);
@@ -275,23 +275,25 @@ export default function HomeAssistantControls() {
return (
<section className="panel-section space-y-0.5 text-base">
<header className="flex items-center justify-between gap-0.5 text-sm text-slate-400">
<div className="flex items-center gap-0.5">
<p>Room Controls</p>
<span className="text-xs text-slate-500">{entities.length}</span>
{controlsLocked ? <StatusBadge label={lockState === 'off' ? 'Locked Off' : 'Locked On'} tone="warn" /> : null}
<div className="flex items-center gap-0.5 text-xs text-slate-300 background-black">
<header className="panel-title-row">
<div className="panel-title-left">
<p className="panel-title-text">Room Controls</p>
<span className="panel-title-meta">{entities.length}</span>
</div>
<div className="panel-title-right">
<div className="panel-title-actions">
<span className="flex items-center gap-0.5">
<span>On</span>
<span className="panel-title-meta">On</span>
{onKeyLabel ? <KeyPill label={onKeyLabel} /> : null}
</span>
<span className="flex items-center gap-0.5">
<span>Off</span>
<span className="panel-title-meta">Off</span>
{offKeyLabel ? <KeyPill label={offKeyLabel} /> : null}
</span>
</div>
{controlsLocked ? <StatusBadge label={lockState === 'off' ? 'Locked Off' : 'Locked On'} tone="warn" /> : null}
<StatusBadge label={connected ? 'Connected' : 'Offline'} tone={connected ? 'success' : 'warn'} />
</div>
<StatusBadge label={connected ? 'Connected' : 'Offline'} tone={connected ? 'success' : 'warn'} />
</header>
{controlsLocked ? (
<p className="rounded border border-amber-600/60 bg-amber-900/40 px-1 py-0.5 text-xs text-amber-100">
@@ -319,5 +321,5 @@ export default function HomeAssistantControls() {
function KeyPill({ label }) {
if (!label) return null;
return <span className="rounded border border-white/40 px-1 text-[0.7rem] text-white">{label}</span>;
return <span className="rounded border border-slate-600 px-1 text-[0.65rem] text-slate-300">{label}</span>;
}
+3 -3
View File
@@ -9,9 +9,9 @@ export default function LogPanel() {
const rendered = useMemo(() => logs.slice().reverse(), [logs]);
return (
<div className="panel-section space-y-0.5 text-base">
<div className="flex items-center justify-between text-sm text-slate-400">
<span>Server logs</span>
<span>{logs.length}</span>
<div className="panel-title-row">
<span className="panel-title-text">Server logs</span>
<span className="panel-title-meta">{logs.length}</span>
</div>
<div className="surface h-64 overflow-y-auto font-mono text-xs">
{logs.length === 0 ? (
@@ -22,7 +22,9 @@ export default function OverseerPreferencePanel() {
return (
<section className="surface p-1 text-xs text-slate-200 text-center">
<div className="text-[0.65rem] text-slate-400">Overseer vote</div>
<div className="panel-title-row">
<span className="panel-title-text">Overseer vote</span>
</div>
<label
className={`flex items-center justify-center gap-1.5 rounded px-1 py-0.5 ${
enabled ? 'bg-emerald-600/80 text-emerald-50' : 'bg-slate-600/70 text-slate-100'
@@ -76,9 +76,9 @@ export default function RawUserPilePanel({
<div className={`space-y-0.5 ${fillHeight ? 'flex flex-1 min-h-0 flex-col' : ''}`}>
{!hideHeader && (
<div className={`flex items-center justify-between text-sm text-slate-400 ${compact ? 'text-xs' : ''}`}>
<span>Users</span>
<span className="text-xs text-slate-500">{sorted.length}</span>
<div className="panel-title-row">
<span className="panel-title-text">Users</span>
<span className="panel-title-meta">{sorted.length}</span>
</div>
)}
<div
@@ -151,9 +151,9 @@ export default function ReplaySourcesPanel({ panelId = 'replay-sources', fillHei
return (
<section className={`panel-section p-0.75 text-sm ${containerClass}`}>
<header className="panel-muted flex items-center justify-between text-xs">
<span>Replay Sources</span>
<span>{sources.length}</span>
<header className="panel-title-row">
<span className="panel-title-text">Replay Sources</span>
<span className="panel-title-meta">{sources.length}</span>
</header>
<div className={`grid gap-0.5 md:grid-cols-2 ${listWrapClass}`}>
<GroupList title="Rovers" items={grouped.rovers} selected={selected} onToggle={toggleKey} />
@@ -101,6 +101,7 @@ function DriveDockPanel() {
value={value}
min={min}
max={max}
label="Camera tilt"
disabled={cameraDisabled}
onChange={setServoAngle}
keyDownLabel={downLabel}
@@ -69,15 +69,15 @@ export default function RoomCameraPanel({
return (
<section className="panel-section space-y-0.5 text-base">
{!hideHeader && (
<header className="flex flex-wrap items-center justify-between gap-0.5 text-sm text-slate-400">
<div className="flex items-center gap-0.5">
<p>Room cameras</p>
<span className="text-xs text-slate-500">{cameras.length}</span>
<header className="panel-title-row">
<div className="panel-title-left">
<p className="panel-title-text">Room cameras</p>
<span className="panel-title-meta">{cameras.length}</span>
</div>
<div className="flex flex-wrap items-center gap-0.5 text-xs">
<div className="panel-title-right">
{showLayoutToggle && (
<div className="flex items-center gap-0.5">
<span className="text-slate-500">Layout:</span>
<div className="panel-title-actions">
<span className="panel-title-meta">Layout</span>
<div className="inline-flex overflow-hidden rounded border border-slate-700">
{ORIENTATIONS.map((option) => (
<button
@@ -97,7 +97,11 @@ export default function RoverQueuesPanel({ title = 'Rovers' }) {
return (
<div className="space-y-0.5 text-sm">
{title && <p className="text-sm text-slate-400">{title}</p>}
{title && (
<div className="panel-title-row">
<p className="panel-title-text">{title}</p>
</div>
)}
{rosterItems.length === 0 ? (
<p className="text-sm text-slate-500">No rovers registered.</p>
) : (
@@ -173,7 +173,7 @@ function SensorDetails({ sensors, dockState }) {
function DetailCard({ title, children }) {
return (
<div className="surface space-y-0.5 p-1 text-sm">
<div className="text-[0.8rem] uppercase tracking-wide text-slate-400">{title}</div>
<div className="panel-title-text">{title}</div>
<div className="space-y-0.5">{children}</div>
</div>
);
@@ -20,6 +20,9 @@ export function NicknameEntryPanel({ compact = false }) {
export function LinkButtonsPanel() {
return (
<section className="panel-section flex h-full min-h-0 flex-col gap-0.5 text-base">
<div className="panel-title-row">
<span className="panel-title-text">Socials</span>
</div>
<SocialButtonsGrid className="flex-1 min-h-0" />
</section>
);
+24
View File
@@ -71,6 +71,30 @@ body {
@apply text-sm text-slate-400 rounded-md;
}
.panel-title-row {
@apply flex items-center justify-between gap-0.5 rounded-md bg-slate-900 px-0.5 py-0.5 text-left;
}
.panel-title-text {
@apply text-[0.78rem] font-semibold tracking-normal text-slate-200 leading-none text-left;
}
.panel-title-meta {
@apply text-[0.68rem] font-medium tracking-normal text-slate-400 leading-none;
}
.panel-title-left {
@apply flex min-w-0 items-center gap-0.5;
}
.panel-title-right {
@apply flex flex-wrap items-center justify-end gap-0.5;
}
.panel-title-actions {
@apply flex items-center gap-0.5 text-[0.68rem] text-slate-400 leading-none;
}
.surface {
@apply bg-neutral-800 text-white px-0.5 py-0.5 rounded-md;
}