"use client";
import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import Rule from "../../../../components/cards/Rule";
import Button from "../../../../components/buttons/Button";
import InlineTextButton from "../../../../components/buttons/InlineTextButton";
import { useMessages, useTranslation } from "../../../../contexts/MessagesContext";
import { CreateFlowHeaderLockup } from "../../components/CreateFlowHeaderLockup";
import { useCreateFlow } from "../../context/CreateFlowContext";
import { useCommunityAvatarDisplayUrl } from "../../hooks/useCommunityAvatarDisplayUrl";
import { useCreateFlowLgUp } from "../../hooks/useCreateFlowLgUp";
import { CreateFlowStepShell } from "../../components/CreateFlowStepShell";
import {
CREATE_FLOW_MD_UP_GRID_CELL_CLASS,
CREATE_FLOW_TWO_COLUMN_MAX_WIDTH_CLASS,
} from "../../components/createFlowLayoutTokens";
import {
getAssetPath,
vectorMarkPath,
} from "../../../../../lib/assetUtils";
import { methodSectionsPinsForHydratedSelections } from "../../../../../lib/create/publishedDocumentToCreateFlowState";
import { CREATE_ROUTES, createFlowStepPath } from "../../utils/createFlowPaths";
import { CREATE_FLOW_REVIEW_RETURN_QUERY_KEY } from "../../utils/flowSteps";
import type { CreateFlowStep } from "../../types";
function firstId(ids: readonly string[] | undefined): string | undefined {
return ids?.find((id) => id.length > 0);
}
function chipLabel(
id: string | undefined,
rows: readonly { id: string; label: string }[] | undefined,
snapshots: readonly { id: string; label: string }[] | undefined,
): string | undefined {
if (!id) return undefined;
const fromSnap = snapshots?.find((row) => row.id === id)?.label.trim();
if (fromSnap) return fromSnap;
return rows?.find((row) => row.id === id)?.label;
}
function reviewSizeValue(
id: string | undefined,
sizes: readonly { id: string; label: string }[],
peopleTemplate: string,
): string | undefined {
if (!id) return undefined;
const row = sizes.find((item) => item.id === id);
if (!row) return undefined;
if (id === "oneMember") return row.label;
return peopleTemplate.replace("{label}", row.label);
}
function CommunityReviewAnswerRow({
label,
value,
editLabel,
onEdit,
}: {
label: string;
value: string;
editLabel: string;
onEdit: () => void;
}) {
return (
{label}
{value}
{editLabel}
);
}
/** Create Community review — Figma `19706:12135` (`/create/review`; two columns from `lg:`; column caps in `createFlowLayoutTokens`). */
export function CommunityReviewScreen() {
const router = useRouter();
const lgUp = useCreateFlowLgUp();
const messages = useMessages();
const t = useTranslation("create.community.review");
const { state, updateState } = useCreateFlow();
/**
* Server layout has an empty context; the client layout may already hold a
* named draft. Defer empty-vs-congrats until after mount so the first paint
* matches SSR (`null`) instead of swapping HeaderLockup titles.
*/
const [reviewReady, setReviewReady] = useState(false);
useEffect(() => {
setReviewReady(true);
}, []);
/**
* If the user picked **Customize** from a template before finishing community
* stage, we pinned `pendingTemplateAction` so this screen can skip itself
* and `replace` to `core-values`. **Use without changes** does not skip
* identity: if they land here with that pin, send them to `community-name`
* and leave the pin so name → description → photo stay in the skip list.
*
* Ref guard covers React 18 StrictMode's double-mount in dev so we don't
* fire `router.replace` twice on the same transition.
*/
const firedRedirectRef = useRef(false);
useEffect(() => {
if (firedRedirectRef.current) return;
const pending = state.pendingTemplateAction;
if (!pending) return;
if (pending.mode !== "customize") {
firedRedirectRef.current = true;
router.replace(createFlowStepPath("community-name"));
return;
}
const target = createFlowStepPath("core-values");
firedRedirectRef.current = true;
const pinMerge = {
methodSectionsPinCommitted: {
...state.methodSectionsPinCommitted,
...methodSectionsPinsForHydratedSelections(state),
},
};
updateState({ pendingTemplateAction: undefined, ...pinMerge });
router.replace(target);
}, [
router,
state.pendingTemplateAction,
state.methodSectionsPinCommitted,
state.selectedCommunicationMethodIds,
state.selectedMembershipMethodIds,
state.selectedDecisionApproachIds,
state.selectedConflictManagementIds,
updateState,
]);
const cardTitle =
typeof state.title === "string" && state.title.trim().length > 0
? state.title.trim()
: "";
/**
* No placeholder fallback: if the user skipped `community-context`, leave
* the card description off rather than render sample copy as real user data.
*/
const cardDescription =
typeof state.communityContext === "string" &&
state.communityContext.trim().length > 0
? state.communityContext.trim()
: undefined;
const avatarUrl = useCommunityAvatarDisplayUrl(state.communityAvatarUrl);
const structure = messages.create.community.communityStructure;
const sizes = messages.create.community.communitySize.communitySizes;
const kindValue = chipLabel(
firstId(state.selectedOrganizationTypeIds),
structure.organizationTypes,
state.communityStructureChipSnapshots?.organizationTypes,
);
const sizeValue = reviewSizeValue(
firstId(state.selectedCommunitySizeIds),
sizes,
t("rows.sizePeople"),
);
const maturityValue = chipLabel(
firstId(state.selectedMaturityIds),
structure.maturityOptions,
state.communityStructureChipSnapshots?.maturity,
);
const goEdit = (step: CreateFlowStep) => {
router.push(
createFlowStepPath(step, {
[CREATE_FLOW_REVIEW_RETURN_QUERY_KEY]: "review",
}),
);
};
if (state.pendingTemplateAction || !reviewReady) {
return null;
}
if (!cardTitle) {
return (