UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

162 lines (161 loc) • 8.71 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const api_services_1 = require("@selfcommunity/api-services"); const utils_1 = require("@selfcommunity/utils"); const material_1 = require("@mui/material"); const react_intl_1 = require("react-intl"); const Choice_1 = tslib_1.__importDefault(require("./Choice")); const Errors_1 = require("../../../constants/Errors"); const classnames_1 = tslib_1.__importDefault(require("classnames")); const constants_1 = require("../constants"); const messages = (0, react_intl_1.defineMessages)({ showPoll: { id: 'ui.feedObject.poll.showPoll', defaultMessage: 'ui.feedObject.poll.showPoll' }, hidePoll: { id: 'ui.feedObject.poll.hidePoll', defaultMessage: 'ui.feedObject.poll.hidePoll' }, expDate: { id: 'ui.feedObject.poll.expDate', defaultMessage: 'ui.feedObject.poll.expDate' }, voters: { id: 'ui.feedObject.poll.voters', defaultMessage: 'ui.feedObject.poll.voters' }, votes: { id: 'ui.feedObject.poll.votes', defaultMessage: 'ui.feedObject.poll.votes' } }); const classes = { root: `${constants_1.PREFIX}-poll-object-root`, voters: `${constants_1.PREFIX}-poll-object-voters`, votes: `${constants_1.PREFIX}-poll-object-votes`, toggleButton: `${constants_1.PREFIX}-poll-object-toggle-button`, title: `${constants_1.PREFIX}-poll-object-title`, expiration: `${constants_1.PREFIX}-poll-object-expiration`, closed: `${constants_1.PREFIX}-poll-object-closed`, expandIcon: `${constants_1.PREFIX}-poll-object-expand-icon`, collapsedIcon: `${constants_1.PREFIX}-poll-object-collapsed-icon` }; const Root = (0, material_1.styled)(material_1.Card, { name: constants_1.PREFIX, slot: 'PollObjectRoot' })(() => ({})); function PollObject(props) { // PROPS const { className, feedObject, pollObject, disabled, visible = true, onChange, onToggleVisibility } = props, rest = tslib_1.__rest(props, ["className", "feedObject", "pollObject", "disabled", "visible", "onChange", "onToggleVisibility"]); // INTL const intl = (0, react_intl_1.useIntl)(); //STATE const [obj, setObj] = (0, react_1.useState)(pollObject); const [votes, setVotes] = (0, react_1.useState)(getVotes()); const [choices, setChoices] = (0, react_1.useState)(pollObject.choices); const [isVoting, setIsVoting] = (0, react_1.useState)(null); const [collapsed, setCollapsed] = (0, react_1.useState)(!visible); // CONST const multipleChoices = pollObject['multiple_choices']; const votable = pollObject['closed']; /** * Handles choice upvote */ const handleVote = (id) => { const prevChoices = [...choices]; let updatedChoices; if (multipleChoices) { updatedChoices = prevChoices.map((choice) => Object.assign({}, choice, { voted: choice.id === id ? true : choice.voted, vote_count: choice.id === id ? choice.vote_count + 1 : choice.vote_count })); setVotes((prevVotes) => prevVotes + 1); } else { updatedChoices = prevChoices.map((choice) => Object.assign({}, choice, { voted: choice.id === id, vote_count: choice.id === id ? choice.vote_count + 1 : choice.vote_count > 0 && choice.voted ? choice.vote_count - 1 : choice.vote_count })); setVotes(updatedChoices.reduce((totalVotes, choice) => totalVotes + choice.vote_count, 0)); } setChoices(updatedChoices); onChange(updatedChoices); }; /** * Handles choice unvote */ const handleUnVote = (id) => { const prevChoices = [...choices]; const updatedChoices = prevChoices.map((choice) => Object.assign({}, choice, { voted: choice.id === id ? false : choice.voted, vote_count: choice.id === id && choice.vote_count > 0 ? choice.vote_count - 1 : choice.vote_count })); setChoices(updatedChoices); onChange(updatedChoices); setVotes((prevVotes) => prevVotes - 1); }; /** * Gets total votes */ function getVotes() { const choices = pollObject.choices; let totalVotes = 0; let defaultVotes = 0; for (let i = 0; i < choices.length; i++) { totalVotes += choices[i].vote_count; } return totalVotes ? totalVotes : defaultVotes; } /** * Performs poll vote */ function vote(choiceObj) { setIsVoting(choiceObj.id); api_services_1.http .request({ url: api_services_1.Endpoints.PollVote.url({ id: feedObject.id, type: feedObject['type'] }), method: api_services_1.Endpoints.PollVote.method, data: { choice: choiceObj.id } }) .then((res) => { if (choiceObj.voted) { handleUnVote(choiceObj.id); } else { handleVote(choiceObj.id); } setIsVoting(null); }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); }); } /** * Handle toggle collapsed/uncollapsed poll */ const handleToggleCollapsedClick = (0, react_1.useMemo)(() => () => { onToggleVisibility && onToggleVisibility(collapsed); setCollapsed((prev) => !prev); }, [setCollapsed, onToggleVisibility]); /** * Renders the poll object */ let objElement = (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}); if (pollObject) { objElement = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.CardHeader, { title: (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ className: classes.toggleButton, onClick: handleToggleCollapsedClick, "aria-expanded": collapsed, endIcon: (0, jsx_runtime_1.jsx)(material_1.Icon, Object.assign({ className: (0, classnames_1.default)(classes.expandIcon, { [classes.collapsedIcon]: collapsed }) }, { children: "arrow_upward" })) }, { children: collapsed ? intl.formatMessage(messages.showPoll) : intl.formatMessage(messages.hidePoll) })) }) }), (0, jsx_runtime_1.jsx)(material_1.Collapse, Object.assign({ in: !collapsed, timeout: "auto", unmountOnExit: true }, { children: (0, jsx_runtime_1.jsxs)(material_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body1", className: classes.title }, { children: obj.title })), obj.expiration_at && Date.parse(obj.expiration_at) >= new Date().getTime() && ((0, jsx_runtime_1.jsxs)(material_1.Typography, Object.assign({ variant: "body2", className: classes.expiration }, { children: [`${intl.formatMessage(messages.expDate)}`, `${intl.formatDate(Date.parse(obj.expiration_at), { year: 'numeric', month: 'numeric', day: 'numeric' })}`] }))), obj.closed && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ variant: "body2", className: classes.closed }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.feedObject.poll.closed", defaultMessage: "ui.feedObject.poll.closed" }) }))), (0, jsx_runtime_1.jsx)(material_1.List, { children: choices.map((choice, index) => ((0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsx)(Choice_1.default, { elevation: 0, choiceObj: choice, feedObject: disabled ? null : feedObject, votes: votes, vote: vote, isVoting: isVoting, votable: votable }) }, index))) }), multipleChoices ? ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: classes.votes }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "list" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { children: `${intl.formatMessage(messages.votes, { total: votes })}` })] }))) : ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: classes.voters }, { children: [(0, jsx_runtime_1.jsx)(material_1.Icon, { children: "people_alt" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { children: `${intl.formatMessage(messages.voters, { total: votes })}` })] })))] }) }))] })); } (0, react_1.useEffect)(() => { setChoices(pollObject.choices); }, [pollObject.choices]); /** * Renders root element */ return ((0, jsx_runtime_1.jsx)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, rest, { children: objElement }))); } exports.default = PollObject;