chore: format B145 detail pages

This commit is contained in:
Cursor Agent 2026-08-02 23:17:17 +00:00
parent 9bcbfaf96d
commit 33d2e5ba01
No known key found for this signature in database
9 changed files with 24 additions and 33 deletions

View file

@ -23,6 +23,7 @@ flowchart LR
```
**Opções consideradas:**
- A) Estender `resolveCampaignPageChrome` com dados de entidade (impossível — catálogo é estático/client-safe)
- B) `SetCampaignPageChrome` + `generateMetadata` por rota (precedente edit routes)
- C) Novo provider server-side de chrome
@ -41,16 +42,16 @@ flowchart LR
### Mapeamento chrome por rota
| Rota | title | subtitle |
| ---- | ----- | -------- |
| municipios/[slug] | view.name | formatMunicipalityGeographyLabel(view) |
| liderancas/[id] | Liderança | leadership.name |
| atividades/[slug] | view.title | view.locationLabel ou municipality.name |
| demandas/[slug] | demand.title | `${kind} · ${municipalityName}` |
| dobradinhas/[slug] | stateDeputy.name | party (opcional) |
| organizacoes/[slug] | organization.name | organizationKindLabels[kind] |
| apoiadores/[id] | Apoiador | supporter.name |
| assessores/[id] | Assessor | advisor.name |
| Rota | title | subtitle |
| ------------------- | ----------------- | --------------------------------------- |
| municipios/[slug] | view.name | formatMunicipalityGeographyLabel(view) |
| liderancas/[id] | Liderança | leadership.name |
| atividades/[slug] | view.title | view.locationLabel ou municipality.name |
| demandas/[slug] | demand.title | `${kind} · ${municipalityName}` |
| dobradinhas/[slug] | stateDeputy.name | party (opcional) |
| organizacoes/[slug] | organization.name | organizationKindLabels[kind] |
| apoiadores/[id] | Apoiador | supporter.name |
| assessores/[id] | Assessor | advisor.name |
## Fases verificáveis

View file

@ -6,10 +6,10 @@ import { getPayload } from 'payload'
import { setSupporterVoteIntentionFormAction } from '@/app/(campaign)/campanha/(app)/apoiadores/[id]/formActions'
import { ConsentText } from '@/components/campaign/shared/ConsentText'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { RemoveSupporterDataButton } from '@/components/campaign/supporter/RemoveSupporterDataButton'
import { SupporterShareKit } from '@/components/campaign/supporter/SupporterShareKit'
import { VoteIntentionControl } from '@/components/campaign/supporter/VoteIntentionControl'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { Badge } from '@/components/ui/Badge'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { campaignPageMetadata } from '@/lib/campaignPageChrome'

View file

@ -6,8 +6,8 @@ import { getPayload } from 'payload'
import { AdvisorDebouncedTextCell } from '@/components/campaign/advisor/AdvisorDebouncedTextCell'
import { AdvisorPasswordResetButton } from '@/components/campaign/advisor/AdvisorPasswordResetButton'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { Badge } from '@/components/ui/Badge'
import { campaignPageMetadata } from '@/lib/campaignPageChrome'
import { formatBrazilianPhoneInput } from '@/lib/phone'

View file

@ -13,8 +13,8 @@ import { ActivityTabNav } from '@/components/campaign/activity/ActivityTabNav'
import { ActivityTaskChecklist } from '@/components/campaign/activity/ActivityTaskChecklist'
import { ActivityUpdateFeed } from '@/components/campaign/activity/ActivityUpdateFeed'
import { ActivityUpdateForm } from '@/components/campaign/activity/ActivityUpdateForm'
import { CampaignQuickActionContextBridge } from '@/components/campaign/shell/CampaignQuickActionContextBridge'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { CampaignQuickActionContextBridge } from '@/components/campaign/shell/CampaignQuickActionContextBridge'
import { Badge } from '@/components/ui/Badge'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
@ -50,9 +50,7 @@ export async function generateMetadata({ params }: ActivityDetailPageProps) {
const context = await resolveAccessibleActivityContext(payload, user, slug, activeTab)
const view = await getActivityDetailPageData(payload, user, context, activeTab, 1)
const subtitle = view.locationLabel || view.municipality?.name
return campaignPageMetadata(
subtitle ? { title: view.title, subtitle } : { title: view.title },
)
return campaignPageMetadata(subtitle ? { title: view.title, subtitle } : { title: view.title })
} catch {
return campaignPageMetadata({ title: 'Atividade' })
}
@ -100,9 +98,7 @@ export default async function ActivityDetailPage({
<div className="mx-auto flex w-full max-w-6xl flex-col gap-6">
<SetCampaignPageChrome
chrome={
chromeSubtitle
? { title: view.title, subtitle: chromeSubtitle }
: { title: view.title }
chromeSubtitle ? { title: view.title, subtitle: chromeSubtitle } : { title: view.title }
}
/>
<CampaignQuickActionContextBridge

View file

@ -5,9 +5,9 @@ import { notFound } from 'next/navigation'
import { getPayload } from 'payload'
import { DemandWorkflowCard } from '@/components/campaign/demand/DemandWorkflowCard'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { CampaignQuickActionContextSync } from '@/components/campaign/shell/CampaignQuickActionContextSync'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { Badge } from '@/components/ui/Badge'
import { campaignPageMetadata } from '@/lib/campaignPageChrome'
import {

View file

@ -4,8 +4,8 @@ import Link from 'next/link'
import { notFound } from 'next/navigation'
import { getPayload } from 'payload'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { StateDeputyForm } from '@/components/campaign/stateDeputy/StateDeputyForm'
import { Badge } from '@/components/ui/Badge'
import { campaignPageMetadata } from '@/lib/campaignPageChrome'

View file

@ -5,9 +5,9 @@ import { getPayload } from 'payload'
import { LeadershipInviteButtons } from '@/components/campaign/invite/LeadershipInviteButtons'
import { LeadershipInternalForm } from '@/components/campaign/leadership/LeadershipInternalForm'
import { SupportStatusBadge } from '@/components/campaign/leadership/SupportStatusBadge'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { CampaignQuickActionContextSync } from '@/components/campaign/shell/CampaignQuickActionContextSync'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { StateDeputyChips } from '@/components/campaign/stateDeputy/StateDeputyChips'
import { Badge } from '@/components/ui/Badge'
import { campaignPageMetadata } from '@/lib/campaignPageChrome'
@ -75,9 +75,7 @@ export default async function LeadershipDetailPage({ params }: LeadershipDetailP
municipalitySlug={singleMunicipalitySlug}
/>
<div className="flex flex-wrap items-center gap-2">
{leadership.supportStatus ? (
<SupportStatusBadge status={leadership.supportStatus} />
) : null}
{leadership.supportStatus ? <SupportStatusBadge status={leadership.supportStatus} /> : null}
<Badge variant={leadership.hasAppAccess ? 'estimate-confirmed' : 'outline'}>
{leadership.hasAppAccess ? 'Com acesso ao app' : 'Sem acesso ao app'}
</Badge>

View file

@ -6,17 +6,15 @@ import { Suspense } from 'react'
import { RecentVisitTracker } from '@/components/campaign/dashboard/RecentVisitTracker'
import { MunicipalityTabNav } from '@/components/campaign/municipality/MunicipalityTabNav'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { campaignPageMetadata } from '@/lib/campaignPageChrome'
import { requireCampaignPageActor } from '@/utilities/campaignPageActor'
import {
resolveMunicipalityDetailTab,
type MunicipalityDetailSearchParams,
} from '@/utilities/municipality/municipalityDetailTabUi'
import {
formatMunicipalityGeographyLabel,
} from '@/utilities/municipality/municipalityLabels'
import { formatMunicipalityGeographyLabel } from '@/utilities/municipality/municipalityLabels'
import {
getMunicipalityDetailViewModel,
MunicipalityNotFoundError,

View file

@ -6,8 +6,8 @@ import { getPayload } from 'payload'
import { ActivityStatusBadge } from '@/components/campaign/activity/ActivityStatusBadge'
import { OrganizationForm } from '@/components/campaign/organization/OrganizationForm'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { SetCampaignPageChrome } from '@/components/campaign/shell/CampaignPageChromeContext'
import { CampaignPageShell } from '@/components/campaign/shell/CampaignPageShell'
import { Badge } from '@/components/ui/Badge'
import { campaignPageMetadata } from '@/lib/campaignPageChrome'
import { organizationKindLabels } from '@/lib/schemas/organization'
@ -59,9 +59,7 @@ export default async function OrganizationDetailPage({ params }: OrganizationDet
}}
/>
{organization.municipalityNames.length ? (
<p className="text-muted-foreground">
Atua em {organization.municipalityNames.join(', ')}
</p>
<p className="text-muted-foreground">Atua em {organization.municipalityNames.join(', ')}</p>
) : null}
{organization.notes ? (
<p className="whitespace-pre-wrap text-sm text-muted-foreground">{organization.notes}</p>