"use client"; import { useState, useCallback } from "react"; import HeaderLockup from "../../components/type/HeaderLockup"; import { useCreateFlow } from "../context/CreateFlowContext"; import CardStack from "../../components/utility/CardStack"; import Create from "../../components/modals/Create"; import TextArea from "../../components/controls/TextArea"; const COMPACT_TITLE = "How should this community communicate with each-other?"; const COMPACT_DESCRIPTION = "You can select multiple methods for different needs or add your own"; const EXPANDED_TITLE = "What method should this community use to communicate with eachother?"; const EXPANDED_DESCRIPTION = COMPACT_DESCRIPTION; /** Create is a shell; which variant shows is determined by which card was clicked; we pass different props and children by pendingCardId. */ /** Card ids for "Add platform" Create modal variants. */ const IN_PERSON_CARD_ID = "in-person-meetings"; const SIGNAL_CARD_ID = "signal"; const VIDEO_MEETINGS_CARD_ID = "video-meetings"; /** Copy for the default confirm modal (non–add-platform cards). */ const CONFIRM_MODAL = { title: "Confirm selection", description: "Confirm to select this option.", nextButtonText: "Confirm", showBackButton: false, currentStep: undefined, totalSteps: undefined, } as const; /** * "Add platform" variants share the same header pattern and "Add Platform" button. * Each has its own title, description, and body (three TextArea sections). */ const ADD_PLATFORM_MODALS: Record< string, { title: string; description: string; nextButtonText: string } > = { [IN_PERSON_CARD_ID]: { title: "In-Person Meetings", description: "Physical gatherings for high-bandwidth communication and relationship building.", nextButtonText: "Add Platform", }, [SIGNAL_CARD_ID]: { title: "Signal", description: "End-to-end encrypted messaging ideal for small, security-minded groups", nextButtonText: "Add Platform", }, [VIDEO_MEETINGS_CARD_ID]: { title: "Video Meetings", description: "Synchronous video calls for remote face-to-face interaction.", nextButtonText: "Add Platform", }, }; const SECTION_KEYS = [ "Core Principle & Scope", "Logistics, Admin & Norms", "Code of Conduct", ] as const; type SectionKey = (typeof SECTION_KEYS)[number]; /** Default section text per platform (Figma 20647-18271, 20647-18273, 20736-12668). */ const ADD_PLATFORM_SECTION_DEFAULTS: Record< string, Record > = { [IN_PERSON_CARD_ID]: { "Core Principle & Scope": `We value the highest bandwidth of communication, physical presence, to build trust that digital tools cannot match. Consequently, we reserve this high-trust space for annual retreats, strategic planning, and high-stakes interpersonal repair where body language is essential.`, "Logistics, Admin & Norms": `Logistics focus on physical accessibility, venue security, and travel equity. Organizers control entry via keys or door staff. Culturally, participants are expected to maintain mission focus and adhere strictly to the itinerary to respect everyone's time. Side conversations or distracting behaviors that derail the agenda are discouraged.`, "Code of Conduct": `We aspire to operate within these principles. We don't need to see eye to eye on everything, but we believe the world can be improved by collective action. Aspire to do no harm to members of this community. Violence or physical intimidation will not be tolerated. We have a zero-tolerance policy for racism, sexism, and bigotry.`, }, [SIGNAL_CARD_ID]: { "Core Principle & Scope": `We use Signal for all operational communication. To keep our workspace organized, official channels are prepended with an emoji (e.g., 🤓). Public channels are open to all volunteers, while Core Channels are restricted to coordinators. All Core Members are designated as admins to share the technical workload.`, "Logistics, Admin & Norms": `We encourage direct messages to build friendship, but all operational logistics must happen in group channels. To respect everyone's time, use "Emoji Reactions" (👍, ♥️) to acknowledge messages rather than typing "thanks," which triggers notifications for everyone. Text is a poor medium for nuance: if a conversation needs more context, move it to a call or in person.`, "Code of Conduct": `This space relies on collective responsibility. Posting content that attracts unwanted legal attention or exposes members' real-world identities without consent is prohibited. We aspire to do no harm by practicing strict operational security. Intentionally leaking information violates our safety. We have a zero-tolerance policy for harassment or abuse.`, }, [VIDEO_MEETINGS_CARD_ID]: { "Core Principle & Scope": `We prioritize synchronous connection to read facial expressions without the barrier of travel, using this tool for weekly syncs and quick consensus checks that benefit from real-time debate before moving to a vote.`, "Logistics, Admin & Norms": `The host manages technical security via waiting rooms to prevent intrusion. Culturally, the focus is on maximizing the value of synchronous time. Norms include muting when not speaking, using the "Raise Hand" feature to queue, and utilizing the chat box for non-interruptive side comments. Distractions should be minimized.`, "Code of Conduct": `We have a zero-tolerance policy for racism, sexism, and bigotry, whether spoken or shared in the chat. We aspire to do no harm. "Zoom-bombing" or broadcasting graphic content is prohibited. Willfully spreading obviously false information will not be tolerated. Do not discuss sensitive data that could attract legal or security risk.`, }, }; /** * Section with heading + info icon and an editable TextArea. * This variant uses TextArea only (no TextInput); design is "Add Signal" / "Add Video Meetings". */ function CreateModalSection({ title, value: _value, onChange, }: { title: string; value: string; onChange: (_value: string) => void; }) { return (

{title}

?