Files
community-rule/app/(app)/create/screens/select/CommunitySizeSelectScreen.tsx
T

114 lines
3.4 KiB
TypeScript

"use client";
import { useState, useEffect, useLayoutEffect } from "react";
import MultiSelect from "../../../../components/controls/MultiSelect";
import type { ChipOption } from "../../../../components/controls/MultiSelect/MultiSelect.types";
import { useMessages } from "../../../../contexts/MessagesContext";
import { useCreateFlow } from "../../context/CreateFlowContext";
import { CreateFlowHeaderLockup } from "../../components/CreateFlowHeaderLockup";
import { CreateFlowTwoColumnSelectShell } from "../../components/CreateFlowTwoColumnSelectShell";
function chipRowsFromLabels(
rows: readonly { id?: string; label: string }[],
): ChipOption[] {
return rows.map((row, i) => ({
id: row.id ?? String(i + 1),
label: row.label,
state: "unselected" as const,
}));
}
/** The first saved id. A count belongs to one band, so later ids are dropped. */
function soleSizeId(ids: readonly string[] | undefined): string | null {
for (const id of ids ?? []) {
if (id.length > 0) return id;
}
return null;
}
function withSoleSelection(
options: ChipOption[],
selectedId: string | null,
): ChipOption[] {
return options.map((opt) =>
opt.state === "custom"
? opt
: {
...opt,
state:
opt.id === selectedId
? ("selected" as const)
: ("unselected" as const),
},
);
}
/** Create Community — Figma `24715:26346`, chips size M (one question). */
export function CommunitySizeSelectScreen() {
const m = useMessages();
const cs = m.create.community.communitySize;
const { markCreateFlowInteraction, updateState, state } = useCreateFlow();
const [communitySizeOptions, setCommunitySizeOptions] = useState<
ChipOption[]
>(() =>
withSoleSelection(
chipRowsFromLabels(cs.communitySizes),
soleSizeId(state.selectedCommunitySizeIds),
),
);
useLayoutEffect(() => {
const ids = state.selectedCommunitySizeIds;
if (!ids || ids.length === 0) return;
const first = soleSizeId(ids);
if (ids.length === 1 && ids[0] === first) return;
updateState({ selectedCommunitySizeIds: first ? [first] : [] });
}, [state.selectedCommunitySizeIds, updateState]);
useEffect(() => {
const selectedId = soleSizeId(state.selectedCommunitySizeIds);
setCommunitySizeOptions((prev) => withSoleSelection(prev, selectedId));
}, [state.selectedCommunitySizeIds]);
const persistSelection = (next: ChipOption[]) => {
markCreateFlowInteraction();
setCommunitySizeOptions(next);
updateState({
selectedCommunitySizeIds: next
.filter((o) => o.state === "selected")
.map((o) => o.id),
});
};
const handleCommunitySizeClick = (chipId: string) => {
const current = communitySizeOptions.find((opt) => opt.state === "selected");
const nextId = current?.id === chipId ? null : chipId;
persistSelection(withSoleSelection(communitySizeOptions, nextId));
};
const multiSelectBlock = (
<MultiSelect
formHeader={false}
size="m"
options={communitySizeOptions}
onChipClick={handleCommunitySizeClick}
addButton={false}
/>
);
return (
<CreateFlowTwoColumnSelectShell
header={
<CreateFlowHeaderLockup
title={cs.header.title}
description={cs.header.description}
justification="left"
/>
}
>
{multiSelectBlock}
</CreateFlowTwoColumnSelectShell>
);
}