Let Use without changes from a template collect identity instead of the full questionnaire.
Direct catalog picks walk name, description, and photo, then stakeholders; leftover drafts no longer skip that path. In-flow template picks keep community identity. Exit on a direct template preview leaves immediately because nothing has been collected yet. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -47,8 +47,44 @@ export const FIRST_STEP: CreateFlowStep = FLOW_STEP_ORDER[0];
|
||||
/** Options for navigation when the email / magic-link save step is not shown (signed-in users). */
|
||||
export type CreateFlowNavigationOptions = {
|
||||
skipCommunitySave?: boolean;
|
||||
/**
|
||||
* Template **Use without changes**: collect community name, description, and
|
||||
* optional photo only. Skips intro, structure, size, save, community review,
|
||||
* and the custom-rule authoring segment.
|
||||
*/
|
||||
useWithoutChangesIdentityOnly?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Community + custom-rule steps skipped when
|
||||
* {@link CreateFlowNavigationOptions.useWithoutChangesIdentityOnly} is set.
|
||||
* Remaining identity steps: `community-name` → `community-context` →
|
||||
* `community-upload`, then `confirm-stakeholders`.
|
||||
*/
|
||||
const USE_WITHOUT_CHANGES_IDENTITY_SKIP = new Set<CreateFlowStep>([
|
||||
"informational",
|
||||
"community-structure",
|
||||
"community-size",
|
||||
"community-save",
|
||||
"review",
|
||||
"core-values",
|
||||
"communication-methods",
|
||||
"membership-methods",
|
||||
"decision-approaches",
|
||||
"conflict-management",
|
||||
]);
|
||||
|
||||
function shouldSkipStep(
|
||||
step: CreateFlowStep,
|
||||
options?: CreateFlowNavigationOptions,
|
||||
): boolean {
|
||||
if (options?.skipCommunitySave && step === "community-save") return true;
|
||||
return Boolean(
|
||||
options?.useWithoutChangesIdentityOnly &&
|
||||
USE_WITHOUT_CHANGES_IDENTITY_SKIP.has(step),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next step in the flow, or null if current is last/invalid
|
||||
*/
|
||||
@@ -57,13 +93,14 @@ export function getNextStep(
|
||||
options?: CreateFlowNavigationOptions,
|
||||
): CreateFlowStep | null {
|
||||
if (!currentStep) return null;
|
||||
const index = FLOW_STEP_ORDER.indexOf(currentStep);
|
||||
if (index === -1 || index === FLOW_STEP_ORDER.length - 1) return null;
|
||||
const next = FLOW_STEP_ORDER[index + 1] as CreateFlowStep;
|
||||
if (options?.skipCommunitySave && next === "community-save") {
|
||||
return getNextStep("community-save", options);
|
||||
let index = FLOW_STEP_ORDER.indexOf(currentStep);
|
||||
if (index === -1) return null;
|
||||
while (index < FLOW_STEP_ORDER.length - 1) {
|
||||
index += 1;
|
||||
const next = FLOW_STEP_ORDER[index] as CreateFlowStep;
|
||||
if (!shouldSkipStep(next, options)) return next;
|
||||
}
|
||||
return next;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,20 +111,27 @@ export function getPreviousStep(
|
||||
options?: CreateFlowNavigationOptions,
|
||||
): CreateFlowStep | null {
|
||||
if (!currentStep) return null;
|
||||
const index = FLOW_STEP_ORDER.indexOf(currentStep);
|
||||
let index = FLOW_STEP_ORDER.indexOf(currentStep);
|
||||
if (index <= 0) return null;
|
||||
const prev = FLOW_STEP_ORDER[index - 1] as CreateFlowStep;
|
||||
if (options?.skipCommunitySave && prev === "community-save") {
|
||||
return getPreviousStep("community-save", options);
|
||||
while (index > 0) {
|
||||
index -= 1;
|
||||
const prev = FLOW_STEP_ORDER[index] as CreateFlowStep;
|
||||
if (!shouldSkipStep(prev, options)) return prev;
|
||||
}
|
||||
return prev;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Where the create-flow footer Back action should go. Usually the previous
|
||||
* step in {@link FLOW_STEP_ORDER}; when the user reached `confirm-stakeholders`
|
||||
* via template **Use without changes**, Back returns to template review instead
|
||||
* of `conflict-management` (that segment was skipped).
|
||||
* step in {@link FLOW_STEP_ORDER}.
|
||||
*
|
||||
* Template **Use without changes** exceptions:
|
||||
* - Direct from a template (`useWithoutChangesIdentityOnly`): Back from
|
||||
* `community-name` returns to template review; Back from
|
||||
* `confirm-stakeholders` is `community-upload`.
|
||||
* - In-flow (`?fromFlow=1`, community identity already collected): Back
|
||||
* from `confirm-stakeholders` returns to template review instead of
|
||||
* `conflict-management`.
|
||||
*/
|
||||
export type CreateFlowBackTarget =
|
||||
| { kind: "step"; step: CreateFlowStep }
|
||||
@@ -102,7 +146,18 @@ export function resolveCreateFlowBackTarget(
|
||||
typeof templateReviewBackSlug === "string"
|
||||
? templateReviewBackSlug.trim()
|
||||
: "";
|
||||
if (currentStep === "confirm-stakeholders" && slug.length > 0) {
|
||||
if (
|
||||
currentStep === "community-name" &&
|
||||
options?.useWithoutChangesIdentityOnly &&
|
||||
slug.length > 0
|
||||
) {
|
||||
return { kind: "templateReview", slug };
|
||||
}
|
||||
if (
|
||||
currentStep === "confirm-stakeholders" &&
|
||||
slug.length > 0 &&
|
||||
!options?.useWithoutChangesIdentityOnly
|
||||
) {
|
||||
return { kind: "templateReview", slug };
|
||||
}
|
||||
const prev = getPreviousStep(currentStep, options);
|
||||
@@ -194,6 +249,22 @@ export function parseCreateFlowScreenFromPathname(
|
||||
export const TEMPLATE_REVIEW_FROM_CREATE_FLOW_QUERY = "fromFlow" as const;
|
||||
export const TEMPLATE_REVIEW_FROM_CREATE_FLOW_VALUE = "1" as const;
|
||||
|
||||
/**
|
||||
* Catalog / marketing template preview (`/create/review-template/[slug]`
|
||||
* without `?fromFlow=1`). There is nothing to save yet; top-nav Exit should
|
||||
* leave immediately. In-flow picks keep the usual save / leave-confirm path.
|
||||
*/
|
||||
export function isDirectTemplateReviewEntry(
|
||||
pathname: string | null | undefined,
|
||||
searchParams?: { get: (name: string) => string | null } | null,
|
||||
): boolean {
|
||||
if (!pathname?.includes("/create/review-template/")) return false;
|
||||
return (
|
||||
searchParams?.get(TEMPLATE_REVIEW_FROM_CREATE_FLOW_QUERY) !==
|
||||
TEMPLATE_REVIEW_FROM_CREATE_FLOW_VALUE
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only set from `/create/review` “Create from template” with `fromFlow=1`.
|
||||
* Enables facet-ranked `GET /api/templates` + “RECOMMENDED” on the grid; omit
|
||||
|
||||
Reference in New Issue
Block a user