UNPKG

mediasfu-reactjs

Version:

MediaSFU Prebuilt ReactJS SDK - Compatible with React 18 & 19, TypeScript & JavaScript

363 lines 14.4 kB
import React from "react"; import { Poll, ShowAlert, HandleCreatePollType, HandleEndPollType, HandleVotePollType } from "../../@types/types"; import { Socket } from "socket.io-client"; import { ModalRenderMode } from '../menuComponents/MenuModal'; interface NewPollFormState { question: string; type: "" | "trueFalse" | "yesNo" | "custom"; options: string[]; } export interface PollModalOptions { isPollModalVisible: boolean; onClose: () => void; position?: string; backgroundColor?: string; member: string; islevel: string; polls: Poll[]; poll: Poll | null; socket: Socket; roomName: string; showAlert?: ShowAlert; updateIsPollModalVisible: (isVisible: boolean) => void; handleCreatePoll: HandleCreatePollType; handleEndPoll: HandleEndPollType; handleVotePoll: HandleVotePollType; title?: React.ReactNode; overlayProps?: React.HTMLAttributes<HTMLDivElement>; contentProps?: React.HTMLAttributes<HTMLDivElement>; headerProps?: React.HTMLAttributes<HTMLDivElement>; titleProps?: React.HTMLAttributes<HTMLHeadingElement>; closeButtonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>; closeIconComponent?: React.ReactNode; bodyProps?: React.HTMLAttributes<HTMLDivElement>; sectionsWrapperProps?: React.HTMLAttributes<HTMLDivElement>; previousPollsWrapperProps?: React.HTMLAttributes<HTMLDivElement>; previousPollsHeaderProps?: React.HTMLAttributes<HTMLHeadingElement>; createPollWrapperProps?: React.HTMLAttributes<HTMLDivElement>; createPollFormProps?: React.FormHTMLAttributes<HTMLFormElement>; activePollWrapperProps?: React.HTMLAttributes<HTMLDivElement>; pollQuestionInputProps?: React.InputHTMLAttributes<HTMLInputElement>; pollTypeSelectProps?: React.SelectHTMLAttributes<HTMLSelectElement>; pollOptionInputProps?: React.InputHTMLAttributes<HTMLInputElement>; voteButtonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>; endPollButtonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>; submitPollButtonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>; emptyPreviousPolls?: React.ReactNode; emptyActivePoll?: React.ReactNode; renderHeader?: (options: { defaultHeader: React.ReactNode; }) => React.ReactNode; renderPreviousPolls?: (options: { defaultPreviousPolls: React.ReactNode; previousPolls: Poll[]; }) => React.ReactNode; renderCreatePoll?: (options: { defaultCreatePoll: React.ReactNode; newPoll: NewPollFormState; setNewPoll: React.Dispatch<React.SetStateAction<NewPollFormState>>; }) => React.ReactNode; renderActivePoll?: (options: { defaultActivePoll: React.ReactNode; activePoll: Poll | null; }) => React.ReactNode; renderBody?: (options: { defaultBody: React.ReactNode; }) => React.ReactNode; renderContent?: (options: { defaultContent: React.ReactNode; }) => React.ReactNode; /** Theme control - whether dark mode is active */ isDarkMode?: boolean; /** Enable glassmorphism effects (modern UI) */ enableGlassmorphism?: boolean; /** Render mode: modal (default overlay), sidebar (inline for desktop), inline (no wrapper) */ renderMode?: ModalRenderMode; } export type PollModalType = (options: PollModalOptions) => React.JSX.Element; /** * PollModal - Interactive polling interface for creating and managing live polls * * A comprehensive modal for creating, displaying, and voting on polls during events. * Supports multiple poll types (True/False, Yes/No, custom options), real-time voting, * and poll history tracking. Perfect for audience engagement and quick feedback. * * Features: * - Create new polls with multiple question types * - True/False and Yes/No quick poll templates * - Custom multiple-choice polls (2-5 options) * - Real-time voting with live result updates * - Previous polls history display with results * - Host controls (create, end polls) * - Participant voting interface * - Vote percentage calculations * - Custom render hooks for complete UI flexibility * * @component * @param {PollModalOptions} options - Configuration options * @param {boolean} options.isPollModalVisible - Modal visibility state * @param {Function} options.onClose - Callback when modal is closed * @param {string} [options.position="topRight"] - Modal position on screen * @param {string} [options.backgroundColor="#f5f5f5"] - Modal background color * @param {string} options.member - Current user's member ID * @param {string} options.islevel - User level ('2'=host, '1'=co-host, '0'=participant) * @param {Poll[]} options.polls - Array of all polls (active + previous) * @param {Poll|null} options.poll - Currently active poll * @param {Socket} options.socket - Socket.io client instance * @param {string} options.roomName - Meeting/room identifier * @param {ShowAlert} [options.showAlert] - Alert display function * @param {Function} options.updateIsPollModalVisible - Update modal visibility state * @param {HandleCreatePollType} options.handleCreatePoll - Function to create new poll * @param {HandleEndPollType} options.handleEndPoll - Function to end active poll * @param {HandleVotePollType} options.handleVotePoll - Function to submit vote * @param {React.ReactNode} [options.title="Polls"] - Modal title content * @param {object} [options.overlayProps] - HTML attributes for overlay div * @param {object} [options.contentProps] - HTML attributes for content container * @param {object} [options.headerProps] - HTML attributes for header section * @param {object} [options.closeButtonProps] - HTML attributes for close button * @param {React.ReactNode} [options.closeIconComponent] - Custom close icon * @param {object} [options.bodyProps] - HTML attributes for body section * @param {object} [options.createPollFormProps] - HTML attributes for create poll form * @param {object} [options.pollQuestionInputProps] - HTML attributes for question input * @param {object} [options.pollTypeSelectProps] - HTML attributes for type selector * @param {object} [options.voteButtonProps] - HTML attributes for vote buttons * @param {object} [options.endPollButtonProps] - HTML attributes for end poll button * @param {object} [options.submitPollButtonProps] - HTML attributes for submit button * @param {React.ReactNode} [options.emptyPreviousPolls] - Content when no previous polls * @param {React.ReactNode} [options.emptyActivePoll] - Content when no active poll * @param {Function} [options.renderHeader] - Custom header renderer * @param {Function} [options.renderPreviousPolls] - Custom previous polls renderer * @param {Function} [options.renderCreatePoll] - Custom create poll form renderer * @param {Function} [options.renderActivePoll] - Custom active poll renderer * @param {Function} [options.renderBody] - Custom body renderer * @param {Function} [options.renderContent] - Custom content renderer * * @returns {React.JSX.Element} Rendered poll modal * * @example * // Basic poll modal for host * ```tsx * import React, { useState } from 'react'; * import { PollModal } from 'mediasfu-reactjs'; * * function HostPolls({ parameters }) { * const [isVisible, setIsVisible] = useState(false); * * return ( * <> * <button onClick={() => setIsVisible(true)}> * Polls ({parameters.polls.length}) * </button> * <PollModal * isPollModalVisible={isVisible} * onClose={() => setIsVisible(false)} * member={parameters.member} * islevel={parameters.islevel} * polls={parameters.polls} * poll={parameters.poll} * socket={parameters.socket} * roomName={parameters.roomName} * showAlert={parameters.showAlert} * updateIsPollModalVisible={parameters.updateIsPollModalVisible} * handleCreatePoll={parameters.handleCreatePoll} * handleEndPoll={parameters.handleEndPoll} * handleVotePoll={parameters.handleVotePoll} * backgroundColor="#0f172a" * position="topRight" * /> * </> * ); * } * ``` * * @example * // Custom styled poll with branded colors * ```tsx * import { PollModal } from 'mediasfu-reactjs'; * * function BrandedPoll({ isVisible, onClose, parameters }) { * return ( * <PollModal * isPollModalVisible={isVisible} * onClose={onClose} * member={parameters.member} * islevel={parameters.islevel} * polls={parameters.polls} * poll={parameters.poll} * socket={parameters.socket} * roomName={parameters.roomName} * showAlert={parameters.showAlert} * updateIsPollModalVisible={parameters.updateIsPollModalVisible} * handleCreatePoll={parameters.handleCreatePoll} * handleEndPoll={parameters.handleEndPoll} * handleVotePoll={parameters.handleVotePoll} * backgroundColor="#1e3a8a" * position="topLeft" * contentProps={{ * style: { * borderRadius: 20, * border: '2px solid #3b82f6', * boxShadow: '0 20px 60px rgba(59,130,246,0.3)', * }, * }} * submitPollButtonProps={{ * style: { * background: 'linear-gradient(135deg, #22c55e 0%, #14532d 100%)', * color: 'white', * padding: '12px 24px', * borderRadius: 12, * fontWeight: 600, * border: 'none', * cursor: 'pointer', * }, * }} * voteButtonProps={{ * style: { * padding: '10px 20px', * borderRadius: 8, * transition: 'all 0.2s ease', * }, * }} * /> * ); * } * ``` * * @example * // Custom poll with analytics tracking * ```tsx * import { PollModal } from 'mediasfu-reactjs'; * * function AnalyticsPoll({ isVisible, onClose, parameters }) { * const handleCreatePoll = async (options) => { * analytics.track('poll_created', { * question: options.poll.question, * type: options.poll.type, * optionsCount: options.poll.options.length, * }); * return parameters.handleCreatePoll(options); * }; * * const handleVotePoll = async (options) => { * analytics.track('poll_voted', { * pollId: options.pollId, * optionIndex: options.optionIndex, * }); * return parameters.handleVotePoll(options); * }; * * return ( * <PollModal * isPollModalVisible={isVisible} * onClose={onClose} * member={parameters.member} * islevel={parameters.islevel} * polls={parameters.polls} * poll={parameters.poll} * socket={parameters.socket} * roomName={parameters.roomName} * showAlert={parameters.showAlert} * updateIsPollModalVisible={parameters.updateIsPollModalVisible} * handleCreatePoll={handleCreatePoll} * handleEndPoll={parameters.handleEndPoll} * handleVotePoll={handleVotePoll} * renderActivePoll={({ defaultActivePoll, activePoll }) => { * if (!activePoll) return defaultActivePoll; * * return ( * <div style={{ * background: 'white', * padding: 20, * borderRadius: 12, * border: '2px solid #3b82f6', * }}> * <h3 style={{ marginBottom: 16, color: '#1e3a8a' }}> * {activePoll.question} * </h3> * <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}> * {activePoll.options.map((option, index) => { * const voteCount = activePoll.votes?.[index] || 0; * const totalVotes = Object.values(activePoll.votes || {}) * .reduce((sum: number, count) => sum + (count as number), 0); * const percentage = totalVotes > 0 * ? Math.round((voteCount / totalVotes) * 100) * : 0; * * return ( * <button * key={index} * onClick={() => handleVotePoll({ pollId: activePoll.id, optionIndex: index })} * style={{ * padding: 12, * borderRadius: 8, * border: '2px solid #e2e8f0', * background: 'white', * cursor: 'pointer', * position: 'relative', * overflow: 'hidden', * }} * > * <div style={{ * position: 'absolute', * left: 0, * top: 0, * bottom: 0, * width: `${percentage}%`, * background: '#3b82f6', * opacity: 0.2, * transition: 'width 0.3s ease', * }} /> * <div style={{ position: 'relative', zIndex: 1, display: 'flex', justifyContent: 'space-between' }}> * <span>{option}</span> * <span style={{ fontWeight: 600 }}>{percentage}%</span> * </div> * </button> * ); * })} * </div> * </div> * ); * }} * /> * ); * } * ``` * * @example * // Override with MediasfuGeneric uiOverrides * ```tsx * import { MediasfuGeneric, PollModal } from 'mediasfu-reactjs'; * * const uiOverrides = { * pollModal: { * component: (props) => ( * <PollModal * {...props} * backgroundColor="#0f172a" * position="topRight" * contentProps={{ * style: { * maxHeight: '85vh', * borderRadius: 20, * border: '2px solid #3b82f6', * }, * }} * submitPollButtonProps={{ * style: { * background: '#22c55e', * borderRadius: 12, * padding: '12px 28px', * fontWeight: 600, * }, * }} * /> * ), * }, * }; * * <MediasfuGeneric uiOverrides={uiOverrides} />; * ``` */ declare const PollModal: React.FC<PollModalOptions>; export default PollModal; //# sourceMappingURL=PollModal.d.ts.map