diff --git a/src/components/campaign/dashboard/CampaignStaffGlobalSearch.tsx b/src/components/campaign/dashboard/CampaignStaffGlobalSearch.tsx
index 0fefbd0d..aba182c0 100644
--- a/src/components/campaign/dashboard/CampaignStaffGlobalSearch.tsx
+++ b/src/components/campaign/dashboard/CampaignStaffGlobalSearch.tsx
@@ -1,6 +1,7 @@
'use client'
import { CampaignHomeSearch } from '@/components/campaign/dashboard/CampaignHomeSearch'
+import { HomeSearchProvider } from '@/components/campaign/dashboard/HomeSearchContext'
import { HomeSearchActivityGroup } from '@/components/campaign/dashboard/HomeSearchActivityGroup'
import { HomeSearchAdvisorGroup } from '@/components/campaign/dashboard/HomeSearchAdvisorGroup'
import { HomeSearchDemandGroup } from '@/components/campaign/dashboard/HomeSearchDemandGroup'
@@ -13,6 +14,7 @@ import {
import { HomeSearchResultsLayout } from '@/components/campaign/dashboard/HomeSearchResultsLayout'
import { HomeSearchResultsShell } from '@/components/campaign/dashboard/HomeSearchResultsShell'
import { HomeSearchStateDeputyGroup } from '@/components/campaign/dashboard/HomeSearchStateDeputyGroup'
+import { useHomeSearchQuery } from '@/components/campaign/dashboard/useHomeSearchQuery'
const CampaignStaffGlobalSearchResults = () => {
const searchResultsState = useHomeSearchResultsState()
@@ -37,3 +39,14 @@ const CampaignStaffGlobalSearchResults = () => {
/** Result groups + input — requires an ancestor `HomeSearchProvider`. */
export const CampaignStaffGlobalSearchBody = CampaignStaffGlobalSearchResults
+
+/** Self-contained staff global search for surfaces outside Início (B90 drawer, future B91). */
+export const CampaignStaffGlobalSearch = () => {
+ const searchState = useHomeSearchQuery()
+
+ return (
+
+
+
+ )
+}
diff --git a/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx b/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx
index c5af7831..784818cf 100644
--- a/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx
+++ b/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx
@@ -101,9 +101,7 @@ export const CampaignQuickActionsDrawer = ({
}))}
className="w-full"
/>
- ) : (
-
Nenhuma ação rápida nesta página.
- )}
+ ) : null}
{expanded ? : null}
diff --git a/src/lib/campaignPaths.ts b/src/lib/campaignPaths.ts
index 3500430d..56c0bf02 100644
--- a/src/lib/campaignPaths.ts
+++ b/src/lib/campaignPaths.ts
@@ -8,3 +8,5 @@ export const CAMPAIGN_DEMANDS_HOME = '/campanha/demandas' as const
export const CAMPAIGN_ADVISORS_HOME = '/campanha/assessores' as const
export const LEADER_CONTACTS_HOME = '/campanha/contatos' as const
+
+export const CAMPAIGN_PROFILE_HOME = '/campanha/perfil' as const
diff --git a/src/lib/campaignQuickActionRegistry.ts b/src/lib/campaignQuickActionRegistry.ts
index 0e35e495..ba55f49a 100644
--- a/src/lib/campaignQuickActionRegistry.ts
+++ b/src/lib/campaignQuickActionRegistry.ts
@@ -23,6 +23,7 @@ import type { CampaignQuickAction } from '@/lib/campaignQuickActionTypes'
import type { CampaignRole } from '@/lib/campaignRoles'
import { resolveLeaderContactsQuickActions } from '@/lib/leaderContactsQuickActions'
import { resolveOrganizationQuickActions } from '@/lib/organizationQuickActions'
+import { resolveReferenceQuickActionsForPath, isReferenceQuickActionPath } from '@/lib/campaignReferenceQuickActions'
const isTerritoriesListPath = (pathname: string): boolean =>
pathname === CAMPAIGN_TERRITORIES_HOME || pathname.startsWith(`${CAMPAIGN_TERRITORIES_HOME}/`)
@@ -71,5 +72,9 @@ export const resolveQuickActionsForPath = (
if (isTerritoriesListPath(pathname)) {
return resolveStaffHomeQuickActions(role)
}
+
+ const referenceActions = resolveReferenceQuickActionsForPath(pathname, role, context)
+ if (isReferenceQuickActionPath(pathname)) return referenceActions
+
return []
}
diff --git a/src/lib/campaignReferenceQuickActions.ts b/src/lib/campaignReferenceQuickActions.ts
new file mode 100644
index 00000000..a9ede31e
--- /dev/null
+++ b/src/lib/campaignReferenceQuickActions.ts
@@ -0,0 +1,25 @@
+import { CAMPAIGN_CONCEPTS_PATH } from '@/lib/campaignIntelligenceConcepts'
+import type { CampaignQuickActionContext } from '@/lib/campaignQuickActionContext'
+import type { CampaignQuickAction } from '@/lib/campaignQuickActionTypes'
+import { CAMPAIGN_PROFILE_HOME } from '@/lib/campaignPaths'
+import { isStaffCampaignRole, type CampaignRole } from '@/lib/campaignRoles'
+
+export const isConceptsPath = (pathname: string): boolean =>
+ pathname === CAMPAIGN_CONCEPTS_PATH || pathname === `${CAMPAIGN_CONCEPTS_PATH}/`
+
+export const isProfilePath = (pathname: string): boolean =>
+ pathname === CAMPAIGN_PROFILE_HOME || pathname === `${CAMPAIGN_PROFILE_HOME}/`
+
+/** B90 — reference/account surfaces with search-only drawer (no action catalog). */
+export const isReferenceQuickActionPath = (pathname: string): boolean =>
+ isConceptsPath(pathname) || isProfilePath(pathname)
+
+export const resolveReferenceQuickActionsForPath = (
+ pathname: string,
+ role: CampaignRole,
+ _context: CampaignQuickActionContext,
+): readonly CampaignQuickAction[] => {
+ if (!isStaffCampaignRole(role)) return []
+ if (!isReferenceQuickActionPath(pathname)) return []
+ return []
+}
diff --git a/tests/unit/campaignQuickAction.unit.spec.ts b/tests/unit/campaignQuickAction.unit.spec.ts
index 30ef56bf..b8336100 100644
--- a/tests/unit/campaignQuickAction.unit.spec.ts
+++ b/tests/unit/campaignQuickAction.unit.spec.ts
@@ -34,6 +34,8 @@ import {
parseOrganizationQuickActionSurface,
} from '@/lib/campaignQuickActionPaths'
import { resolveQuickActionsForPath } from '@/lib/campaignQuickActionRegistry'
+import { CAMPAIGN_CONCEPTS_PATH } from '@/lib/campaignIntelligenceConcepts'
+import { CAMPAIGN_PROFILE_HOME } from '@/lib/campaignPaths'
import {
QUICK_ACTIONS_SNAP_COLLAPSED,
QUICK_ACTIONS_SNAP_EXPANDED,
@@ -86,9 +88,14 @@ describe('campaignQuickActionMount', () => {
expect(shouldMountQuickActionsDrawer('/campanha/assessores/12', 'advisor')).toBe(false)
})
+<<<<<<< HEAD
it('mounts on dobradinhas for staff (B83)', () => {
expect(shouldMountQuickActionsDrawer('/campanha/dobradinhas', 'coordinator')).toBe(true)
expect(shouldMountQuickActionsDrawer('/campanha/dobradinhas/foo', 'advisor')).toBe(true)
+=======
+ it('omits drawer on perfil for leader (B90)', () => {
+ expect(shouldMountQuickActionsDrawer(CAMPAIGN_PROFILE_HOME, 'leader')).toBe(false)
+>>>>>>> 2291493 (B90 — Ações rápidas Conceitos + Perfil (só busca staff))
})
})
@@ -253,6 +260,11 @@ describe('campaignQuickActionRegistry', () => {
expect(resolveQuickActionsForPath('/campanha/apoiadores', 'coordinator', {})).toEqual([])
})
+ it('returns empty catalog on conceitos and perfil for staff (B90)', () => {
+ expect(resolveQuickActionsForPath(CAMPAIGN_CONCEPTS_PATH, 'coordinator', {})).toEqual([])
+ expect(resolveQuickActionsForPath(CAMPAIGN_PROFILE_HOME, 'candidate', {})).toEqual([])
+ })
+
it('delegates municipality list and detail catalogs (B80)', () => {
const list = resolveQuickActionsForPath('/campanha/municipios', 'coordinator', {})
expect(list).toHaveLength(6)
diff --git a/tests/unit/campaignReferenceQuickActions.unit.spec.ts b/tests/unit/campaignReferenceQuickActions.unit.spec.ts
new file mode 100644
index 00000000..e639c473
--- /dev/null
+++ b/tests/unit/campaignReferenceQuickActions.unit.spec.ts
@@ -0,0 +1,45 @@
+import { describe, expect, it } from 'vitest'
+
+import { CAMPAIGN_CONCEPTS_PATH } from '@/lib/campaignIntelligenceConcepts'
+import { CAMPAIGN_PROFILE_HOME } from '@/lib/campaignPaths'
+import {
+ isConceptsPath,
+ isProfilePath,
+ isReferenceQuickActionPath,
+ resolveReferenceQuickActionsForPath,
+} from '@/lib/campaignReferenceQuickActions'
+
+describe('campaignReferenceQuickActions paths', () => {
+ it('matches conceitos exactly', () => {
+ expect(isConceptsPath(CAMPAIGN_CONCEPTS_PATH)).toBe(true)
+ expect(isConceptsPath(`${CAMPAIGN_CONCEPTS_PATH}/`)).toBe(true)
+ expect(isConceptsPath(`${CAMPAIGN_CONCEPTS_PATH}/foo`)).toBe(false)
+ })
+
+ it('matches perfil exactly', () => {
+ expect(isProfilePath(CAMPAIGN_PROFILE_HOME)).toBe(true)
+ expect(isProfilePath(`${CAMPAIGN_PROFILE_HOME}/`)).toBe(true)
+ expect(isProfilePath(`${CAMPAIGN_PROFILE_HOME}/editar`)).toBe(false)
+ })
+
+ it('groups reference surfaces', () => {
+ expect(isReferenceQuickActionPath(CAMPAIGN_CONCEPTS_PATH)).toBe(true)
+ expect(isReferenceQuickActionPath(CAMPAIGN_PROFILE_HOME)).toBe(true)
+ expect(isReferenceQuickActionPath('/campanha/municipios')).toBe(false)
+ })
+})
+
+describe('resolveReferenceQuickActionsForPath (B90)', () => {
+ it('returns empty catalog for staff on conceitos and perfil', () => {
+ expect(
+ resolveReferenceQuickActionsForPath(CAMPAIGN_CONCEPTS_PATH, 'coordinator', {}),
+ ).toEqual([])
+ expect(resolveReferenceQuickActionsForPath(CAMPAIGN_PROFILE_HOME, 'advisor', {})).toEqual([])
+ })
+
+ it('returns empty catalog for leader lockdown', () => {
+ expect(
+ resolveReferenceQuickActionsForPath(CAMPAIGN_PROFILE_HOME, 'leader', {}),
+ ).toEqual([])
+ })
+})