From 5d6530e9147f7c53bd63b757edfb3c5a89398891 Mon Sep 17 00:00:00 2001
From: adilallo <39313955+adilallo@users.noreply.github.com>
Date: Sat, 4 Apr 2026 10:36:26 -0600
Subject: [PATCH] Confirm stakeholder template
---
.../controls/MultiSelect/MultiSelect.view.tsx | 25 ++--
app/create/confirm-stakeholders/page.tsx | 107 ++++++++++++++++++
app/create/layout.tsx | 4 +-
app/create/select/page.tsx | 90 +++++++++++----
app/create/types.ts | 1 +
app/create/utils/flowSteps.ts | 1 +
6 files changed, 199 insertions(+), 29 deletions(-)
create mode 100644 app/create/confirm-stakeholders/page.tsx
diff --git a/app/components/controls/MultiSelect/MultiSelect.view.tsx b/app/components/controls/MultiSelect/MultiSelect.view.tsx
index e3ce198..8ab81b8 100644
--- a/app/components/controls/MultiSelect/MultiSelect.view.tsx
+++ b/app/components/controls/MultiSelect/MultiSelect.view.tsx
@@ -78,7 +78,7 @@ function MultiSelectView({
/>
))}
- {/* Add button - Circular button with border (not ghost) when no text, ghost style when text provided */}
+ {/* Add button — icon-only: bordered circle + brand icon (chips stay yellow). With label: Figma 19688:38288 — brand + icon, primary label text, no fill/border. */}
{addButton && (
) : null
}
diff --git a/app/create/select/page.tsx b/app/create/select/page.tsx
index 9f287f2..474be3a 100644
--- a/app/create/select/page.tsx
+++ b/app/create/select/page.tsx
@@ -1,9 +1,33 @@
"use client";
-import { useState, useEffect } from "react";
+import { useState, useEffect, useMemo, type Dispatch, type SetStateAction } from "react";
import { useMediaQuery } from "../../hooks/useMediaQuery";
import HeaderLockup from "../../components/type/HeaderLockup";
import MultiSelect from "../../components/controls/MultiSelect";
+import type { ChipOption } from "../../components/controls/MultiSelect/MultiSelect.types";
+
+function createListCustomHandlers(
+ setList: Dispatch>,
+ confirmState: "Unselected" | "Selected",
+) {
+ return {
+ onAddClick: () =>
+ setList((prev) => [
+ ...prev,
+ { id: crypto.randomUUID(), label: "", state: "Custom" },
+ ]),
+ onCustomChipConfirm: (chipId: string, value: string) =>
+ setList((prev) =>
+ prev.map((opt) =>
+ opt.id === chipId
+ ? { ...opt, label: value, state: confirmState }
+ : opt,
+ ),
+ ),
+ onCustomChipClose: (chipId: string) =>
+ setList((prev) => prev.filter((o) => o.id !== chipId)),
+ };
+}
/**
* Select page for the create flow
@@ -24,30 +48,48 @@ export default function SelectPage() {
const effectiveMdOrLarger = !isMounted || isMdOrLarger;
- // Sample options for MultiSelect components
- const [communitySizeOptions, setCommunitySizeOptions] = useState([
- { id: "1", label: "1 member", state: "Unselected" as const },
- { id: "2", label: "2-10 members", state: "Unselected" as const },
- { id: "3", label: "10-24 members", state: "Unselected" as const },
- { id: "4", label: "24-64 members", state: "Unselected" as const },
- { id: "5", label: "64-128 members", state: "Unselected" as const },
- { id: "6", label: "125-1000 members", state: "Unselected" as const },
- { id: "7", label: "1000+ members", state: "Unselected" as const },
+ const [communitySizeOptions, setCommunitySizeOptions] = useState(
+ [
+ { id: "1", label: "1 member", state: "Unselected" },
+ { id: "2", label: "2-10 members", state: "Unselected" },
+ { id: "3", label: "10-24 members", state: "Unselected" },
+ { id: "4", label: "24-64 members", state: "Unselected" },
+ { id: "5", label: "64-128 members", state: "Unselected" },
+ { id: "6", label: "125-1000 members", state: "Unselected" },
+ { id: "7", label: "1000+ members", state: "Unselected" },
+ ],
+ );
+
+ const [organizationTypeOptions, setOrganizationTypeOptions] = useState<
+ ChipOption[]
+ >([
+ { id: "1", label: "Non-profit", state: "Unselected" },
+ { id: "2", label: "For-profit", state: "Unselected" },
+ { id: "3", label: "Community", state: "Unselected" },
+ { id: "4", label: "Educational", state: "Unselected" },
]);
- const [organizationTypeOptions, setOrganizationTypeOptions] = useState([
- { id: "1", label: "Non-profit", state: "Unselected" as const },
- { id: "2", label: "For-profit", state: "Unselected" as const },
- { id: "3", label: "Community", state: "Unselected" as const },
- { id: "4", label: "Educational", state: "Unselected" as const },
+ const [governanceStyleOptions, setGovernanceStyleOptions] = useState<
+ ChipOption[]
+ >([
+ { id: "1", label: "Democratic", state: "Unselected" },
+ { id: "2", label: "Consensus", state: "Unselected" },
+ { id: "3", label: "Hierarchical", state: "Unselected" },
+ { id: "4", label: "Flat", state: "Unselected" },
]);
- const [governanceStyleOptions, setGovernanceStyleOptions] = useState([
- { id: "1", label: "Democratic", state: "Unselected" as const },
- { id: "2", label: "Consensus", state: "Unselected" as const },
- { id: "3", label: "Hierarchical", state: "Unselected" as const },
- { id: "4", label: "Flat", state: "Unselected" as const },
- ]);
+ const communityCustomHandlers = useMemo(
+ () => createListCustomHandlers(setCommunitySizeOptions, "Unselected"),
+ [],
+ );
+ const organizationCustomHandlers = useMemo(
+ () => createListCustomHandlers(setOrganizationTypeOptions, "Unselected"),
+ [],
+ );
+ const governanceCustomHandlers = useMemo(
+ () => createListCustomHandlers(setGovernanceStyleOptions, "Unselected"),
+ [],
+ );
const handleCommunitySizeClick = (chipId: string) => {
setCommunitySizeOptions((prev) =>
@@ -110,6 +152,7 @@ export default function SelectPage() {
size="S"
options={communitySizeOptions}
onChipClick={handleCommunitySizeClick}
+ {...communityCustomHandlers}
addButton={true}
addButtonText="Add organization type"
/>
@@ -118,6 +161,7 @@ export default function SelectPage() {
size="S"
options={organizationTypeOptions}
onChipClick={handleOrganizationTypeClick}
+ {...organizationCustomHandlers}
addButton={true}
addButtonText="Add organization type"
/>
@@ -126,6 +170,7 @@ export default function SelectPage() {
size="S"
options={governanceStyleOptions}
onChipClick={handleGovernanceStyleClick}
+ {...governanceCustomHandlers}
addButton={true}
addButtonText="Add organization type"
/>
@@ -148,6 +193,7 @@ export default function SelectPage() {
size="S"
options={communitySizeOptions}
onChipClick={handleCommunitySizeClick}
+ {...communityCustomHandlers}
addButton={true}
addButtonText="Add organization type"
/>
@@ -156,6 +202,7 @@ export default function SelectPage() {
size="S"
options={organizationTypeOptions}
onChipClick={handleOrganizationTypeClick}
+ {...organizationCustomHandlers}
addButton={true}
addButtonText="Add organization type"
/>
@@ -164,6 +211,7 @@ export default function SelectPage() {
size="S"
options={governanceStyleOptions}
onChipClick={handleGovernanceStyleClick}
+ {...governanceCustomHandlers}
addButton={true}
addButtonText="Add organization type"
/>
diff --git a/app/create/types.ts b/app/create/types.ts
index 32b8204..6c1459d 100644
--- a/app/create/types.ts
+++ b/app/create/types.ts
@@ -16,6 +16,7 @@ export type CreateFlowStep =
| "review"
| "cards"
| "right-rail"
+ | "confirm-stakeholders"
| "final-review"
| "completed";
diff --git a/app/create/utils/flowSteps.ts b/app/create/utils/flowSteps.ts
index 3b5138b..474cc51 100644
--- a/app/create/utils/flowSteps.ts
+++ b/app/create/utils/flowSteps.ts
@@ -17,6 +17,7 @@ export const FLOW_STEP_ORDER: readonly CreateFlowStep[] = [
"review",
"cards",
"right-rail",
+ "confirm-stakeholders",
"final-review",
"completed",
] as const;