mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 17:40:46 -04:00
pre cardcolor
This commit is contained in:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user