Template navigation and review/complete cleanup

This commit is contained in:
adilallo
2026-04-20 19:00:30 -06:00
parent 707d08642c
commit 2438c6f707
15 changed files with 836 additions and 355 deletions
@@ -1,13 +1,18 @@
"use client";
import { usePathname, useRouter } from "next/navigation";
import { useCallback } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useCallback, useLayoutEffect, useMemo } from "react";
import { useCreateFlow } from "../context/CreateFlowContext";
import type { CreateFlowStep } from "../types";
import {
type CreateFlowNavigationOptions,
buildTemplateReviewHref,
getNextStep,
getPreviousStep,
parseCreateFlowScreenFromPathname,
resolveCreateFlowBackTarget,
TEMPLATE_REVIEW_FROM_CREATE_FLOW_QUERY,
TEMPLATE_REVIEW_FROM_CREATE_FLOW_VALUE,
} from "../utils/flowSteps";
/**
@@ -25,7 +30,15 @@ const blurActiveElement = (): void => {
/**
* Hook for Create Rule Flow navigation.
*
* Resolves the active step from `/create/{screenId}` via {@link parseCreateFlowScreenFromPathname} (flowSteps).
* Resolves the active step from `/create/{screenId}` via
* {@link parseCreateFlowScreenFromPathname} (flowSteps). Footer Back uses
* {@link resolveCreateFlowBackTarget} so template **Use without changes**
* (which skips the custom-rule segment) returns to `/create/review-template/{slug}`
* from `confirm-stakeholders` instead of `conflict-management`.
*
* Template review footer Back uses {@link buildTemplateReviewHref}s
* `?fromFlow=1` marker (and persisted `templateReviewEntryFromCreateFlow`) so
* users who came from `/create/review` return there instead of `/`.
*/
export function useCreateFlowNavigation(
options?: CreateFlowNavigationOptions,
@@ -38,15 +51,46 @@ export function useCreateFlowNavigation(
canGoBack: () => boolean;
nextStep: CreateFlowStep | null;
previousStep: CreateFlowStep | null;
/** On `/create/review-template/…`, footer Back should go to `/create/review`. */
templateReviewFooterBackToCreateReview: boolean;
} {
const pathname = usePathname();
const searchParams = useSearchParams();
const router = useRouter();
const { state, updateState } = useCreateFlow();
const validStep = parseCreateFlowScreenFromPathname(pathname ?? null);
useLayoutEffect(() => {
if (!pathname?.includes("/create/review-template/")) return;
if (
searchParams.get(TEMPLATE_REVIEW_FROM_CREATE_FLOW_QUERY) !==
TEMPLATE_REVIEW_FROM_CREATE_FLOW_VALUE
) {
return;
}
if (state.templateReviewEntryFromCreateFlow === true) return;
updateState({ templateReviewEntryFromCreateFlow: true });
}, [
pathname,
searchParams,
state.templateReviewEntryFromCreateFlow,
updateState,
]);
const nextStep = getNextStep(validStep, options);
const previousStep = getPreviousStep(validStep, options);
const backTarget = useMemo(
() =>
resolveCreateFlowBackTarget(
validStep,
options,
state.templateReviewBackSlug,
),
[validStep, options?.skipCommunitySave, state.templateReviewBackSlug],
);
const goToNextStep = useCallback(() => {
blurActiveElement();
if (nextStep) {
@@ -56,10 +100,26 @@ export function useCreateFlowNavigation(
const goToPreviousStep = useCallback(() => {
blurActiveElement();
if (previousStep) {
router.push(`/create/${previousStep}`);
if (!backTarget) return;
if (backTarget.kind === "templateReview") {
router.push(
buildTemplateReviewHref(backTarget.slug, {
fromCreateWizard: state.templateReviewEntryFromCreateFlow === true,
}),
);
return;
}
}, [router, previousStep]);
router.push(`/create/${backTarget.step}`);
}, [router, backTarget, state.templateReviewEntryFromCreateFlow]);
const templateReviewFooterBackToCreateReview = useMemo(
() =>
Boolean(state.templateReviewEntryFromCreateFlow) ||
(pathname?.includes("/create/review-template/") &&
searchParams.get(TEMPLATE_REVIEW_FROM_CREATE_FLOW_QUERY) ===
TEMPLATE_REVIEW_FROM_CREATE_FLOW_VALUE),
[state.templateReviewEntryFromCreateFlow, pathname, searchParams],
);
const goToStep = useCallback(
(step: CreateFlowStep) => {
@@ -70,7 +130,7 @@ export function useCreateFlowNavigation(
);
const canGoNext = useCallback(() => nextStep !== null, [nextStep]);
const canGoBack = useCallback(() => previousStep !== null, [previousStep]);
const canGoBack = useCallback(() => backTarget != null, [backTarget]);
return {
currentStep: validStep,
@@ -81,5 +141,6 @@ export function useCreateFlowNavigation(
canGoBack,
nextStep,
previousStep,
templateReviewFooterBackToCreateReview,
};
}