fix Owliver ai chat

This commit is contained in:
2026-08-10 13:19:10 +05:30
parent 52fe6d9c14
commit 76412b08b4
8 changed files with 57 additions and 272 deletions

View File

@@ -10,6 +10,7 @@ import { logActivity } from '@/lib/userTracking';
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet';
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator } from '@/components/ui/dropdown-menu';
import { AssistantPanel, AssistantPanelProvider } from '@/components/ai-assistant';
import OwliverChatBubble from '@/components/krow/OwliverChatBubble';
import { HoverCard, HoverCardTrigger, HoverCardContent } from '@/components/ui/hover-card';
import KrowIdPreview from '@/components/krow/KrowIdPreview';
@@ -52,6 +53,9 @@ export default function Layout() {
const [menuOpen, setMenuOpen] = useState(false);
const [user, setUser] = useState(null);
const [activeRole, setActiveRole] = useState(() => localStorage.getItem('activeRole') || 'employer');
// Owliver's own open state. Owliver is a separate product with its own UI and
// voice workflow; it is not routed through the Krow AI panel.
const [owliverOpen, setOwliverOpen] = useState(false);
useEffect(() => {
base44.auth.me().then(setUser).catch(() => {});
@@ -89,13 +93,13 @@ export default function Layout() {
navigate(ROLE_HOME[role]);
};
// Talent can be sent to the Owliver profile-builder conversation from
// anywhere via this event (the portal's own CTA uses it).
// Anything in the talent portal can open Owliver through this event — the
// portal hero's own CTA uses it.
useEffect(() => {
const openBuilder = () => navigate('/owliver');
window.addEventListener('krow:open-owliver', openBuilder);
return () => window.removeEventListener('krow:open-owliver', openBuilder);
}, [navigate]);
const openOwliver = () => setOwliverOpen(true);
window.addEventListener('krow:open-owliver', openOwliver);
return () => window.removeEventListener('krow:open-owliver', openOwliver);
}, []);
const navItems = ROLE_NAV[activeRole];
const isTalent = activeRole === 'talent';
@@ -190,7 +194,7 @@ export default function Layout() {
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() => navigate(isTalent ? '/owliver' : '/identity')}
onClick={() => (isTalent ? window.dispatchEvent(new CustomEvent('krow:open-owliver')) : navigate('/identity'))}
className="cursor-pointer"
>
<UserIcon className="w-4 h-4 mr-2" />
@@ -314,7 +318,7 @@ export default function Layout() {
</Link>
))}
<button
onClick={() => { setMenuOpen(false); navigate(isTalent ? '/owliver' : '/identity'); }}
onClick={() => { setMenuOpen(false); isTalent ? window.dispatchEvent(new CustomEvent('krow:open-owliver')) : navigate('/identity'); }}
className={cn(
'px-4 py-2.5 rounded-xl text-[14px] font-medium transition-all text-left w-full',
isActive('/identity') ? 'bg-[#EFF6FF] text-[#0A39DF]' : 'text-[#374151] hover:bg-white/60'
@@ -373,15 +377,19 @@ export default function Layout() {
<Outlet />
</main>
{/* Sticky below the sticky chrome so the assistant stays put while the
dashboard scrolls. Talent has no control bar, hence the two offsets. */}
{/* Krow AI — the dashboard assistant. Employer and Admin only; see
ai-assistant/placement.js. Sticky below the sticky chrome so it stays
put while the dashboard scrolls. */}
<AssistantPanel
stickyClassName={isTalent ? 'top-20' : 'top-[8.5rem]'}
panelHeightClassName={
isTalent ? 'h-[calc(100vh_-_7rem)]' : 'h-[calc(100vh_-_10rem)]'
}
stickyClassName="top-[8.5rem]"
panelHeightClassName="h-[calc(100vh_-_10rem)]"
/>
</div>
{/* Owliver — the independent AI product, with its own branding, voice
experience and workflow. Talent only. Deliberately untouched by the
Krow AI work: different product, different UI, no shared components. */}
{isTalent && <OwliverChatBubble open={owliverOpen} onOpenChange={setOwliverOpen} />}
</div>
</AssistantPanelProvider>
);