Edit add feature refined
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { useMemo } from "react";
|
||||
import { useCreateFlow } from "../context/CreateFlowContext";
|
||||
import type { CreateFlowMethodCardFacetSection } from "../types";
|
||||
import {
|
||||
@@ -18,14 +18,17 @@ type MethodEntry = { id: string; label: string; supportText: string };
|
||||
|
||||
/**
|
||||
* Applies score ranking, compact-slot rules, optional “pinned selection” showcase
|
||||
* order, and clears the pin draft flag when a section loses all selections.
|
||||
* order. Rows stay pinned across navigation while `methodSectionsPinCommitted` is true
|
||||
* and the section still has selections; we do **not** clear the flag when selection
|
||||
* arrays briefly go empty during draft hydration (`replaceState` / merge flashes) —
|
||||
* display order already ignores the pin until `pinActive` is true again.
|
||||
*/
|
||||
export function useMethodCardDeckOrdering(
|
||||
section: RecommendationSection,
|
||||
methods: readonly MethodEntry[],
|
||||
selectedIds: readonly string[],
|
||||
) {
|
||||
const { state, setMethodSectionsPinCommitted } = useCreateFlow();
|
||||
const { state } = useCreateFlow();
|
||||
const facetKey = section as CreateFlowMethodCardFacetSection;
|
||||
const { scoresBySlug, hasAnyFacets } = useFacetRecommendations(section);
|
||||
|
||||
@@ -33,17 +36,6 @@ export function useMethodCardDeckOrdering(
|
||||
state.methodSectionsPinCommitted?.[facetKey] === true;
|
||||
const pinActive = Boolean(pinStored && selectedIds.length > 0);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedIds.length > 0) return;
|
||||
if (!pinStored) return;
|
||||
setMethodSectionsPinCommitted(facetKey, false);
|
||||
}, [
|
||||
facetKey,
|
||||
pinStored,
|
||||
selectedIds.length,
|
||||
setMethodSectionsPinCommitted,
|
||||
]);
|
||||
|
||||
const rankedMethods = useMemo(
|
||||
() => rankMethodsByScore(methods, scoresBySlug),
|
||||
[methods, scoresBySlug],
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { ChipOption } from "../../../../components/controls/MultiSelect/Mul
|
||||
import Create from "../../../../components/modals/Create";
|
||||
import ContentLockup from "../../../../components/type/ContentLockup";
|
||||
import { useMessages } from "../../../../contexts/MessagesContext";
|
||||
import { buildCoreValueChipOptionsFromDraft } from "../../../../../lib/create/coreValueChipOptionsFromDraft";
|
||||
import { useCreateFlow } from "../../context/CreateFlowContext";
|
||||
import type {
|
||||
CommunityStructureChipSnapshotRow,
|
||||
@@ -57,31 +58,6 @@ function normalizeCoreValuePresets(
|
||||
});
|
||||
}
|
||||
|
||||
function chipRowsFromPresets(presets: readonly CoreValuePreset[]): ChipOption[] {
|
||||
return presets.map((row, i) => ({
|
||||
id: String(i + 1),
|
||||
label: row.label,
|
||||
state: "unselected" as const,
|
||||
}));
|
||||
}
|
||||
|
||||
function applySavedSelection(
|
||||
options: ChipOption[],
|
||||
saved: string[] | undefined,
|
||||
): ChipOption[] {
|
||||
const selected = new Set(saved ?? []);
|
||||
return options.map((opt) =>
|
||||
opt.state === "custom"
|
||||
? opt
|
||||
: {
|
||||
...opt,
|
||||
state: selected.has(opt.id)
|
||||
? ("selected" as const)
|
||||
: ("unselected" as const),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
function selectedIdsFromOptions(options: ChipOption[]): string[] {
|
||||
return options
|
||||
.filter((o) => o.state === "selected")
|
||||
@@ -98,19 +74,6 @@ function chipOptionsToSnapshotRows(
|
||||
}));
|
||||
}
|
||||
|
||||
function snapshotRowsToChipOptions(
|
||||
rows: CommunityStructureChipSnapshotRow[] | undefined,
|
||||
): ChipOption[] | null {
|
||||
if (!Array.isArray(rows) || rows.length === 0) return null;
|
||||
return rows.map((r) => ({
|
||||
id: r.id,
|
||||
label: r.label,
|
||||
...(r.state !== undefined
|
||||
? { state: r.state as ChipOption["state"] }
|
||||
: {}),
|
||||
}));
|
||||
}
|
||||
|
||||
const EMPTY_DETAIL: CoreValueDetailEntry = { meaning: "", signals: "" };
|
||||
|
||||
/** Create Custom — Core Values (Figma `20264:68378`). Up to five selections; preset list + custom chips. */
|
||||
@@ -124,15 +87,12 @@ export function CoreValuesSelectScreen() {
|
||||
|
||||
const { markCreateFlowInteraction, updateState, state } = useCreateFlow();
|
||||
|
||||
const [coreValueOptions, setCoreValueOptions] = useState<ChipOption[]>(
|
||||
() => {
|
||||
const fromSnap = snapshotRowsToChipOptions(state.coreValuesChipsSnapshot);
|
||||
if (fromSnap) return fromSnap;
|
||||
return applySavedSelection(
|
||||
chipRowsFromPresets(presets),
|
||||
state.selectedCoreValueIds,
|
||||
);
|
||||
},
|
||||
const [coreValueOptions, setCoreValueOptions] = useState<ChipOption[]>(() =>
|
||||
buildCoreValueChipOptionsFromDraft(
|
||||
presets,
|
||||
state.coreValuesChipsSnapshot,
|
||||
state.selectedCoreValueIds,
|
||||
),
|
||||
);
|
||||
|
||||
const [activeModalChipId, setActiveModalChipId] = useState<string | null>(
|
||||
@@ -142,15 +102,18 @@ export function CoreValuesSelectScreen() {
|
||||
const [draft, setDraft] = useState<CoreValueDetailEntry>(EMPTY_DETAIL);
|
||||
|
||||
useEffect(() => {
|
||||
const fromSnap = snapshotRowsToChipOptions(state.coreValuesChipsSnapshot);
|
||||
if (fromSnap) {
|
||||
setCoreValueOptions(fromSnap);
|
||||
return;
|
||||
}
|
||||
setCoreValueOptions((prev) =>
|
||||
applySavedSelection(prev, state.selectedCoreValueIds),
|
||||
setCoreValueOptions(
|
||||
buildCoreValueChipOptionsFromDraft(
|
||||
presets,
|
||||
state.coreValuesChipsSnapshot,
|
||||
state.selectedCoreValueIds,
|
||||
),
|
||||
);
|
||||
}, [state.coreValuesChipsSnapshot, state.selectedCoreValueIds]);
|
||||
}, [
|
||||
presets,
|
||||
state.coreValuesChipsSnapshot,
|
||||
state.selectedCoreValueIds,
|
||||
]);
|
||||
|
||||
/** Sync chips to create-flow draft. Never call `updateState` from inside a `setCoreValueOptions` updater — defer with `queueMicrotask`. */
|
||||
const syncCoreValuesToDraft = useCallback(
|
||||
|
||||
Reference in New Issue
Block a user