teqo/src/lib/activityQuickActions.ts

167 lines
4.9 KiB
TypeScript

import {
Calendar,
CalendarCog,
ClipboardList,
ListChecks,
MapPinned,
Pencil,
Plus,
} from 'lucide-react'
import {
CAMPAIGN_WIZARD_ACTION_SLUGS,
wizardActionHref,
type CampaignWizardActionId,
} from '@/lib/campaignActionRoutes'
import { homeActionsForRole, toHomeActionButtonProps } from '@/lib/campaignHomeActions'
import type { CampaignQuickActionContext } from '@/lib/campaignQuickActionContext'
import {
ACTIVITY_TOUR_COMPOSER_PATH,
type ActivityQuickActionSurface,
} from '@/lib/campaignQuickActionPaths'
import type { CampaignQuickAction } from '@/lib/campaignQuickActionTypes'
import { isStaffCampaignRole, type CampaignRole } from '@/lib/campaignRoles'
const WIZARD_ACTION_IDS: readonly CampaignWizardActionId[] = [
'update-votes',
'register-update',
'change-trend',
'update-leadership',
'register-demand',
]
const listQuickActions = (context: CampaignQuickActionContext): readonly CampaignQuickAction[] => [
// C123 — the create surface is the agenda overlay; the FAB opens it via the
// page-bridged context (same pattern as openCalendarFeed/openGoogleCalendarSync).
// Conditional like the dialog neighbors: while the bridge is not registered
// yet (initial load), the entry must not render as a dead button.
...(context.openActivityCreate
? [
{
id: 'new-activity',
label: 'Nova atividade',
icon: Plus,
description: 'Criar caminhada, comício, panfletagem ou outra ação de campanha',
onAction: context.openActivityCreate,
},
]
: []),
...(context.openCalendarFeed
? [
{
id: 'import-calendar',
label: 'Link de import',
icon: Calendar,
description: 'Gerar link para sincronizar a agenda com o Google Calendar',
onAction: context.openCalendarFeed,
},
]
: []),
...(context.openGoogleCalendarSync
? [
{
id: 'google-calendar-mirror',
label: 'Agenda da Campanha',
icon: CalendarCog,
description: 'Espelhar a agenda oficial no Google Calendar da campanha',
onAction: context.openGoogleCalendarSync,
},
]
: []),
{
id: 'plan-tour',
label: 'Planejar giro',
icon: MapPinned,
description: 'Compor um giro por território e gerar rascunhos de atividade',
href: ACTIVITY_TOUR_COMPOSER_PATH,
},
]
const wizardActionsWithMunicipalityPrefill = (
role: CampaignRole,
municipalitySlug: string,
returnPath: string,
): readonly CampaignQuickAction[] => {
const homeActions = homeActionsForRole(role).filter((action) =>
WIZARD_ACTION_IDS.includes(action.id as CampaignWizardActionId),
)
return toHomeActionButtonProps(homeActions).map((action) => {
const wizardId = action.id as CampaignWizardActionId
return {
id: action.id,
label: action.label,
icon: action.icon,
description: action.description,
href: wizardActionHref(CAMPAIGN_WIZARD_ACTION_SLUGS[wizardId], municipalitySlug, {
returnPath,
}),
}
})
}
const detailVerticalQuickActions = (
activitySlug: string,
context: CampaignQuickActionContext,
): readonly CampaignQuickAction[] => {
const base = `/campanha/atividades/${activitySlug}`
const actions: CampaignQuickAction[] = [
// C123 — set by the detail page bridge (opens the edit overlay). Conditional
// like the list entry: no dead "Editar" while the bridge is not registered.
...(context.openActivityEdit
? [
{
id: 'edit-activity',
label: 'Editar',
icon: Pencil,
description: 'Abrir o formulário completo da atividade',
onAction: context.openActivityEdit,
},
]
: []),
{
id: 'activity-tasks',
label: 'Tarefas',
icon: ListChecks,
description: 'Ver e marcar o checklist desta atividade',
href: `${base}?tab=tasks`,
},
{
id: 'activity-updates',
label: 'Atualizações',
icon: ClipboardList,
description: 'Registrar ou revisar o feed de atualizações',
href: `${base}?tab=updates`,
},
]
return actions
}
export const resolveActivityQuickActions = (
surface: ActivityQuickActionSurface,
role: CampaignRole,
context: CampaignQuickActionContext,
pathname?: string,
): readonly CampaignQuickAction[] => {
if (!isStaffCampaignRole(role)) return []
if (surface.kind === 'list') {
return listQuickActions(context)
}
const activitySlug = context.activitySlug ?? surface.activitySlug
const municipalitySlug = context.municipalitySlug
const returnPath = pathname ?? `/campanha/atividades/${activitySlug}`
const detailActions = detailVerticalQuickActions(activitySlug, context)
if (!municipalitySlug) {
return detailActions
}
return [
...wizardActionsWithMunicipalityPrefill(role, municipalitySlug, returnPath),
...detailActions,
]
}