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:
+12
-4
@@ -79,9 +79,17 @@ Call sites for **`prepareFreshCreateFlowEntry`**: [`Top.container.tsx`](../app/c
|
||||
|
||||
From that page, **Customize** pre-fills the custom-rule selections on the current `CreateFlowState` (via [`buildTemplateCustomizePrefill`](../lib/create/applyTemplatePrefill.ts)) and routes to **`/create/core-values`** when the community name (`state.title`) is already set, otherwise to **`/create/informational`**. Name-only is the gate because other community-stage fields (e.g. `communityStructureChipSnapshots`) are sticky once the user lands on those screens; a non-empty title is also the minimum bar [`buildPublishPayload`](../lib/create/buildPublishPayload.ts) enforces, so the two checks stay aligned. No query-param plumbing: state persists via the usual anonymous/server-draft mirrors.
|
||||
|
||||
**Use without changes** writes the template's `body.sections` into `state.sections` (chip titles only; bodies are empty in seeded templates), resets any prior Customize chip selections so they don't bleed into `document.coreValues`, and routes to **`/create/confirm-stakeholders`**. It does **not** copy the template catalog `description` into `state.summary` — the published rule summary comes from **`communityContext` first**, then `summary`, when the user publishes. At publish, [`buildPublishPayload`](../lib/create/buildPublishPayload.ts) derives `methodSelections` from those section titles, merges preset copy into `document.sections`, and emits structured `methodSelections`. The user then exits via the normal **`final-review → handleFinalize → publishRule`** pipeline. Guests can publish without signing in (`POST /api/rules` with `userId` null); stakeholder invites are sent only when a session exists.
|
||||
**Exit on template preview.** Direct catalog / marketing entry (`/create/review-template/[slug]` without `?fromFlow=1`) has nothing to save — top-nav **Exit** clears client state and goes home, with no save-progress modal and no leave confirm. In-flow (`?fromFlow=1`) still has community progress, so Exit keeps the usual save / leave-confirm path.
|
||||
|
||||
**Entering a template before community stage is done.** When `state.title` is empty, both handlers apply their side effects eagerly (prefill for Customize; `sections` for Use without changes) *and* pin a `pendingTemplateAction: { slug, mode }` on `CreateFlowState` before routing to `/create/informational`. Once the user reaches `/create/review`, [`CommunityReviewScreen`](../app/(app)/create/screens/review/CommunityReviewScreen.tsx) reads the action on mount, clears it via `updateState`, and `router.replace`s past itself — to `/create/core-values` for `customize`, `/create/confirm-stakeholders` for `useWithoutChanges`. The user never sees the community-review page in that flow because their intent was already expressed at the template-review step. `replace` (not `push`) keeps `community-save` as the Back-button target from the destination. The action is cleared on the first fire so later direct visits to `/create/review` render normally.
|
||||
**Use without changes** writes the template's `body.sections` into `state.sections` (chip titles only; bodies are empty in seeded templates), resets any prior Customize chip selections so they don't bleed into `document.coreValues`, and skips custom-rule authoring. It does **not** copy the template catalog `description` into `state.summary` — the published rule summary comes from **`communityContext` first**, then `summary`, when the user publishes. At publish, [`buildPublishPayload`](../lib/create/buildPublishPayload.ts) derives `methodSelections` from those section titles, merges preset copy into `document.sections`, and emits structured `methodSelections`. The user then exits via the normal **`final-review → handleFinalize → publishRule`** pipeline. Guests can publish without signing in (`POST /api/rules` with `userId` null); stakeholder invites are sent only when a session exists.
|
||||
|
||||
**Entering a template before community stage is done.** Both handlers apply their side effects eagerly (prefill for Customize; `sections` for Use without changes) *and* pin a `pendingTemplateAction: { slug, mode }` when the community questionnaire still needs to run.
|
||||
|
||||
- **Customize** routes to `/create/informational` and walks the full Create Community questionnaire. Once the user reaches `/create/review`, [`CommunityReviewScreen`](../app/(app)/create/screens/review/CommunityReviewScreen.tsx) reads the action on mount, clears it via `updateState`, and `router.replace`s to `/create/core-values`. `replace` (not `push`) keeps `community-save` as the Back-button target from that destination.
|
||||
- **Use without changes (direct from a template)** — home Popular templates, `/templates` without `fromFlow`, or a pasted review-template URL. Always routes to `/create/community-name` and walks **name → description → optional photo**, then `/create/confirm-stakeholders`. A leftover draft title is **not** “community already done”; those identity fields are cleared so cache cannot skip or pre-fill the path. Intro, structure, size, save, community review, and custom-rule authoring are skipped. Back from name returns to template review.
|
||||
- **Use without changes (in-flow)** — `/create/review` → `/templates?fromFlow=1` → template. Community identity is already collected, so this action seeds the template and routes to `/create/confirm-stakeholders`. Back returns to template review.
|
||||
|
||||
The action for Customize is cleared on the first fire so later direct visits to `/create/review` render normally. The review screen is not part of the Use-without-changes identity path. If they land on `/create/review` with a leftover Use-without-changes pin, the screen `replace`s to `community-name`.
|
||||
|
||||
**Direct entry vs in-flow template pick.** The same `/create/review-template/[slug]` URL is reached from two different origins. We disambiguate at the *click site*, not on the review-template page. **Direct** picks call [`prepareFreshCreateFlowEntry`](../app/(app)/create/utils/prepareFreshCreateFlowEntry.ts) **before** navigation (local + server draft when sync is on — see **Fresh start vs continue draft** above). **In-flow** picks skip that call so the user’s community-stage state survives the detour. Because `CreateFlowProvider` reads `localStorage` in its `useState` initializer, clearing **before** `push` means a direct entry mounts without stale anonymous keys; signed-in users also avoid a stale server draft overwriting the empty mirror.
|
||||
|
||||
@@ -89,9 +97,9 @@ From that page, **Customize** pre-fills the custom-rule selections on the curren
|
||||
| --- | --- | --- |
|
||||
| Home marketing "Popular templates" ([`RuleStack.container.tsx`](../app/components/sections/RuleStack/RuleStack.container.tsx)) | always `await prepareFreshCreateFlowEntry()` then navigate | `/create/review-template/[slug]` |
|
||||
| `/templates` index ([`TemplatesPageClient.tsx`](../app/(marketing)/templates/TemplatesPageClient.tsx)) visited directly / via pasted URL | `fromFlow` absent → `await prepareFreshCreateFlowEntry()` then navigate | `/create/review-template/[slug]` |
|
||||
| In-flow: `/create/review` footer "Create from template" → `/templates?fromFlow=1` → template click | `fromFlow=1` → no fresh-entry prep | `/create/review-template/[slug]` |
|
||||
| In-flow: `/create/review` footer "Create from template" → `/templates?fromFlow=1` → template click | `fromFlow=1` → no fresh-entry prep | `/create/review-template/[slug]?fromFlow=1` |
|
||||
|
||||
Only one `?fromFlow=1` marker exists, on one hop (`/create/review` → `/templates`). It is not forwarded onto the review-template URL. The review-template handlers branch solely on `state.title` — they don't need to know the origin.
|
||||
Only one `?fromFlow=1` marker exists on `/templates`. Template clicks forward it onto `/create/review-template/[slug]?fromFlow=1` so **Use without changes** can tell in-flow (skip identity) from a direct catalog start (collect name / description / photo). **Customize** still branches on `state.title` (full questionnaire vs `core-values`).
|
||||
|
||||
**Resume from profile** remains explicit-only: **Continue** clears local mirrors then opens `/create/{step}` so [`SignedInDraftHydration`](../app/(app)/create/SignedInDraftHydration.tsx) can load `/api/drafts/me` when the client buffer is empty. There is no automatic “pick template from marketing → silently merge server draft” path.
|
||||
|
||||
|
||||
@@ -255,8 +255,13 @@ now prefills the custom-rule flow via
|
||||
[`buildTemplateCustomizePrefill`](../../lib/create/applyTemplatePrefill.ts)
|
||||
(applied in `CreateFlowLayoutClient.tsx`) and routes to `core-values`
|
||||
when Community already has input, else to `informational`. Template **Use
|
||||
without changes** writes `template.body.sections` into `state.sections`
|
||||
and routes to `confirm-stakeholders`, so the user exits via the normal
|
||||
without changes** writes `template.body.sections` into `state.sections`.
|
||||
Direct catalog / marketing entry routes to `community-name` and Next/Back
|
||||
collect only name, description, and optional photo, then
|
||||
`confirm-stakeholders`. A leftover draft title does not skip those
|
||||
identity steps. In-flow (`?fromFlow=1` after the community questionnaire)
|
||||
skips identity and opens `confirm-stakeholders`. The user
|
||||
exits via the normal
|
||||
`final-review → handleFinalize → publishRule` path and picks up the
|
||||
server-enforced 401 sign-in gate for free.
|
||||
|
||||
@@ -264,12 +269,13 @@ When the user picks a template **before** completing the community
|
||||
stage, both handlers still apply their side effects eagerly (prefill or
|
||||
`sections`/`summary`) and pin a
|
||||
`pendingTemplateAction: { slug, mode: "customize" | "useWithoutChanges" }`
|
||||
on `CreateFlowState`, then route to `informational`. Once the user
|
||||
reaches `/create/review`, `CommunityReviewScreen` consumes the pin and
|
||||
`router.replace`s past itself — to `core-values` for `customize`, to
|
||||
`confirm-stakeholders` for `useWithoutChanges`. The community-review
|
||||
screen is therefore only shown when the user came from "Create Custom"
|
||||
(no template), matching the intent already expressed at the
|
||||
on `CreateFlowState`. Customize then routes to `informational`. Direct
|
||||
Use without changes routes to `community-name` (identity-only skip list
|
||||
while the pin is set). Once the user reaches `/create/review`, `CommunityReviewScreen`
|
||||
consumes the pin and `router.replace`s past itself — to `core-values` for
|
||||
`customize`, to `community-name` for `useWithoutChanges`. The
|
||||
community-review screen is therefore only shown when the user came from
|
||||
"Create Custom" (no template), matching the intent already expressed at the
|
||||
template-review step.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user