moving a LOT of stuff around in web ui

This commit is contained in:
legop3
2026-08-02 23:06:30 -04:00
parent 3ebd1c7f9c
commit 15a60a58e6
45 changed files with 814 additions and 870 deletions
@@ -0,0 +1,34 @@
// Mobile Chat Tab
// Purpose: Owns the mobile chat and compact supporting-card composition.
import ChatPanel from '../../../../../components/ChatPanel/index.jsx';
import SocialButtonsGrid from '../../../../../components/SocialButtonsGrid/index.jsx';
import OverseerPreferencePanel from '../../../../../components/OverseerPreferencePanel/index.jsx';
import RawUserPilePanel from '../../../../../components/RawUserPilePanel/index.jsx';
import { TabPanel } from '../../../../../components/Tabs/index.jsx';
import { useSessionSelector } from '../../../../../context/SessionContext.jsx';
import { isFeatureEnabled } from '../../../../../lib/features.js';
import { themeGapClass, themeStackClass } from '../../../../../themes/index.js';
export default function MobileChatTab() {
const showOverseerPreferencePanel = useSessionSelector((state) => Boolean(state.session?.overseerVote?.votingEnabled));
const showSocialButtons = useSessionSelector((state) => {
/* Match the card's own gate so its absence cannot reserve an empty column. */
const socials = Array.isArray(state.session?.socials) ? state.session.socials : [];
return isFeatureEnabled(state, 'socials') && socials.length > 0;
});
return (
<TabPanel id="chat">
<div className={themeStackClass}>
<ChatPanel nicknameLayout="stacked" />
<div className={`grid items-start ${themeGapClass} ${showSocialButtons ? 'grid-cols-[minmax(0,1fr)_minmax(0,1fr)]' : 'grid-cols-[minmax(0,1fr)]'}`}>
{showSocialButtons ? <SocialButtonsGrid /> : null}
<div className={`flex min-w-0 flex-col ${themeGapClass} ${showSocialButtons ? '' : 'max-w-sm'}`}>
{showOverseerPreferencePanel ? <OverseerPreferencePanel /> : null}
<RawUserPilePanel hideNicknameForm compact />
</div>
</div>
</div>
</TabPanel>
);
}
@@ -0,0 +1,20 @@
// Mobile Room Controls Tab
// Purpose: Owns the concrete mobile room-controls card order.
import { TabPanel } from '../../../../../components/Tabs/index.jsx';
import HomeAssistantControls from '../../../../../components/HomeAssistantControls/index.jsx';
import RoomCameraPanel from '../../../../../components/RoomCameraPanel/index.jsx';
import { themeStackClass } from '../../../../../themes/index.js';
import { useDriverLayout } from '../../../DriverLayoutContext.jsx';
export default function RoomControlsTab() {
const layout = useDriverLayout();
const panelId = layout === 'mobile-landscape' ? 'mobile-landscape-room' : 'mobile-portrait-room';
return (
<TabPanel id="roomcontrols">
<div className={themeStackClass}>
<HomeAssistantControls />
<RoomCameraPanel panelId={panelId} />
</div>
</TabPanel>
);
}
@@ -0,0 +1,30 @@
// Driver Activities Tab
// Purpose: Owns the shared desktop/mobile ordering of activity cards.
import { TabPanel } from '../../../../../components/Tabs/index.jsx';
import NeatoCard from '../../../../../components/NeatoCard/index.jsx';
import LiftCard from '../../../../../components/LiftCard/index.jsx';
import BalanceBoardPanel from '../../../../../components/BalanceBoardPanel/index.jsx';
import BarcodeGamesPanel from '../../../../../components/BarcodeGamesPanel/index.jsx';
import OdometerPanel from '../../../../../components/OdometerPanel/index.jsx';
import ButtonBoxPanel from '../../../../../components/ButtonBoxPanel/index.jsx';
import KinectPanel from '../../../../../components/KinectPanel/index.jsx';
import FleetReportsCard from '../../../../../components/FleetReportsCard/index.jsx';
import { themeGapClass } from '../../../../../themes/index.js';
export default function ActivitiesTab() {
return (
<TabPanel id="activities">
<div className={`flex flex-col ${themeGapClass}`}>
<NeatoCard />
<LiftCard />
<BalanceBoardPanel />
<BarcodeGamesPanel />
<OdometerPanel />
<ButtonBoxPanel />
<KinectPanel />
{/* Fleet reports retains its existing terminal position and self-gate. */}
<FleetReportsCard />
</div>
</TabPanel>
);
}
@@ -0,0 +1,16 @@
// Driver Help Tab
// Purpose: Owns the shared driver help panel placement.
import { TabPanel } from '../../../../../components/Tabs/index.jsx';
import HelpPanel from '../../../../../components/HelpPanel/index.jsx';
import { useOpenDriverHelp } from '../../../DriverLayoutContext.jsx';
import { useDriverLayout } from '../../../DriverLayoutContext.jsx';
export default function HelpTab() {
const openHelp = useOpenDriverHelp();
const layout = useDriverLayout();
return (
<TabPanel id="help">
<HelpPanel layout={layout} onOpenOverlay={openHelp} />
</TabPanel>
);
}
@@ -0,0 +1,16 @@
// Driver Settings Tab
// Purpose: Owns the shared driver settings panel placement.
import { TabPanel } from '../../../../../components/Tabs/index.jsx';
import SettingsPanel from '../../../../../components/SettingsPanel/index.jsx';
import { themeStackClass } from '../../../../../themes/index.js';
import { useDriverLayout } from '../../../DriverLayoutContext.jsx';
export default function SettingsTab() {
const layout = useDriverLayout();
const wrapped = layout !== 'desktop';
return (
<TabPanel id="settings">
{wrapped ? <div className={themeStackClass}><SettingsPanel /></div> : <SettingsPanel />}
</TabPanel>
);
}
@@ -0,0 +1,15 @@
// Driver VIP Tab
// Purpose: Owns the shared keep-mounted VIP panel lifecycle.
import { TabPanel, useTabIsActive } from '../../../../../components/Tabs/index.jsx';
import VipPanel from '../../../../../components/VipPanel/index.jsx';
import { useDriverLayout } from '../../../DriverLayoutContext.jsx';
export default function VipTab() {
const layout = useDriverLayout();
const isActive = useTabIsActive('vip');
return (
<TabPanel id="vip" keepMounted>
<VipPanel isActive={isActive} layout={layout} />
</TabPanel>
);
}