updates on bugs on the dispatch and ai button integrations
This commit is contained in:
78
src/components/assistant/DoormileAI/AILauncher.jsx
Normal file
78
src/components/assistant/DoormileAI/AILauncher.jsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import { PanelRight } from 'lucide-react';
|
||||
|
||||
import { cn } from '@/lib/utils';
|
||||
import doormileMark from '@/assets/images/doormile-mark.png';
|
||||
|
||||
// ==============================|| Doormile AI — the launcher ||============================== //
|
||||
//
|
||||
// The floating control that opens MileTruth. It replaces the 32px icon that sat
|
||||
// in the header between the search box and the notification bell.
|
||||
//
|
||||
// The header is a poor home for it. Everything else in that row is a utility
|
||||
// the operator reaches for occasionally — search, alerts, the account menu —
|
||||
// and the assistant was a bare brand mark among them, with nothing saying what
|
||||
// it opened. Down here it is a named control that reads as one thing: a pill
|
||||
// with the mark, the word, and the panel glyph that shows where it will appear.
|
||||
//
|
||||
// It is NOT rendered on the home page, where the assistant is the page rather
|
||||
// than a panel beside it. That rule lives with the caller, next to the matching
|
||||
// rule for the panel itself, so the two cannot disagree about where it applies.
|
||||
const AILauncher = ({ isOpen, onToggle, className }) => {
|
||||
// Hidden while the panel is open.
|
||||
//
|
||||
// The panel docks to the right edge and this button is pinned to the bottom
|
||||
// right, so an open panel sits underneath it on a wide screen and covers it
|
||||
// completely on a narrow one, where the panel goes full-width behind a scrim.
|
||||
// Rather than chase the dock width across breakpoints, the launcher steps
|
||||
// aside: the panel's own header carries the close control, so nothing is lost.
|
||||
if (isOpen) return null;
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onToggle}
|
||||
aria-label="Open MileTruth"
|
||||
aria-expanded={false}
|
||||
title="MileTruth — Operations Copilot"
|
||||
className={cn(
|
||||
// Sits under the panel's own layer (1200) so a panel opening over it is
|
||||
// never a z-index race, and above ordinary page chrome.
|
||||
'fixed bottom-5 right-5 z-[1100]',
|
||||
'inline-flex items-center gap-2 rounded-full',
|
||||
'border border-border bg-surface py-1.5 pl-1.5 pr-3',
|
||||
'shadow-lg shadow-black/10',
|
||||
'cursor-pointer transition-all duration-150',
|
||||
'hover:-translate-y-0.5 hover:shadow-xl',
|
||||
// The outline is the brand crimson, on hover AND on keyboard focus.
|
||||
//
|
||||
// `ring-brand` at full strength, not the `/20` wash the header icon
|
||||
// used: on a white pill a 20% tint of #C8102E reads as a pale pink
|
||||
// smudge rather than as an outline, which is the whole affordance.
|
||||
'hover:border-brand/40 hover:ring-2 hover:ring-brand',
|
||||
'focus-visible:outline-none focus-visible:border-brand/40 focus-visible:ring-2 focus-visible:ring-brand',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<img
|
||||
src={doormileMark}
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
// `object-contain` and no `max-w-none`, so the mark can never outgrow
|
||||
// its slot however the asset is redrawn — the bug the header icon hit
|
||||
// twice before it settled.
|
||||
className="h-7 w-7 shrink-0 object-contain"
|
||||
/>
|
||||
<span className="text-body-sm font-bold text-ink-1">Doormile</span>
|
||||
<PanelRight className="h-4 w-4 shrink-0 text-ink-4" aria-hidden="true" />
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
AILauncher.propTypes = {
|
||||
isOpen: PropTypes.bool,
|
||||
onToggle: PropTypes.func.isRequired,
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default AILauncher;
|
||||
Reference in New Issue
Block a user