"use client"; /** * Controlled field blocks for wizard-authored method cards in Create modals * (facet screens + final-review chip edit). When `onBlocksChange` is omitted, * blocks render read-only (disabled controls). * * Layout matches preset method editors ({@link CommunicationMethodEditFields}, * {@link DecisionApproachEditFields}): {@link ModalTextAreaField}, * {@link ApplicableScopeField} chip rows, {@link IncrementerBlock}. */ import { memo, useCallback, useRef } from "react"; import { useMessages } from "../../../contexts/MessagesContext"; import Chip from "../../../components/controls/Chip"; import IncrementerBlock from "../../../components/controls/IncrementerBlock"; import InlineTextButton from "../../../components/buttons/InlineTextButton"; import Upload from "../../../components/controls/Upload"; import ApplicableScopeField from "./ApplicableScopeField"; import InputLabel from "../../../components/type/InputLabel"; import type { CustomMethodCardFieldBlock } from "../../../../lib/create/customMethodCardFieldBlocks"; import ModalTextAreaField from "./ModalTextAreaField"; const TEXT_VALUE_MAX = 8000; export interface CustomMethodCardFieldBlocksSummaryProps { blocks: CustomMethodCardFieldBlock[]; /** When set, fields update the draft via immutable block-array replacements. */ onBlocksChange?: (_next: CustomMethodCardFieldBlock[]) => void; } function mapBlockById( blocks: CustomMethodCardFieldBlock[], blockId: string, mapFn: (_b: CustomMethodCardFieldBlock) => CustomMethodCardFieldBlock, ): CustomMethodCardFieldBlock[] { return blocks.map((b) => (b.id === blockId ? mapFn(b) : b)); } function CustomMethodCardUploadBlockRow({ block, blocks, patch, uploadFileInputAriaLabel, uploadHint, clearFileLabel, noFileChosen, }: { block: Extract; blocks: CustomMethodCardFieldBlock[]; patch: (_next: CustomMethodCardFieldBlock[]) => void; uploadFileInputAriaLabel: string; uploadHint: string; clearFileLabel: string; noFileChosen: string; }) { const uploadInputRef = useRef(null); const displayName = block.fileName?.trim() ? block.fileName : noFileChosen; return (

{displayName}

{ const file = e.target.files?.[0]; const name = file?.name?.trim(); patch( mapBlockById(blocks, block.id, (b) => b.kind === "upload" ? { ...b, ...(name ? { fileName: name } : {}), } : b, ), ); e.target.value = ""; }} /> uploadInputRef.current?.click()} /> {block.fileName?.trim() ? ( patch( mapBlockById(blocks, block.id, (b) => b.kind === "upload" ? { ...b, fileName: undefined } : b, ), ) } > {clearFileLabel} ) : null}
); } function CustomMethodCardFieldBlocksSummaryComponent({ blocks, onBlocksChange, }: CustomMethodCardFieldBlocksSummaryProps) { const m = useMessages(); const wiz = m.create.customRule.customMethodCardWizard; const fm = wiz.fieldModals; const em = wiz.editModal; const emptyValue = em.readout.emptyValue; const noFileChosen = em.readout.noFileChosen; const readOnly = !onBlocksChange; const patch = useCallback( (next: CustomMethodCardFieldBlock[]) => { onBlocksChange?.(next); }, [onBlocksChange], ); return (
{blocks.map((block) => { if (block.kind === "text") { return ( patch( mapBlockById(blocks, block.id, (b) => b.kind === "text" ? { ...b, placeholderText: v.slice(0, TEXT_VALUE_MAX) } : b, ), ) } disabled={readOnly} /> ); } if (block.kind === "badges") { if (readOnly) { return (
{block.options.length > 0 ? (
{block.options.map((opt, idx) => ( ))}
) : (

{emptyValue}

)}
); } return ( patch( mapBlockById(blocks, block.id, (b) => b.kind === "badges" ? { ...b, options: b.options.filter((o) => o !== scope) } : b, ), ) } onAddScope={(scope) => patch( mapBlockById(blocks, block.id, (b) => { if (b.kind !== "badges") return b; if (b.options.includes(scope) || b.options.length >= 50) return b; return { ...b, options: [...b.options, scope] }; }), ) } /> ); } if (block.kind === "upload") { return (
{readOnly ? ( {}} disabled /> ) : ( )}
); } return ( patch( mapBlockById(blocks, block.id, (b) => b.kind === "proportion" ? { ...b, defaultPercent: v } : b, ), ) } formatValue={(v) => `${v}%`} decrementAriaLabel={fm.proportion.decrementAriaLabel} incrementAriaLabel={fm.proportion.incrementAriaLabel} /> ); })}
); } const CustomMethodCardFieldBlocksSummary = memo( CustomMethodCardFieldBlocksSummaryComponent, ); CustomMethodCardFieldBlocksSummary.displayName = "CustomMethodCardFieldBlocksSummary"; export default CustomMethodCardFieldBlocksSummary;