pre cardcolor

This commit is contained in:
legop3
2026-05-21 02:42:44 -04:00
parent bfd1a94030
commit 331302da01
27 changed files with 324 additions and 328 deletions
@@ -17,6 +17,7 @@ import {
import { mergeFloatChunks, encodeWavMono16 } from './audioCodec.js';
import StatusIndicator from './StatusIndicator.jsx';
import KeyPill from './KeyPill.jsx';
import CardFrame from '../../CardFrame/index.jsx';
export default function VipAudioUploadCard({
ownRoverId = '',
@@ -529,9 +530,8 @@ export default function VipAudioUploadCard({
);
return (
<section className="surface">
<CardFrame title="Audio Controls">
<div className="grid gap-1">
<p className="text-sm text-slate-100 text-center">Audio Controls</p>
<section className="surface">
<div className="flex items-center justify-center gap-0.5 py-0.25 text-xs text-slate-300">
<span>Push-to-Talk Key</span>
@@ -653,6 +653,6 @@ export default function VipAudioUploadCard({
</div>
</section>
</div>
</section>
</CardFrame>
);
}
+3 -3
View File
@@ -2,6 +2,7 @@
// Purpose: Defines the Vip Identity Card module and the local helpers/components used in this file.
// Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit.
import { useState } from 'react';
import CardFrame from '../CardFrame/index.jsx';
import { fieldClass, flowWrapClass, innerFlowClass, maskKey } from './constants.js';
export default function VipIdentityCard({ currentStoredKey, applyIdentityKey, onMessage, fullWidth = false }) {
@@ -40,9 +41,8 @@ export default function VipIdentityCard({ currentStoredKey, applyIdentityKey, on
const wrapClass = fullWidth ? 'w-full' : flowWrapClass;
return (
<section className={`surface ${wrapClass}`}>
<CardFrame title="Identity key" className={wrapClass}>
<div className={innerFlowClass}>
<p className="text-sm text-slate-300">Identity key</p>
<p className="text-xs text-slate-500">Current: {maskKey(currentStoredKey) || 'not set yet'}</p>
<input
className={fieldClass}
@@ -109,6 +109,6 @@ export default function VipIdentityCard({ currentStoredKey, applyIdentityKey, on
</form>
) : null}
</div>
</section>
</CardFrame>
);
}
+15 -13
View File
@@ -2,6 +2,7 @@
// Purpose: Renders a shared lift controller panel synced from server session state.
// Scope: Presents verified-user controls while reflecting global busy/position/cooldown state.
import { useEffect, useMemo, useState } from 'react';
import CardFrame from '../CardFrame/index.jsx';
function badgeClass(tone) {
if (tone === 'good') return 'bg-emerald-600 text-white';
@@ -67,7 +68,16 @@ export default function VipLiftCard({ lift, onUp, onDown, fullWidth = false }) {
};
return (
<section className={`surface relative text-sm text-slate-200 ${wrapClass}`}>
<CardFrame
title="Lift Controls"
className={`relative ${wrapClass}`}
bodyClassName="text-sm text-slate-200"
actions={
<span className={`inline-flex w-auto rounded px-1 py-0.25 text-xs font-semibold ${badgeClass(statusTone)}`}>
{status}
</span>
}
>
{blocked ? (
<div className="absolute inset-0 z-20 flex items-center justify-center rounded-md bg-slate-950/80 px-1.5 text-center">
<div className="space-y-0.25">
@@ -82,18 +92,10 @@ export default function VipLiftCard({ lift, onUp, onDown, fullWidth = false }) {
) : null}
</div>
</div>
) : null}
) : null}
<div className="grid gap-0.5">
<div className="relative flex items-center justify-center min-h-[1.5rem]">
<div className="text-center">
<p className="text-sm text-slate-100">Lift Controls</p>
<p className="text-xs text-slate-400">Move the lift up and down. Please don't break anything...</p>
</div>
<span
className={`absolute right-0 inline-flex w-auto rounded px-1 py-0.25 text-xs font-semibold ${badgeClass(statusTone)}`}
>
{status}
</span>
<div className="text-center">
<p className="text-xs text-slate-400">Move the lift up and down. Please don't break anything...</p>
</div>
<section className="surface-muted px-0.5 py-0.5">
@@ -133,6 +135,6 @@ export default function VipLiftCard({ lift, onUp, onDown, fullWidth = false }) {
{lift?.lastError ? <p className="text-xs text-rose-300 text-center">Last error: {lift.lastError}</p> : null}
</div>
</section>
</CardFrame>
);
}
+14 -12
View File
@@ -2,6 +2,7 @@
// Purpose: Defines the Vip Neato Card module and the local helpers/components used in this file.
// Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit.
import { useState } from 'react';
import CardFrame from '../CardFrame/index.jsx';
function normalizeState(value) {
return String(value || '').trim();
@@ -98,18 +99,19 @@ export default function VipNeatoCard({
const primaryState = docked ? 'Docked' : uiStateLabel !== '--' ? uiStateLabel : 'Away from dock';
return (
<section className={`surface text-sm text-slate-200 ${wrapClass}`}>
<CardFrame
title="Neato Controls"
className={wrapClass}
bodyClassName="text-sm text-slate-200"
actions={
<span className={`inline-flex w-auto rounded px-1 py-0.25 text-xs font-semibold ${metricToneClass(headerTone)}`}>
{headerStatus}
</span>
}
>
<div className="grid gap-0.5">
<div className="relative flex items-center justify-center min-h-[1.5rem]">
<div className="text-center">
<p className="text-sm text-slate-100">Neato Controls</p>
<p className="text-xs text-slate-400">Control the autonomous Neato robovac. Be nice to him.</p>
</div>
<span
className={`absolute right-0 inline-flex w-auto rounded px-1 py-0.25 text-xs font-semibold ${metricToneClass(headerTone)}`}
>
{headerStatus}
</span>
<div className="text-center">
<p className="text-xs text-slate-400">Control the autonomous Neato robovac. Be nice to him.</p>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-0.5">
@@ -217,6 +219,6 @@ export default function VipNeatoCard({
</p>
) : null}
</div>
</section>
</CardFrame>
);
}
@@ -2,6 +2,7 @@
// Purpose: Defines the Vip Private Rover Access Card module and the local helpers/components used in this file.
// Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit.
import { useMemo, useState } from 'react';
import CardFrame from '../CardFrame/index.jsx';
import { flowWrapClass, innerFlowClass } from './constants.js';
export default function VipPrivateRoverAccessCard({
@@ -42,9 +43,8 @@ export default function VipPrivateRoverAccessCard({
};
return (
<section className={`surface text-sm text-slate-300 ${wrapClass}`}>
<CardFrame title="Private rover access requests" className={wrapClass} bodyClassName="text-sm text-slate-300">
<div className={innerFlowClass}>
<p className="text-sm text-slate-300">Private rover access requests</p>
{requestableRovers.length === 0 ? (
<p className="text-xs text-slate-500">No closed private rovers are available to request right now.</p>
) : (
@@ -79,7 +79,6 @@ export default function VipPrivateRoverAccessCard({
</div>
)}
</div>
</section>
</CardFrame>
);
}
@@ -3,6 +3,7 @@
// Scope: Owns local URL validation UX and writes to the existing profile settings namespace.
import { useEffect, useMemo, useState } from 'react';
import { useSettingsNamespace } from '../../settings/index.js';
import CardFrame from '../CardFrame/index.jsx';
import { fieldClass, flowWrapClass, innerFlowClass } from './constants.js';
function normalizeHttpUrl(value) {
@@ -54,9 +55,8 @@ export default function VipProfileImageCard({ isVerified = false, fullWidth = fa
};
return (
<section className={`surface text-sm text-slate-300 ${wrapClass}`}>
<CardFrame title="Chat profile image URL" className={wrapClass} bodyClassName="text-sm text-slate-300">
<form className={innerFlowClass} onSubmit={handleSave}>
<p className="text-sm text-slate-300">Chat profile image URL</p>
<p className="text-xs text-slate-500">
Verified users can set a custom avatar for chat and Discord bridge messages.
</p>
@@ -86,6 +86,6 @@ export default function VipProfileImageCard({ isVerified = false, fullWidth = fa
</button>
</div>
</form>
</section>
</CardFrame>
);
}
@@ -3,6 +3,7 @@
// Scope: Keeps behavior unchanged while isolating this concern into a clear, single-responsibility unit.
import { useState } from 'react';
import NicknameForm from '../NicknameForm/index.jsx';
import CardFrame from '../CardFrame/index.jsx';
import { flowWrapClass, innerFlowClass, fieldClass } from './constants.js';
export default function VipVerificationCard({
@@ -61,29 +62,28 @@ export default function VipVerificationCard({
if (pendingRequestId) {
return (
<section className={`surface text-sm text-slate-300 ${wrapClass}`}>
<CardFrame title="Verification" className={wrapClass} bodyClassName="text-sm text-slate-300">
<div className={innerFlowClass}>Verification request pending: {pendingRequestId}</div>
</section>
</CardFrame>
);
}
if (requestFlowStep === 0) {
return (
<section className={`surface ${wrapClass}`}>
<CardFrame title="Verification" className={wrapClass}>
<div className={innerFlowClass}>
<p className="text-sm text-slate-300">Verification</p>
<button type="button" className="button-dark text-sm" onClick={beginRequestFlow} disabled={working}>
Request Verification
</button>
</div>
</section>
</CardFrame>
);
}
return (
<form className={`surface ${wrapClass}`} onSubmit={handleRequestSubmit}>
<CardFrame title="Request verification" className={wrapClass}>
<form onSubmit={handleRequestSubmit}>
<div className={innerFlowClass}>
<p className="text-sm text-slate-300">Request verification</p>
<p className="text-xs text-slate-500">
Step {requestFlowStep} of 3
</p>
@@ -189,6 +189,7 @@ export default function VipVerificationCard({
</div>
) : null}
</div>
</form>
</form>
</CardFrame>
);
}