From f78793d610bba8c04157b1f5bd73df19734c2b91 Mon Sep 17 00:00:00 2001 From: Akhileshwar Shriram <112577383+AkhilTheBoss@users.noreply.github.com> Date: Wed, 13 May 2026 16:13:38 -0700 Subject: [PATCH] feat: modified event manager to use davis-react components --- .../AuthenticatedStatusMessage.tsx | 98 +- .../CustomForms/DeleteBlockModal.tsx | 40 +- .../CustomForms/EditableFormBlock.tsx | 109 +- .../components/CustomForms/HeadingBlock.tsx | 10 +- .../components/CustomForms/HeadingModal.tsx | 51 +- .../components/CustomForms/NonUserForm.tsx | 64 +- .../components/CustomForms/PromptBlock.tsx | 157 +-- .../components/CustomForms/PromptModal.tsx | 282 ++-- .../CustomForms/ShippingAddressForm.tsx | 106 +- .../components/CustomForms/TextBlockModal.tsx | 41 +- .../EventsManager/AutoSyncToProjectModal.tsx | 155 ++- .../EventsManager/CancelEventModal.tsx | 49 +- .../EventsManager/CollectShippingMessage.tsx | 27 +- .../EventInstructionsSegment.tsx | 142 +- .../EventsManager/EventSettingsModal.tsx | 197 +-- .../EventsManager/EventSettingsSegment.tsx | 210 ++- .../EventsManager/FeeWaiverInputMessage.tsx | 27 +- .../EventsManager/FeeWaiverModal.tsx | 74 +- .../EventsManager/FeeWaiverStatusLabel.tsx | 21 +- .../EventsManager/FeeWaiversSegment.tsx | 185 ++- .../EventsManager/ParticipantsSegment.tsx | 475 +++---- .../EventsManager/PaymentStatusLabel.tsx | 51 +- .../RegistrationOpenStatusMessage.tsx | 100 +- .../RegistrationSuccessMessage.tsx | 63 +- .../UnregisterParticipantModal.tsx | 38 +- .../UnregisterParticipantsModal.tsx | 48 +- .../EventsManager/ManageEvent.tsx | 1221 +++++------------ .../controlpanel/EventsManager/index.tsx | 316 ++--- 28 files changed, 1689 insertions(+), 2668 deletions(-) diff --git a/client/src/components/CustomForms/AuthenticatedStatusMessage.tsx b/client/src/components/CustomForms/AuthenticatedStatusMessage.tsx index 1d9876988..90ec66c96 100644 --- a/client/src/components/CustomForms/AuthenticatedStatusMessage.tsx +++ b/client/src/components/CustomForms/AuthenticatedStatusMessage.tsx @@ -1,83 +1,45 @@ -import { Message, Icon, MessageProps } from "semantic-ui-react"; +import { IconUserCircle, IconKey } from "@tabler/icons-react"; import Breakpoint from "../util/Breakpoints"; import { User } from "../../types"; -interface AuthenticatedStatusMessageProps extends MessageProps { +interface AuthenticatedStatusMessageProps { user: User; + className?: string; } const AuthenticatedStatusMessage: React.FC = ({ user, - ...rest + className, }) => { - if (user.isAuthenticated) { - return ( - - - - - - - - - You're logged into Conductor as{" "} - - {user.firstName} {user.lastName} - - . - - - -
-
- - - - -
-

- You're logged into Conductor as{" "} - - {user.firstName} {user.lastName} - - . -

-
-
-
-
- ); - } + const msgText = user.isAuthenticated + ? <>You're logged into Conductor as {user.firstName} {user.lastName}. + : <>You are not logged in. You must login to Conductor to register for this event.; + + const colorClass = user.isAuthenticated + ? "bg-blue-50 border-blue-200 text-blue-800" + : "bg-yellow-50 border-yellow-200 text-yellow-800"; return ( - - - - - - - - - You are not logged in. You must login to Conductor to register for - this event. - - - -
-
- - - - -
-

- You are not logged in. You must login to Conductor to register for - this event. -

+
+ +
+
+ + +
+ {msgText} +
+
+ +
+
+ +
- - - +

{msgText}

+
+
+
); }; diff --git a/client/src/components/CustomForms/DeleteBlockModal.tsx b/client/src/components/CustomForms/DeleteBlockModal.tsx index d79513d8c..b08757525 100644 --- a/client/src/components/CustomForms/DeleteBlockModal.tsx +++ b/client/src/components/CustomForms/DeleteBlockModal.tsx @@ -1,6 +1,7 @@ -import { Modal, Button, Icon, ModalProps } from "semantic-ui-react"; +import { Modal, Button } from "@libretexts/davis-react"; +import { IconTrash } from "@tabler/icons-react"; -interface DeleteBlockModalProps extends ModalProps { +interface DeleteBlockModalProps { show: boolean; blockType: "heading" | "textBlock" | "prompt"; onSave: () => void; @@ -14,24 +15,31 @@ const DeleteBlockModal: React.FC = ({ onSave, onRequestClose, loading, - ...rest }) => { return ( - onRequestClose()} {...rest}> - Delete Block - + + + Delete Block + + +

- Are you sure you want to delete this {blockType}{" "} - block? + Are you sure you want to delete this {blockType} block?

-
- - - - + + +
+ + +
+
); }; diff --git a/client/src/components/CustomForms/EditableFormBlock.tsx b/client/src/components/CustomForms/EditableFormBlock.tsx index 8ae3d43f3..ea6758d46 100644 --- a/client/src/components/CustomForms/EditableFormBlock.tsx +++ b/client/src/components/CustomForms/EditableFormBlock.tsx @@ -1,7 +1,8 @@ import { useEffect } from "react"; import DOMPurify from "dompurify"; import { marked } from "marked"; -import { Segment, Label, Button, Icon, SegmentProps } from "semantic-ui-react"; +import { IconArrowUp, IconArrowDown, IconPencil, IconTrash } from "@tabler/icons-react"; +import { Button } from "@libretexts/davis-react"; import { isCustomFormHeadingOrTextBlock, isCustomFormPromptBlock, @@ -9,8 +10,9 @@ import { import { CustomFormElement } from "../../types"; import { getFriendlyUIType } from "../../utils/customFormHelpers"; -interface EditableFormBlockProps extends SegmentProps { +interface EditableFormBlockProps { item: CustomFormElement; + disabled?: boolean; onMove: (item: CustomFormElement, direction: "up" | "down") => void; onRequestEdit: (order: number) => void; onRequestDelete: (order: number) => void; @@ -18,13 +20,11 @@ interface EditableFormBlockProps extends SegmentProps { const EditableFormBlock: React.FC = ({ item, + disabled, onMove, onRequestEdit, onRequestDelete, - ...rest }) => { - const { disabled } = rest; - useEffect(() => { DOMPurify.addHook("afterSanitizeAttributes", (node) => { if ("target" in node) { @@ -43,59 +43,66 @@ const EditableFormBlock: React.FC = ({ __html: DOMPurify.sanitize(marked(textToRender, { breaks: true })), }; + const typeLabel = + item.uiType === "prompt" && isCustomFormPromptBlock(item) + ? item.promptRequired + ? `(Required)` + : `(Optional)` + : ""; + return ( - -
+ + #{item.order}: {getFriendlyUIType(item.uiType)}{" "} + {typeLabel && {typeLabel}} + + +
+ +
- +
+
); }; diff --git a/client/src/components/CustomForms/HeadingBlock.tsx b/client/src/components/CustomForms/HeadingBlock.tsx index fde1c58ce..9fa0c595d 100644 --- a/client/src/components/CustomForms/HeadingBlock.tsx +++ b/client/src/components/CustomForms/HeadingBlock.tsx @@ -1,15 +1,15 @@ -import { Header, HeaderProps } from "semantic-ui-react"; import { CustomFormHeading } from "../../types"; -interface HeadingBlockProps extends HeaderProps { +interface HeadingBlockProps { item: CustomFormHeading; + className?: string; } -const HeadingBlock: React.FC = ({ item, ...rest }) => { +const HeadingBlock: React.FC = ({ item, className }) => { return ( -
+

{item.text} -

+ ); }; diff --git a/client/src/components/CustomForms/HeadingModal.tsx b/client/src/components/CustomForms/HeadingModal.tsx index e55b188bc..7948aa604 100644 --- a/client/src/components/CustomForms/HeadingModal.tsx +++ b/client/src/components/CustomForms/HeadingModal.tsx @@ -1,7 +1,8 @@ -import { Modal, Input, Button, Icon, ModalProps } from "semantic-ui-react"; +import { Modal, Button, Input } from "@libretexts/davis-react"; +import { IconDeviceFloppy, IconPlus } from "@tabler/icons-react"; import { useRef, useEffect } from "react"; -interface HeadingModalProps extends ModalProps { +interface HeadingModalProps { show: boolean; mode: "add" | "edit"; value: string; @@ -21,38 +22,44 @@ const HeadingModal: React.FC = ({ onSave, onClose, loading, - ...rest }) => { - - //Auto-focus input on open - const textInputRef = useRef(null); + const textInputRef = useRef(null); useEffect(() => { if (show && textInputRef.current) { - (textInputRef.current as HTMLFormElement).focus(); + textInputRef.current.focus(); } }, [show]); return ( - - {mode === "add" ? "Add" : "Edit"} Heading - + + + {mode === "add" ? "Add" : "Edit"} Heading + + + onChange(value)} - fluid - placeholder={`Enter ${mode === "add" && "new"} heading text...`} - error={hasError} + onChange={(e) => onChange(e.target.value)} + placeholder={`Enter ${mode === "add" ? "new " : ""}heading text...`} ref={textInputRef} /> - - - - - + + +
+ + +
+
); }; diff --git a/client/src/components/CustomForms/NonUserForm.tsx b/client/src/components/CustomForms/NonUserForm.tsx index 11793324e..df7e3d96f 100644 --- a/client/src/components/CustomForms/NonUserForm.tsx +++ b/client/src/components/CustomForms/NonUserForm.tsx @@ -1,6 +1,5 @@ -import { Form, Header } from "semantic-ui-react"; import { OrgEventParticipant } from "../../types"; -import { Control, UseFormGetValues } from "react-hook-form"; +import { Control } from "react-hook-form"; import CtlTextInput from "../ControlledInputs/CtlTextInput"; import { required } from "../../utils/formRules"; @@ -10,46 +9,49 @@ interface NonUserFormProps { >; isSubForm?: boolean; } + const NonUserForm: React.FC = ({ control, isSubForm = false, }) => { - const nonUserForm = ( + const fields = ( <> -
+

Participant Information -

-

+ +

This is the contact information for the person you are registering on behalf of.

- - - +
+ + + +
); - return isSubForm ? nonUserForm :
{nonUserForm}
; + return isSubForm ? fields :
{fields}
; }; export default NonUserForm; diff --git a/client/src/components/CustomForms/PromptBlock.tsx b/client/src/components/CustomForms/PromptBlock.tsx index f5bc67f9b..281f4bc0b 100644 --- a/client/src/components/CustomForms/PromptBlock.tsx +++ b/client/src/components/CustomForms/PromptBlock.tsx @@ -1,4 +1,4 @@ -import { Form, TextArea } from "semantic-ui-react"; +import { Checkbox } from "@libretexts/davis-react"; import LikertScale from "./LikertScale"; import { CustomFormPrompt } from "../../types"; @@ -11,139 +11,92 @@ type PromptBlockProps = { error: boolean; }; -//TODO: Handle values not being defined const PromptBlock: React.FC = ({ item, handleFieldChange, error, }) => { - if (item.promptType === "3-likert") { + const labelClass = `block text-sm font-medium mb-1 ${error ? "text-red-600" : "text-gray-700"}`; + const requiredMark = item.promptRequired ? * : null; + + if (["3-likert", "5-likert", "7-likert"].includes(item.promptType)) { + const points = item.promptType === "3-likert" ? 3 : item.promptType === "5-likert" ? 5 : 7; return ( - +
{item.promptText && ( -
); - } else if (item.promptType === "5-likert") { + } + + if (item.promptType === "text") { return ( - +
{item.promptText && ( -