diff --git a/src/app/(campaign)/campanha/(app)/acoes/[slug]/page.tsx b/src/app/(campaign)/campanha/(app)/acoes/[slug]/page.tsx index 2a6b42dd..11a460d0 100644 --- a/src/app/(campaign)/campanha/(app)/acoes/[slug]/page.tsx +++ b/src/app/(campaign)/campanha/(app)/acoes/[slug]/page.tsx @@ -35,7 +35,7 @@ import { CAMPAIGN_HOME } from '@/lib/campaignPaths' import { buildPoliticalTrendNotePrefill, resolvePoliticalTrendNotePrefillSource, - selectablePoliticalTrendStatuses, + resolveWizardTrendNoteDestination, } from '@/lib/politicalTrendWizardUi' import { toVoteEstimateScenarioViewModel } from '@/lib/voteEstimate' import config from '@/payload.config' @@ -189,10 +189,13 @@ export default async function CampaignActionWizardPage({ } if (trendStatus) { - if ( - trendStatus === currentStatus || - !selectablePoliticalTrendStatuses(currentStatus).includes(trendStatus) - ) { + const noteDestination = resolveWizardTrendNoteDestination(trendStatus, currentStatus) + + if (noteDestination === 'home') { + redirect(CAMPAIGN_HOME) + } + + if (noteDestination === 'choice') { redirect( wizardTrendHref(slug, municipalitySlug, undefined, entryAction, prefillExtraParams), ) diff --git a/src/components/campaign/municipality/WizardTrendNoteStep.tsx b/src/components/campaign/municipality/WizardTrendNoteStep.tsx index 5f340734..2f897973 100644 --- a/src/components/campaign/municipality/WizardTrendNoteStep.tsx +++ b/src/components/campaign/municipality/WizardTrendNoteStep.tsx @@ -54,7 +54,7 @@ export const WizardTrendNoteStep = ({ useCampaignFormSuccessToast(state, () => { recordLastActedMunicipality(municipalitySlug) - router.push(CAMPAIGN_HOME) + router.replace(CAMPAIGN_HOME) }) return ( diff --git a/src/lib/politicalTrendWizardUi.ts b/src/lib/politicalTrendWizardUi.ts index e2a160b7..8dcae59f 100644 --- a/src/lib/politicalTrendWizardUi.ts +++ b/src/lib/politicalTrendWizardUi.ts @@ -41,6 +41,28 @@ export const selectablePoliticalTrendStatuses = ( ? politicalTrendStatuses.filter((status) => status !== currentStatus) : [...politicalTrendStatuses] +/** Where the change-trend wizard should land when `tendencia=` is present. */ +export type WizardTrendNoteDestination = 'note' | 'choice' | 'home' + +/** + * `home` when the query trend already matches the persisted status — covers + * post-save RSC refresh (B97) and stale deep-links; never loops back to choice. + */ +export const resolveWizardTrendNoteDestination = ( + trendStatus: PoliticalTrendStatusValue, + currentStatus: PoliticalTrendStatusValue | null, +): WizardTrendNoteDestination => { + if (trendStatus === currentStatus) { + return 'home' + } + + if (!selectablePoliticalTrendStatuses(currentStatus).includes(trendStatus)) { + return 'choice' + } + + return 'note' +} + export const resolveWizardTrendSkip = (): WizardTrendSkipAction => ({ label: WIZARD_TREND_SKIP_LABEL, href: CAMPAIGN_HOME, diff --git a/tests/unit/politicalTrendWizardUi.unit.spec.ts b/tests/unit/politicalTrendWizardUi.unit.spec.ts index 7572c077..95f0d3a7 100644 --- a/tests/unit/politicalTrendWizardUi.unit.spec.ts +++ b/tests/unit/politicalTrendWizardUi.unit.spec.ts @@ -8,6 +8,7 @@ import { import { buildPoliticalTrendNotePrefill, resolvePoliticalTrendNotePrefillSource, + resolveWizardTrendNoteDestination, resolveWizardTrendSkip, selectablePoliticalTrendStatuses, WIZARD_TREND_SKIP_LABEL, @@ -28,6 +29,12 @@ describe('politicalTrendWizardUi', () => { expect(selectablePoliticalTrendStatuses('desfavoravel')).toEqual(['favoravel', 'neutra']) }) + it('resolves the note-step destination without looping to choice after save', () => { + expect(resolveWizardTrendNoteDestination('favoravel', 'neutra')).toBe('note') + expect(resolveWizardTrendNoteDestination('favoravel', 'favoravel')).toBe('home') + expect(resolveWizardTrendNoteDestination('favoravel', null)).toBe('note') + }) + it('always exposes skip to abandon the trend change', () => { expect(resolveWizardTrendSkip()).toEqual({ label: WIZARD_TREND_SKIP_LABEL,