UNPKG

@vocdoni/chakra-components

Version:
1,313 lines (1,283 loc) 236 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); // ../../node_modules/react-string-replace/index.js var require_react_string_replace = __commonJS({ "../../node_modules/react-string-replace/index.js"(exports, module) { var isRegExp = function(re) { return re instanceof RegExp; }; var escapeRegExp = function escapeRegExp2(string) { var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, reHasRegExpChar = RegExp(reRegExpChar.source); return string && reHasRegExpChar.test(string) ? string.replace(reRegExpChar, "\\$&") : string; }; var isString2 = function(value) { return typeof value === "string"; }; var flatten = function(array) { var newArray = []; array.forEach(function(item) { if (Array.isArray(item)) { newArray = newArray.concat(item); } else { newArray.push(item); } }); return newArray; }; function replaceString(str, match2, fn) { var curCharStart = 0; var curCharLen = 0; if (str === "") { return str; } else if (!str || !isString2(str)) { throw new TypeError("First argument to react-string-replace#replaceString must be a string"); } var re = match2; if (!isRegExp(re)) { re = new RegExp("(" + escapeRegExp(re) + ")", "gi"); } var result = str.split(re); for (var i2 = 1, length = result.length; i2 < length; i2 += 2) { if (result[i2] === void 0 || result[i2 - 1] === void 0) { console.warn("reactStringReplace: Encountered undefined value during string replacement. Your RegExp may not be working the way you expect."); continue; } curCharLen = result[i2].length; curCharStart += result[i2 - 1].length; result[i2] = fn(result[i2], i2, curCharStart); curCharStart += curCharLen; } return result; } module.exports = function reactStringReplace2(source, match2, fn) { if (!Array.isArray(source)) source = [source]; return flatten(source.map(function(x2) { return isString2(x2) ? replaceString(x2, match2, fn) : x2; })); }; } }); // src/client.tsx import { ToastProvider } from "@chakra-ui/react"; import { ClientProvider as RPClientProvider } from "@vocdoni/react-providers"; // ../../node_modules/ts-deepmerge/esm/index.js var isObject = (obj) => { if (typeof obj === "object" && obj !== null) { if (typeof Object.getPrototypeOf === "function") { const prototype = Object.getPrototypeOf(obj); return prototype === Object.prototype || prototype === null; } return Object.prototype.toString.call(obj) === "[object Object]"; } return false; }; var merge = (...objects) => objects.reduce((result, current) => { if (Array.isArray(current)) { throw new TypeError("Arguments provided to ts-deepmerge must be objects, not arrays."); } Object.keys(current).forEach((key) => { if (["__proto__", "constructor", "prototype"].includes(key)) { return; } if (Array.isArray(result[key]) && Array.isArray(current[key])) { result[key] = merge.options.mergeArrays ? merge.options.uniqueArrayItems ? Array.from(new Set(result[key].concat(current[key]))) : [...result[key], ...current[key]] : current[key]; } else if (isObject(result[key]) && isObject(current[key])) { result[key] = merge(result[key], current[key]); } else { result[key] = current[key] === void 0 ? merge.options.allowUndefinedOverrides ? current[key] : result[key] : current[key]; } }); return result; }, {}); var defaultOptions = { allowUndefinedOverrides: true, mergeArrays: true, uniqueArrayItems: true }; merge.options = defaultOptions; merge.withOptions = (options, ...objects) => { merge.options = Object.assign(Object.assign({}, defaultOptions), options); const result = merge(...objects); merge.options = defaultOptions; return result; }; var esm_default = merge; // src/components/Account/Balance.tsx import { Tag } from "@chakra-ui/react"; import { useClient } from "@vocdoni/react-providers"; import { jsx } from "react/jsx-runtime"; var Balance = (props) => { const { balance, localize: localize2 } = useClient(); if (balance < 0) { return null; } let color = "teal"; if (balance < 50 && balance > 20) { color = "yellow"; } else if (balance <= 20) { color = "red"; } return /* @__PURE__ */ jsx(Tag, { size: "sm", colorScheme: color, ...props, children: localize2("balance", { balance }) }); }; // src/components/Election/Actions/Actions.tsx import { ButtonGroup, chakra as chakra3, IconButton, useMultiStyleConfig as useMultiStyleConfig3 } from "@chakra-ui/react"; import { useClient as useClient7, useElection as useElection5 } from "@vocdoni/react-providers"; import { areEqualHexStrings as areEqualHexStrings5, ElectionStatus as ElectionStatus5, PublishedElection as PublishedElection5 } from "@vocdoni/sdk"; // ../../node_modules/react-icons/lib/esm/iconBase.js import React2 from "react"; // ../../node_modules/react-icons/lib/esm/iconContext.js import React from "react"; var DefaultContext = { color: void 0, size: void 0, className: void 0, style: void 0, attr: void 0 }; var IconContext = React.createContext && React.createContext(DefaultContext); // ../../node_modules/react-icons/lib/esm/iconBase.js var __assign = function() { __assign = Object.assign || function(t2) { for (var s3, i2 = 1, n = arguments.length; i2 < n; i2++) { s3 = arguments[i2]; for (var p in s3) if (Object.prototype.hasOwnProperty.call(s3, p)) t2[p] = s3[p]; } return t2; }; return __assign.apply(this, arguments); }; var __rest = function(s3, e2) { var t2 = {}; for (var p in s3) if (Object.prototype.hasOwnProperty.call(s3, p) && e2.indexOf(p) < 0) t2[p] = s3[p]; if (s3 != null && typeof Object.getOwnPropertySymbols === "function") for (var i2 = 0, p = Object.getOwnPropertySymbols(s3); i2 < p.length; i2++) { if (e2.indexOf(p[i2]) < 0 && Object.prototype.propertyIsEnumerable.call(s3, p[i2])) t2[p[i2]] = s3[p[i2]]; } return t2; }; function Tree2Element(tree) { return tree && tree.map(function(node, i2) { return React2.createElement(node.tag, __assign({ key: i2 }, node.attr), Tree2Element(node.child)); }); } function GenIcon(data) { return function(props) { return React2.createElement(IconBase, __assign({ attr: __assign({}, data.attr) }, props), Tree2Element(data.child)); }; } function IconBase(props) { var elem = function(conf) { var attr = props.attr, size = props.size, title = props.title, svgProps = __rest(props, ["attr", "size", "title"]); var computedSize = size || conf.size || "1em"; var className; if (conf.className) className = conf.className; if (props.className) className = (className ? className + " " : "") + props.className; return React2.createElement("svg", __assign({ stroke: "currentColor", fill: "currentColor", strokeWidth: "0" }, conf.attr, attr, svgProps, { className, style: __assign(__assign({ color: props.color || conf.color }, conf.style), props.style), height: computedSize, width: computedSize, xmlns: "http://www.w3.org/2000/svg" }), title && React2.createElement("title", null, title), props.children); }; return IconContext !== void 0 ? React2.createElement(IconContext.Consumer, null, function(conf) { return elem(conf); }) : elem(DefaultContext); } // ../../node_modules/react-icons/fa/index.esm.js function FaPause(props) { return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 448 512" }, "child": [{ "tag": "path", "attr": { "d": "M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z" } }] })(props); } function FaPlay(props) { return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 448 512" }, "child": [{ "tag": "path", "attr": { "d": "M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z" } }] })(props); } function FaStop(props) { return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 448 512" }, "child": [{ "tag": "path", "attr": { "d": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48z" } }] })(props); } // ../../node_modules/react-icons/im/index.esm.js function ImCross(props) { return GenIcon({ "tag": "svg", "attr": { "version": "1.1", "viewBox": "0 0 16 16" }, "child": [{ "tag": "path", "attr": { "d": "M15.854 12.854c-0-0-0-0-0-0l-4.854-4.854 4.854-4.854c0-0 0-0 0-0 0.052-0.052 0.090-0.113 0.114-0.178 0.066-0.178 0.028-0.386-0.114-0.529l-2.293-2.293c-0.143-0.143-0.351-0.181-0.529-0.114-0.065 0.024-0.126 0.062-0.178 0.114 0 0-0 0-0 0l-4.854 4.854-4.854-4.854c-0-0-0-0-0-0-0.052-0.052-0.113-0.090-0.178-0.114-0.178-0.066-0.386-0.029-0.529 0.114l-2.293 2.293c-0.143 0.143-0.181 0.351-0.114 0.529 0.024 0.065 0.062 0.126 0.114 0.178 0 0 0 0 0 0l4.854 4.854-4.854 4.854c-0 0-0 0-0 0-0.052 0.052-0.090 0.113-0.114 0.178-0.066 0.178-0.029 0.386 0.114 0.529l2.293 2.293c0.143 0.143 0.351 0.181 0.529 0.114 0.065-0.024 0.126-0.062 0.178-0.114 0-0 0-0 0-0l4.854-4.854 4.854 4.854c0 0 0 0 0 0 0.052 0.052 0.113 0.090 0.178 0.114 0.178 0.066 0.386 0.029 0.529-0.114l2.293-2.293c0.143-0.143 0.181-0.351 0.114-0.529-0.024-0.065-0.062-0.126-0.114-0.178z" } }] })(props); } // src/components/Election/Actions/ActionsProvider.tsx import { ActionsProvider as RActionsProvider } from "@vocdoni/react-providers"; // src/components/Election/Actions/use-actions-toast.ts import { useToast } from "@chakra-ui/react"; import { useActions } from "@vocdoni/react-providers"; import { useEffect, useRef } from "react"; var useActionsToast = () => { const tRef = useRef(); const { info, error } = useActions(); const toast = useToast(); useEffect(() => { if (toast && info === null && tRef.current) { toast.close(tRef.current); } if (info && toast) { tRef.current = toast({ title: info.title, description: info.description, status: "info", duration: null, isClosable: false }); } if (error && toast) { toast({ title: error.title, description: error.description, status: "error", duration: 7e3, isClosable: false }); } }, [info, error, toast]); }; // src/components/Election/Actions/ActionsProvider.tsx import { jsx as jsx2 } from "react/jsx-runtime"; var ActionsProvider = (props) => { return /* @__PURE__ */ jsx2(RActionsProvider, { children: /* @__PURE__ */ jsx2(ChakraInternalActionsProvider, { ...props }) }); }; var ChakraInternalActionsProvider = ({ children }) => { useActionsToast(); return children; }; // src/components/Election/Actions/Cancel.tsx import { Button as Button2, forwardRef } from "@chakra-ui/react"; import { useActions as useActions2, useClient as useClient3, useElection } from "@vocdoni/react-providers"; import { areEqualHexStrings, ElectionStatus, PublishedElection } from "@vocdoni/sdk"; // src/components/layout/ConfirmModal/ConfirmModal.tsx import { Modal, ModalContent, ModalOverlay, useMultiStyleConfig } from "@chakra-ui/react"; // src/components/layout/ConfirmModal/ConfirmProvider.tsx import { createContext, useContext, useState } from "react"; import { jsx as jsx3, jsxs } from "react/jsx-runtime"; var useConfirmProvider = () => { const [state, setState] = useState({ prompt: null, isOpen: false, proceed: null, cancel: null }); const confirm = (prompt) => new Promise((resolve, reject) => { setState({ prompt, isOpen: true, proceed: resolve, cancel: reject }); }).then( () => { setState({ ...state, isOpen: false }); return true; }, () => { setState({ ...state, isOpen: false }); return false; } ); return { ...state, confirm }; }; var ConfirmContext = createContext(void 0); var useConfirm = () => { const ctxt = useContext(ConfirmContext); if (!ctxt) { throw new Error( "useConfirm returned `undefined`, maybe you forgot to wrap the component within <ConfirmProvider />?" ); } return ctxt; }; var ConfirmProvider = ({ children }) => { const value = useConfirmProvider(); return /* @__PURE__ */ jsxs(ConfirmContext.Provider, { value, children: [ /* @__PURE__ */ jsx3(ConfirmModal, {}), children ] }); }; // src/components/layout/ConfirmModal/ConfirmModal.tsx import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime"; var ConfirmModal = () => { const styles = useMultiStyleConfig("ConfirmModal"); const { prompt, isOpen, cancel } = useConfirm(); return /* @__PURE__ */ jsxs2(Modal, { isOpen, onClose: cancel, children: [ /* @__PURE__ */ jsx4(ModalOverlay, { sx: styles.overlay }), /* @__PURE__ */ jsx4(ModalContent, { sx: styles.content, children: prompt }) ] }); }; // src/components/layout/HR.tsx import { chakra, useStyleConfig } from "@chakra-ui/react"; import { jsx as jsx5 } from "react/jsx-runtime"; var HR = (props) => { const { variant, ...rest } = props; const styles = useStyleConfig("HorizontalRuler", { variant }); return /* @__PURE__ */ jsx5(chakra.div, { __css: styles, ...rest, as: "hr" }); }; HR.displayName = "HorizontalRuler"; // src/components/layout/Image.tsx import { Avatar as CAvatar, Image as CImage } from "@chakra-ui/react"; import { jsx as jsx6 } from "react/jsx-runtime"; var linkify = (link, gateway) => { if (typeof link === "undefined") { return; } if (!link.startsWith("ipfs")) { return link; } const matches = link.match(/(?:ipfs:\/\/)?(.*)/); if (!matches) { return link; } const [, pin] = matches; return gateway + pin; }; var Image = ({ src, ...props }) => { if (!src && !props.fallbackSrc && !props.fallback) return null; const link = linkify(src, props.gateway || "https://infura-ipfs.io/ipfs/"); return /* @__PURE__ */ jsx6(CImage, { src: link, ...props }); }; var Avatar = ({ src, ...props }) => { if (!src) return null; const link = linkify(src, props.gateway || "https://infura-ipfs.io/ipfs/"); return /* @__PURE__ */ jsx6(CAvatar, { src: link, ...props }); }; // src/components/layout/Markdown.tsx import { Box, chakra as chakra2, Code, Heading, Link, ListItem, OrderedList, Table, Text, Tr, UnorderedList } from "@chakra-ui/react"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import { jsx as jsx7 } from "react/jsx-runtime"; var MD = ({ children, ...rest }) => { if (!children) { return null; } return /* @__PURE__ */ jsx7( ReactMarkdown, { remarkPlugins: [remarkGfm], components: { a: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(Link, { ...props, target: "_blank", children: children2 }), h1: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(Heading, { size: "lg", mt: 5, mb: 4, ...props, children: children2 }), h2: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(Heading, { size: "md", mt: 5, mb: 4, ...props, children: children2 }), h3: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(Heading, { as: "h3", size: "sm", mt: 5, mb: 4, ...props, children: children2 }), ol: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(OrderedList, { ...props, children: children2 }), ul: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(UnorderedList, { ...props, children: children2 }), li: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(ListItem, { ...props, children: children2 }), p: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(Text, { fontWeight: "medium", mb: 4, children: children2 }), table: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(Box, { overflowX: "auto", maxW: "full", children: /* @__PURE__ */ jsx7(Table, { ...props, children: children2 }) }), tr: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(Tr, { ...props, children: children2 }), code: ({ node, children: children2, ...props }) => /* @__PURE__ */ jsx7(Code, { ...props, children: children2 }) }, ...rest, children } ); }; var Markdown = chakra2(MD); Markdown.displayName = "Markdown"; // src/components/Election/Actions/ConfirmActionModal.tsx import { Button, ModalBody, ModalCloseButton, ModalFooter, ModalHeader, Text as Text2, useMultiStyleConfig as useMultiStyleConfig2 } from "@chakra-ui/react"; import { useClient as useClient2 } from "@vocdoni/react-providers"; import { Fragment, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime"; var ConfirmActionModal = ({ title, description, confirm, cancel, ...rest }) => { const mstyles = useMultiStyleConfig2("ConfirmModal"); const styles = useMultiStyleConfig2("QuestionsConfirmation", rest); const { cancel: cancelFn, proceed } = useConfirm(); const { localize: localize2 } = useClient2(); const _confirm = confirm || localize2("actions.confirm"); const _cancel = cancel || localize2("actions.cancel"); return /* @__PURE__ */ jsxs3(Fragment, { children: [ /* @__PURE__ */ jsx8(ModalHeader, { sx: mstyles.header, children: title }), /* @__PURE__ */ jsx8(ModalCloseButton, { sx: mstyles.close }), /* @__PURE__ */ jsx8(ModalBody, { sx: mstyles.body, children: /* @__PURE__ */ jsx8(Text2, { sx: styles.description, children: description }) }), /* @__PURE__ */ jsxs3(ModalFooter, { sx: mstyles.footer, children: [ /* @__PURE__ */ jsx8(Button, { onClick: cancelFn, variant: "ghost", sx: mstyles.cancel, children: _cancel }), /* @__PURE__ */ jsx8(Button, { onClick: proceed, sx: mstyles.confirm, children: _confirm }) ] }) ] }); }; // src/components/Election/Actions/Cancel.tsx import { jsx as jsx9 } from "react/jsx-runtime"; var ActionCancel = forwardRef((props, ref) => { const { account, localize: localize2 } = useClient3(); const { confirm } = useConfirm(); const { election } = useElection(); const { cancel, disabled, loading: { cancel: loading } } = useActions2(); const handle = async () => { if (await confirm( /* @__PURE__ */ jsx9( ConfirmActionModal, { title: localize2("confirm.cancel_process_title"), description: localize2("actions.cancel_description", { election }), confirm: localize2("confirm.cancel_process_button"), cancel: localize2("confirm.cancel_button") } ) )) { await cancel(); } }; if (!election || !(election instanceof PublishedElection) || !areEqualHexStrings(election.organizationId, account?.address)) { return null; } return /* @__PURE__ */ jsx9( Button2, { ref, isLoading: loading, onClick: handle, isDisabled: disabled || [ElectionStatus.CANCELED, ElectionStatus.ENDED, ElectionStatus.RESULTS].includes(election.status), children: localize2("actions.cancel"), shouldWrapChildren: true, ...props } ); }); // src/components/Election/Actions/Continue.tsx import { Button as Button3, forwardRef as forwardRef2 } from "@chakra-ui/react"; import { useActions as useActions3, useClient as useClient4, useElection as useElection2 } from "@vocdoni/react-providers"; import { areEqualHexStrings as areEqualHexStrings2, ElectionStatus as ElectionStatus2, PublishedElection as PublishedElection2 } from "@vocdoni/sdk"; import { jsx as jsx10 } from "react/jsx-runtime"; var ActionContinue = forwardRef2((props, ref) => { const { account, localize: localize2 } = useClient4(); const { election } = useElection2(); const { resume, disabled, loading: { continue: loading } } = useActions3(); if (!election || !(election instanceof PublishedElection2) || !areEqualHexStrings2(election.organizationId, account?.address)) { return null; } return /* @__PURE__ */ jsx10( Button3, { ref, isLoading: loading, onClick: resume, isDisabled: disabled || election.status !== ElectionStatus2.PAUSED, children: localize2("actions.continue"), shouldWrapChildren: true, ...props } ); }); // src/components/Election/Actions/End.tsx import { Button as Button4, forwardRef as forwardRef3 } from "@chakra-ui/react"; import { useActions as useActions4, useClient as useClient5, useElection as useElection3 } from "@vocdoni/react-providers"; import { areEqualHexStrings as areEqualHexStrings3, ElectionStatus as ElectionStatus3, PublishedElection as PublishedElection3 } from "@vocdoni/sdk"; import { jsx as jsx11 } from "react/jsx-runtime"; var ActionEnd = forwardRef3((props, ref) => { const { account, localize: localize2 } = useClient5(); const { confirm } = useConfirm(); const { election } = useElection3(); const { end, loading: { end: loading }, disabled } = useActions4(); const handle = async () => { if (await confirm( /* @__PURE__ */ jsx11( ConfirmActionModal, { title: localize2("confirm.end_process_title"), description: localize2("actions.end_description", { election }), confirm: localize2("confirm.end_process_button"), cancel: localize2("confirm.cancel_button") } ) )) { await end(); } }; if (!election || !(election instanceof PublishedElection3) || !areEqualHexStrings3(election.organizationId, account?.address)) { return null; } return /* @__PURE__ */ jsx11( Button4, { ref, isLoading: loading, onClick: handle, isDisabled: disabled || [ElectionStatus3.RESULTS, ElectionStatus3.ENDED, ElectionStatus3.CANCELED, ElectionStatus3.UPCOMING].includes( election.status ), children: localize2("actions.end"), shouldWrapChildren: true, ...props } ); }); // src/components/Election/Actions/Pause.tsx import { Button as Button5, forwardRef as forwardRef4 } from "@chakra-ui/react"; import { useActions as useActions5, useClient as useClient6, useElection as useElection4 } from "@vocdoni/react-providers"; import { areEqualHexStrings as areEqualHexStrings4, ElectionStatus as ElectionStatus4, PublishedElection as PublishedElection4 } from "@vocdoni/sdk"; import { jsx as jsx12 } from "react/jsx-runtime"; var ActionPause = forwardRef4((props, ref) => { const { account, localize: localize2 } = useClient6(); const { election } = useElection4(); const { pause, disabled, loading: { pause: loading } } = useActions5(); if (!election || !(election instanceof PublishedElection4) || !areEqualHexStrings4(election.organizationId, account?.address)) return null; return /* @__PURE__ */ jsx12( Button5, { ref, isLoading: loading, onClick: pause, isDisabled: disabled || election?.status !== ElectionStatus4.ONGOING, children: localize2("actions.pause"), shouldWrapChildren: true, ...props } ); }); // src/components/Election/Actions/Actions.tsx import { jsx as jsx13, jsxs as jsxs4 } from "react/jsx-runtime"; var Cancel = chakra3(ImCross); var Play = chakra3(FaPlay); var Pause = chakra3(FaPause); var Stop = chakra3(FaStop); var ElectionActions = (props) => { const { localize: localize2, account } = useClient7(); const { election } = useElection5(); const styles = useMultiStyleConfig3("ElectionActions"); if (!election || !(election instanceof PublishedElection5) || election && !areEqualHexStrings5(election.organizationId, account?.address) || [ElectionStatus5.CANCELED, ElectionStatus5.ENDED, ElectionStatus5.RESULTS].includes(election.status)) { return null; } return /* @__PURE__ */ jsx13(ButtonGroup, { size: "sm", isAttached: true, variant: "outline", position: "relative", sx: styles.group, ...props, children: /* @__PURE__ */ jsxs4(ActionsProvider, { children: [ /* @__PURE__ */ jsx13( ActionContinue, { as: IconButton, "aria-label": localize2("actions.continue"), title: localize2("actions.continue"), sx: styles.buttons, icon: /* @__PURE__ */ jsx13(Play, { sx: styles.icons }) } ), /* @__PURE__ */ jsx13( ActionPause, { as: IconButton, "aria-label": localize2("actions.pause"), title: localize2("actions.pause"), sx: styles.buttons, icon: /* @__PURE__ */ jsx13(Pause, { sx: styles.icons }) } ), /* @__PURE__ */ jsx13( ActionEnd, { as: IconButton, "aria-label": localize2("actions.end"), title: localize2("actions.end"), sx: styles.buttons, icon: /* @__PURE__ */ jsx13(Stop, { sx: styles.icons }) } ), /* @__PURE__ */ jsx13( ActionCancel, { as: IconButton, "aria-label": localize2("actions.cancel"), title: localize2("actions.cancel"), sx: styles.buttons, icon: /* @__PURE__ */ jsx13(Cancel, { sx: styles.icons }) } ) ] }) }); }; // src/components/Election/Description.tsx import { useStyleConfig as useStyleConfig2 } from "@chakra-ui/react"; import { useElection as useElection6 } from "@vocdoni/react-providers"; import { PublishedElection as PublishedElection6 } from "@vocdoni/sdk"; import { jsx as jsx14 } from "react/jsx-runtime"; var ElectionDescription = (props) => { const styles = useStyleConfig2("ElectionDescription", props); const { election } = useElection6(); if (!election || !(election instanceof PublishedElection6) || !election.description) { return null; } return /* @__PURE__ */ jsx14(Markdown, { ...props, sx: styles, children: election.description.default }); }; ElectionDescription.displayName = "ElectionDescription"; // src/components/Election/Election.tsx import { Alert, AlertDescription, AlertIcon } from "@chakra-ui/react"; import { ElectionProvider, useElection as useElection8 } from "@vocdoni/react-providers"; import { PublishedElection as PublishedElection8 } from "@vocdoni/sdk"; // src/components/Election/SpreadsheetAccess.tsx import { Button as Button6, FormControl, FormErrorMessage, FormHelperText, FormLabel, Input, Modal as Modal2, ModalBody as ModalBody2, ModalCloseButton as ModalCloseButton2, ModalContent as ModalContent2, ModalFooter as ModalFooter2, ModalHeader as ModalHeader2, ModalOverlay as ModalOverlay2, useDisclosure, useMultiStyleConfig as useMultiStyleConfig4, useToast as useToast2 } from "@chakra-ui/react"; import { Wallet } from "@ethersproject/wallet"; import { errorToString, useClient as useClient8, useElection as useElection7, walletFromRow } from "@vocdoni/react-providers"; import { PublishedElection as PublishedElection7, VocdoniSDKClient } from "@vocdoni/sdk"; import { useEffect as useEffect2, useState as useState2 } from "react"; // ../../node_modules/react-hook-form/dist/index.esm.mjs import React3 from "react"; var isCheckBoxInput = (element) => element.type === "checkbox"; var isDateObject = (value) => value instanceof Date; var isNullOrUndefined = (value) => value == null; var isObjectType = (value) => typeof value === "object"; var isObject2 = (value) => !isNullOrUndefined(value) && !Array.isArray(value) && isObjectType(value) && !isDateObject(value); var getEventValue = (event) => isObject2(event) && event.target ? isCheckBoxInput(event.target) ? event.target.checked : event.target.value : event; var getNodeParentName = (name) => name.substring(0, name.search(/\.\d+(\.|$)/)) || name; var isNameInFieldArray = (names, name) => names.has(getNodeParentName(name)); var isPlainObject = (tempObject) => { const prototypeCopy = tempObject.constructor && tempObject.constructor.prototype; return isObject2(prototypeCopy) && prototypeCopy.hasOwnProperty("isPrototypeOf"); }; var isWeb = typeof window !== "undefined" && typeof window.HTMLElement !== "undefined" && typeof document !== "undefined"; function cloneObject(data) { let copy; const isArray = Array.isArray(data); const isFileListInstance = typeof FileList !== "undefined" ? data instanceof FileList : false; if (data instanceof Date) { copy = new Date(data); } else if (!(isWeb && (data instanceof Blob || isFileListInstance)) && (isArray || isObject2(data))) { copy = isArray ? [] : Object.create(Object.getPrototypeOf(data)); if (!isArray && !isPlainObject(data)) { copy = data; } else { for (const key in data) { if (data.hasOwnProperty(key)) { copy[key] = cloneObject(data[key]); } } } } else { return data; } return copy; } var isKey = (value) => /^\w*$/.test(value); var isUndefined = (val) => val === void 0; var compact = (value) => Array.isArray(value) ? value.filter(Boolean) : []; var stringToPath = (input) => compact(input.replace(/["|']|\]/g, "").split(/\.|\[/)); var get = (object, path, defaultValue) => { if (!path || !isObject2(object)) { return defaultValue; } const result = (isKey(path) ? [path] : stringToPath(path)).reduce((result2, key) => isNullOrUndefined(result2) ? result2 : result2[key], object); return isUndefined(result) || result === object ? isUndefined(object[path]) ? defaultValue : object[path] : result; }; var isBoolean = (value) => typeof value === "boolean"; var set = (object, path, value) => { let index = -1; const tempPath = isKey(path) ? [path] : stringToPath(path); const length = tempPath.length; const lastIndex = length - 1; while (++index < length) { const key = tempPath[index]; let newValue = value; if (index !== lastIndex) { const objValue = object[key]; newValue = isObject2(objValue) || Array.isArray(objValue) ? objValue : !isNaN(+tempPath[index + 1]) ? [] : {}; } if (key === "__proto__" || key === "constructor" || key === "prototype") { return; } object[key] = newValue; object = object[key]; } }; var EVENTS = { BLUR: "blur", FOCUS_OUT: "focusout", CHANGE: "change" }; var VALIDATION_MODE = { onBlur: "onBlur", onChange: "onChange", onSubmit: "onSubmit", onTouched: "onTouched", all: "all" }; var INPUT_VALIDATION_RULES = { max: "max", min: "min", maxLength: "maxLength", minLength: "minLength", pattern: "pattern", required: "required", validate: "validate" }; var HookFormContext = React3.createContext(null); HookFormContext.displayName = "HookFormContext"; var useFormContext = () => React3.useContext(HookFormContext); var FormProvider = (props) => { const { children, ...data } = props; return React3.createElement(HookFormContext.Provider, { value: data }, children); }; var getProxyFormState = (formState, control, localProxyFormState, isRoot = true) => { const result = { defaultValues: control._defaultValues }; for (const key in formState) { Object.defineProperty(result, key, { get: () => { const _key = key; if (control._proxyFormState[_key] !== VALIDATION_MODE.all) { control._proxyFormState[_key] = !isRoot || VALIDATION_MODE.all; } localProxyFormState && (localProxyFormState[_key] = true); return formState[_key]; } }); } return result; }; var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React3.useLayoutEffect : React3.useEffect; function useFormState(props) { const methods = useFormContext(); const { control = methods.control, disabled, name, exact } = props || {}; const [formState, updateFormState] = React3.useState(control._formState); const _localProxyFormState = React3.useRef({ isDirty: false, isLoading: false, dirtyFields: false, touchedFields: false, validatingFields: false, isValidating: false, isValid: false, errors: false }); useIsomorphicLayoutEffect(() => control._subscribe({ name, formState: _localProxyFormState.current, exact, callback: (formState2) => { !disabled && updateFormState({ ...control._formState, ...formState2 }); } }), [name, disabled, exact]); React3.useEffect(() => { _localProxyFormState.current.isValid && control._setValid(true); }, [control]); return React3.useMemo(() => getProxyFormState(formState, control, _localProxyFormState.current, false), [formState, control]); } var isString = (value) => typeof value === "string"; var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) => { if (isString(names)) { isGlobal && _names.watch.add(names); return get(formValues, names, defaultValue); } if (Array.isArray(names)) { return names.map((fieldName) => (isGlobal && _names.watch.add(fieldName), get(formValues, fieldName))); } isGlobal && (_names.watchAll = true); return formValues; }; var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value); function deepEqual(object1, object2, _internal_visited = /* @__PURE__ */ new WeakSet()) { if (isPrimitive(object1) || isPrimitive(object2)) { return object1 === object2; } if (isDateObject(object1) && isDateObject(object2)) { return object1.getTime() === object2.getTime(); } const keys1 = Object.keys(object1); const keys2 = Object.keys(object2); if (keys1.length !== keys2.length) { return false; } if (_internal_visited.has(object1) || _internal_visited.has(object2)) { return true; } _internal_visited.add(object1); _internal_visited.add(object2); for (const key of keys1) { const val1 = object1[key]; if (!keys2.includes(key)) { return false; } if (key !== "ref") { const val2 = object2[key]; if (isDateObject(val1) && isDateObject(val2) || isObject2(val1) && isObject2(val2) || Array.isArray(val1) && Array.isArray(val2) ? !deepEqual(val1, val2, _internal_visited) : val1 !== val2) { return false; } } } return true; } function useWatch(props) { const methods = useFormContext(); const { control = methods.control, name, defaultValue, disabled, exact, compute } = props || {}; const _defaultValue = React3.useRef(defaultValue); const _compute = React3.useRef(compute); const _computeFormValues = React3.useRef(void 0); _compute.current = compute; const defaultValueMemo = React3.useMemo(() => control._getWatch(name, _defaultValue.current), [control, name]); const [value, updateValue] = React3.useState(_compute.current ? _compute.current(defaultValueMemo) : defaultValueMemo); useIsomorphicLayoutEffect(() => control._subscribe({ name, formState: { values: true }, exact, callback: (formState) => { if (!disabled) { const formValues = generateWatchOutput(name, control._names, formState.values || control._formValues, false, _defaultValue.current); if (_compute.current) { const computedFormValues = _compute.current(formValues); if (!deepEqual(computedFormValues, _computeFormValues.current)) { updateValue(computedFormValues); _computeFormValues.current = computedFormValues; } } else { updateValue(formValues); } } } }), [control, disabled, name, exact]); React3.useEffect(() => control._removeUnmounted()); return value; } function useController(props) { const methods = useFormContext(); const { name, disabled, control = methods.control, shouldUnregister, defaultValue } = props; const isArrayField = isNameInFieldArray(control._names.array, name); const defaultValueMemo = React3.useMemo(() => get(control._formValues, name, get(control._defaultValues, name, defaultValue)), [control, name, defaultValue]); const value = useWatch({ control, name, defaultValue: defaultValueMemo, exact: true }); const formState = useFormState({ control, name, exact: true }); const _props = React3.useRef(props); const _registerProps = React3.useRef(control.register(name, { ...props.rules, value, ...isBoolean(props.disabled) ? { disabled: props.disabled } : {} })); _props.current = props; const fieldState = React3.useMemo(() => Object.defineProperties({}, { invalid: { enumerable: true, get: () => !!get(formState.errors, name) }, isDirty: { enumerable: true, get: () => !!get(formState.dirtyFields, name) }, isTouched: { enumerable: true, get: () => !!get(formState.touchedFields, name) }, isValidating: { enumerable: true, get: () => !!get(formState.validatingFields, name) }, error: { enumerable: true, get: () => get(formState.errors, name) } }), [formState, name]); const onChange = React3.useCallback((event) => _registerProps.current.onChange({ target: { value: getEventValue(event), name }, type: EVENTS.CHANGE }), [name]); const onBlur = React3.useCallback(() => _registerProps.current.onBlur({ target: { value: get(control._formValues, name), name }, type: EVENTS.BLUR }), [name, control._formValues]); const ref = React3.useCallback((elm) => { const field2 = get(control._fields, name); if (field2 && elm) { field2._f.ref = { focus: () => elm.focus && elm.focus(), select: () => elm.select && elm.select(), setCustomValidity: (message) => elm.setCustomValidity(message), reportValidity: () => elm.reportValidity() }; } }, [control._fields, name]); const field = React3.useMemo(() => ({ name, value, ...isBoolean(disabled) || formState.disabled ? { disabled: formState.disabled || disabled } : {}, onChange, onBlur, ref }), [name, disabled, formState.disabled, onChange, onBlur, ref, value]); React3.useEffect(() => { const _shouldUnregisterField = control._options.shouldUnregister || shouldUnregister; control.register(name, { ..._props.current.rules, ...isBoolean(_props.current.disabled) ? { disabled: _props.current.disabled } : {} }); const updateMounted = (name2, value2) => { const field2 = get(control._fields, name2); if (field2 && field2._f) { field2._f.mount = value2; } }; updateMounted(name, true); if (_shouldUnregisterField) { const value2 = cloneObject(get(control._options.defaultValues, name)); set(control._defaultValues, name, value2); if (isUndefined(get(control._formValues, name))) { set(control._formValues, name, value2); } } !isArrayField && control.register(name); return () => { (isArrayField ? _shouldUnregisterField && !control._state.action : _shouldUnregisterField) ? control.unregister(name) : updateMounted(name, false); }; }, [name, control, isArrayField, shouldUnregister]); React3.useEffect(() => { control._setDisabledField({ disabled, name }); }, [disabled, name, control]); return React3.useMemo(() => ({ field, formState, fieldState }), [field, formState, fieldState]); } var Controller = (props) => props.render(useController(props)); var appendErrors = (name, validateAllFieldCriteria, errors, type, message) => validateAllFieldCriteria ? { ...errors[name], types: { ...errors[name] && errors[name].types ? errors[name].types : {}, [type]: message || true } } : {}; var convertToArrayPayload = (value) => Array.isArray(value) ? value : [value]; var createSubject = () => { let _observers = []; const next = (value) => { for (const observer of _observers) { observer.next && observer.next(value); } }; const subscribe = (observer) => { _observers.push(observer); return { unsubscribe: () => { _observers = _observers.filter((o) => o !== observer); } }; }; const unsubscribe = () => { _observers = []; }; return { get observers() { return _observers; }, next, subscribe, unsubscribe }; }; var isEmptyObject = (value) => isObject2(value) && !Object.keys(value).length; var isFileInput = (element) => element.type === "file"; var isFunction = (value) => typeof value === "function"; var isHTMLElement = (value) => { if (!isWeb) { return false; } const owner = value ? value.ownerDocument : 0; return value instanceof (owner && owner.defaultView ? owner.defaultView.HTMLElement : HTMLElement); }; var isMultipleSelect = (element) => element.type === `select-multiple`; var isRadioInput = (element) => element.type === "radio"; var isRadioOrCheckbox = (ref) => isRadioInput(ref) || isCheckBoxInput(ref); var live = (ref) => isHTMLElement(ref) && ref.isConnected; function baseGet(object, updatePath) { const length = updatePath.slice(0, -1).length; let index = 0; while (index < length) { object = isUndefined(object) ? index++ : object[updatePath[index++]]; } return object; } function isEmptyArray(obj) { for (const key in obj) { if (obj.hasOwnProperty(key) && !isUndefined(obj[key])) { return false; } } return true; } function unset(object, path) { const paths = Array.isArray(path) ? path : isKey(path) ? [path] : stringToPath(path); const childObject = paths.length === 1 ? object : baseGet(object, paths); const index = paths.length - 1; const key = paths[index]; if (childObject) { delete childObject[key]; } if (index !== 0 && (isObject2(childObject) && isEmptyObject(childObject) || Array.isArray(childObject) && isEmptyArray(childObject))) { unset(object, paths.slice(0, -1)); } return object; } var objectHasFunction = (data) => { for (const key in data) { if (isFunction(data[key])) { return true; } } return false; }; function markFieldsDirty(data, fields = {}) { const isParentNodeArray = Array.isArray(data); if (isObject2(data) || isParentNodeArray) { for (const key in data) { if (Array.isArray(data[key]) || isObject2(data[key]) && !objectHasFunction(data[key])) { fields[key] = Array.isArray(data[key]) ? [] : {}; markFieldsDirty(data[key], fields[key]); } else if (!isNullOrUndefined(data[key])) { fields[key] = true; } } } return fields; } function getDirtyFieldsFromDefaultValues(data, formValues, dirtyFieldsFromValues) { const isParentNodeArray = Array.isArray(data); if (isObject2(data) || isParentNodeArray) { for (const key in data) { if (Array.isArray(data[key]) || isObject2(data[key]) && !objectHasFunction(data[key])) { if (isUndefined(formValues) || isPrimitive(dirtyFieldsFromValues[key])) { dirtyFieldsFromValues[key] = Array.isArray(data[key]) ? markFieldsDirty(data[key], []) : { ...markFieldsDirty(data[key]) }; } else { getDirtyFieldsFromDefaultValues(data[key], isNullOrUndefined(formValues) ? {} : formValues[key], dirtyFieldsFromValues[key]); } } else { dirtyFieldsFromValues[key] = !deepEqual(data[key], formValues[key]); } } } return dirtyFieldsFromValues; } var getDirtyFields = (defaultValues, formValues) => getDirtyFieldsFromDefaultValues(defaultValues, formValues, markFieldsDirty(formValues)); var defaultResult = { value: false, isValid: false }; var validResult = { value: true, isValid: true }; var getCheckboxValue = (options) => { if (Array.isArray(options)) { if (options.length > 1) { const values = options.filter((option) => option && option.checked && !option.disabled).map((option) => option.value); return { value: values, isValid: !!values.length }; } return options[0].checked && !options[0].disabled ? ( // @ts-expect-error expected to work in the browser options[0].attributes && !isUndefined(options[0].attributes.value) ? isUndefined(options[0].value) || options[0].value === "" ? validResult : { value: options[0].value, isValid: true } : validResult ) : defaultResult; } return defaultResult; }; var getFieldValueAs = (value, { valueAsNumber, valueAsDate, setValueAs }) => isUndefined(value) ? value : valueAsNumber ? value === "" ? NaN : value ? +value : value : valueAsDate && isString(value) ? new Date(value) : setValueAs ? setValueAs(value) : value; var defaultReturn = { isValid: false, value: null }; var getRadioValue = (options) => Array.isArray(options) ? options.reduce((previous, option) => option && option.checked && !option.disabled ? { isValid: true, value: option.value } : previous, defaultReturn) : defaultReturn; function getFieldValue(_f) { const ref = _f.ref; if (isFileInput(ref)) { return ref.files; } if (isRadioInput(ref)) { return getRadioValue(_f.refs).value; } if (isMultipleSelect(ref)) { return [...ref.selectedOptions].map(({ value }) => value); } if (isCheckBoxInput(ref)) { return getCheckboxValue(_f.refs).value; } return getFieldValueAs(isUndefined(ref.value) ? _f.ref.value : ref.value, _f); } var getResolverOptions = (fieldsNames, _fields, criteriaMode, shouldUseNativeValidation) => { const fields = {}; for (const name of fieldsNames) { const field = get(_fields, name); field && set(fields, name, field._f); } return { criteriaMode, names: [...fieldsNames], fields, shouldUseNativeValidation }; }; var isRegex = (value) => value instanceof RegExp; var getRuleValue = (rule) => isUndefined(rule) ? rule : isRegex(rule) ? rule.source : isObject2(rule) ? isRegex(rule.value) ? rule.value.source : rule.value : rule; var getValidationModes = (mode) => ({ isOnSubmit: !mode || mode === VALIDATION_MODE.onSubmit, isOnBlur: mode === VALIDATION_MODE.onBlur, isOnChange: mode === VALIDATION_MODE.onChange, isOnAll: mode === VALIDATION_MODE.all, isOnTouch: mode === VALIDATION_MODE.onTouched }); var ASYNC_FUNCTION = "AsyncFunction"; var hasPromiseValidation = (fieldReference) => !!fieldReference && !!fieldReference.validate && !!(isFunction(fieldReference.validate) && fieldReference.validate.constructor.name === ASYNC_FUNCTION || isObject2(fieldReference.validate) && Object.values(fieldReference.validate).find((validateFunction) => validateFunction.constructor.name === ASYNC_FUNCTION)); var hasValidation = (options) => options.mount && (options.required || options.min || options.max || options.maxLength || options.minLength || options.pattern || options.validate); var isWatched = (name, _names, isBlurEvent) => !isBlurEvent && (_names.watchAll || _names.watch.has(name) || [..._names.watch].some((watchName) => name.startsWith(watchName) && /^\.\w+/.test(name.slice(watchName.length)))); var iterateFieldsByAction = (fields, action, fieldsNames, abortEarly) => { for (const key of fieldsNames || Object.keys(fields)) { const field = get(fields, key); if (field) { const { _f, ...currentField } = field; if (_f) { if (_f.refs && _f.refs[0] && action(_f.refs[0], key) && !abortEarly) { return true; } else if (_f.ref && action(_f.ref, _f.name) && !abortEarly) { return true; } else { if (iterateFieldsByAction(currentField, action)) { break; } } } else if (isObject2(currentField)) { if (iterateFieldsByAction(currentField, action)) { break; } } } } return; }; function schemaErrorLookup(errors, _fields, name) { const error = get(errors, name); if (error || isKey(name)) { return { error, name }; } const names = name.split("."); while (names.length) { const fieldName = names.join("."); const field = get(_fields, fieldName); const foundError = get(errors, fieldName); if (field && !Array.isArray(field) && name !== fieldName) { return { name }; } if (foundError && foundError.type) { return { name: fieldName, error: foundError }; } if (foundError && foundError.root && foundError.root.type) { return { name: `${fieldName}.root`, error: foundError.root }; } names.pop(); } return { name }; } var shouldRenderFormState = (formStateData, _proxyFormState, updateFormState, isRoot) => { updateFormState(formStateData); const { name, ...formState } = formStateData; return isEmptyObject(formState) || Object.keys(formState).length >= Object.keys(_proxyFormState).length || Object.keys(formState).find((key) => _proxyFormState[key] === (!isRoot || VALIDATION_MODE.all)); }; var shouldSubscribeByName = (name, signalName, exact) => !name ||