- Streaming AI endpoint at /campanha/api/ai-chat with DeepSeek V4 Flash - 8 tools: calculate, getMunicipalityVotes, getTopDeputies, getDobradinhas, getMunicipalityOverview, getLeaderships, getOrganizations, searchEntities - In-memory rate limiter (50 msgs / 15 min per user) - Desktop: resizable right sidebar via react-resizable-panels - Mobile: full-screen Drawer opened by FAB (2/3 size of quick-actions FAB) - Markdown rendering with react-markdown + remark-gfm (tables, bold, lists) - Session-bound context (clean slate each open) - Auth via existing campaign-token cookie, tools respect user RBAC - Architecture doc: docs/plans/ai-chat-sollinha.md - E2E tests: campaignAiChat.e2e.spec.ts (mocked endpoint)
18 lines
767 B
TypeScript
18 lines
767 B
TypeScript
'use client'
|
|
|
|
import type { ReactNode } from 'react'
|
|
|
|
import { CampaignAIHeaderButton } from '@/components/campaign/shell/ai/CampaignAIHeaderButton'
|
|
import { CampaignPageChromeDisplay } from '@/components/campaign/shell/CampaignPageChromeDisplay'
|
|
import { SidebarTrigger } from '@/components/ui/Sidebar'
|
|
|
|
export const CampaignDesktopHeader = ({ notificationBell }: { notificationBell?: ReactNode }) => (
|
|
<header className="hidden min-h-11 shrink-0 items-center gap-3 border-b border-border px-4 md:flex print:hidden">
|
|
<SidebarTrigger />
|
|
<CampaignPageChromeDisplay layout="desktop" className="flex-1" />
|
|
<div className="ml-auto flex shrink-0 items-center gap-1">
|
|
<CampaignAIHeaderButton />
|
|
{notificationBell ?? null}
|
|
</div>
|
|
</header>
|
|
)
|