UNPKG

alpha-version-dce-check-in-ui

Version:

UI for taking attendance and checking people in.

1,239 lines (1,179 loc) 474 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); var reactFontawesome = require('@fortawesome/react-fontawesome'); var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons'); var freeRegularSvgIcons = require('@fortawesome/free-regular-svg-icons'); var QRCode = require('qrcode'); var require$$0$1 = require('crypto'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var QRCode__default = /*#__PURE__*/_interopDefaultLegacy(QRCode); var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$1); /** * Input group with a title and space for buttons * @author Gabe Abrams */ /*------------------------------------------------------------------------*/ /* ------------------------------ Component ----------------------------- */ /*------------------------------------------------------------------------*/ const ButtonInputGroup = (props) => { /*------------------------------------------------------------------------*/ /* -------------------------------- Setup ------------------------------- */ /*------------------------------------------------------------------------*/ /* -------------- Props ------------- */ // Destructure all props const { label, minLabelWidth, children, className, wrapButtonsAndAddGaps, } = props; /*------------------------------------------------------------------------*/ /* ------------------------------- Render ------------------------------- */ /*------------------------------------------------------------------------*/ /*----------------------------------------*/ /* --------------- Main UI -------------- */ /*----------------------------------------*/ return (React__default["default"].createElement("div", { className: `input-group ${className !== null && className !== void 0 ? className : ''}` }, React__default["default"].createElement("div", { className: "input-group-prepend d-flex w-100" }, React__default["default"].createElement("span", { className: "input-group-text", style: { minWidth: (minLabelWidth !== null && minLabelWidth !== void 0 ? minLabelWidth : undefined), borderTopRightRadius: 0, borderBottomRightRadius: 0, } }, label), React__default["default"].createElement("span", { className: "input-group-text flex-grow-1 rounded-right d-flex flex-wrap", style: { backgroundColor: 'white', borderTopLeftRadius: 0, borderBottomLeftRadius: 0, borderLeftWidth: 0, } }, wrapButtonsAndAddGaps ? (React__default["default"].createElement("div", { className: "d-flex gap-1 flex-wrap" }, children)) : children)))); }; /** * Bootstrap variants * @author Gabe Abrams */ var Variant; (function (Variant) { Variant["Primary"] = "primary"; Variant["Secondary"] = "secondary"; Variant["Success"] = "success"; Variant["Warning"] = "warning"; Variant["Info"] = "info"; Variant["Danger"] = "danger"; Variant["Light"] = "light"; Variant["Dark"] = "dark"; })(Variant || (Variant = {})); var Variant$1 = Variant; /** * A checkbox button * @author Gabe Abrams */ /*------------------------------------------------------------------------*/ /* ------------------------------ Component ----------------------------- */ /*------------------------------------------------------------------------*/ const CheckboxButton = (props) => { /*------------------------------------------------------------------------*/ /* -------------------------------- Setup ------------------------------- */ /*------------------------------------------------------------------------*/ /* -------------- Props ------------- */ const { text, onChanged, ariaLabel, title, checked, id, className, noMarginOnRight, checkedVariant = (Variant$1.Secondary), uncheckedVariant = (Variant$1.Light), small, dashed, } = props; /*------------------------------------------------------------------------*/ /* ------------------------------- Render ------------------------------- */ /*------------------------------------------------------------------------*/ /*----------------------------------------*/ /* --------------- Main UI -------------- */ /*----------------------------------------*/ // Determine the icon let icon; if (checked) { icon = freeSolidSvgIcons.faCheckSquare; } else { icon = (dashed ? freeRegularSvgIcons.faSquareMinus : freeRegularSvgIcons.faSquare); } // Create the button return (React__default["default"].createElement("button", { type: "button", id: id, title: title, className: `CheckboxButton-status-${checked ? 'checked' : 'unchecked'} ${dashed ? 'CheckboxButton-dashed ' : ''}btn btn-${checked ? checkedVariant : uncheckedVariant}${checked ? ' selected' : ''}${small ? ' btn-sm' : ''} m-0${noMarginOnRight ? '' : ' me-1'} ${className !== null && className !== void 0 ? className : ''}`, "aria-label": `${ariaLabel}${checked ? ': currently checked' : ''}`, onClick: () => { onChanged(!checked); } }, React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: icon, className: "me-1" }), text)); }; /** * Drawer container * @author Gabe Abrams */ /*------------------------------------------------------------------------*/ /* -------------------------------- Style ------------------------------- */ /*------------------------------------------------------------------------*/ const style$5 = ` .Drawer-container { margin-left: 1rem; margin-right: 1rem; margin-top: 0; margin-bottom: 1rem; padding: 0.75rem; border-left: 1px solid #dee2e6; border-bottom: 1px solid #dee2e6; border-right: 1px solid #dee2e6; border-bottom-left-radius: .25rem; border-bottom-right-radius: .25rem; box-shadow: inset 0 0 0.5rem 0 rgba(0, 0, 0, 0.05); } `; /*------------------------------------------------------------------------*/ /* ------------------------------ Component ----------------------------- */ /*------------------------------------------------------------------------*/ const Drawer = (props) => { /*------------------------------------------------------------------------*/ /* -------------------------------- Setup ------------------------------- */ /*------------------------------------------------------------------------*/ /* -------------- Props ------------- */ // Destructure all props const { customBackgroundColor, children, } = props; /*------------------------------------------------------------------------*/ /* ------------------------------- Render ------------------------------- */ /*------------------------------------------------------------------------*/ /*----------------------------------------*/ /* --------------- Main UI -------------- */ /*----------------------------------------*/ return (React__default["default"].createElement("div", { className: "Drawer-container", style: { backgroundColor: (customBackgroundColor !== null && customBackgroundColor !== void 0 ? customBackgroundColor : undefined), } }, React__default["default"].createElement("style", null, style$5), children)); }; /** * Loading spinner/indicator * @author Gabe Abrams */ /*------------------------------------------------------------------------*/ /* -------------------------------- Style ------------------------------- */ /*------------------------------------------------------------------------*/ const style$4 = ` /* Container fades in */ .LoadingSpinner-container { animation-name: LoadingSpinner-container-fade-in; animation-duration: 0.3s; animation-delay: 0.4s; animation-fill-mode: both; animation-timing-function: ease-out; } @keyframes LoadingSpinner-container-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } } /* Blips */ .LoadingSpinner-blip-1, .LoadingSpinner-blip-2, .LoadingSpinner-blip-3, .LoadingSpinner-blip-4 { font-size: 1.8rem; opacity: 0.6; margin-top: 1rem; margin-bottom: 1rem; } /* First Blip */ .LoadingSpinner-blip-1 { animation: LoadingSpinner-pop-animation 2s infinite; } /* Second Blip */ .LoadingSpinner-blip-2 { animation: LoadingSpinner-pop-animation 2s infinite; -webkit-animation-delay: 0.1s; animation-delay: 0.1s; } /* Third Blip */ .LoadingSpinner-blip-3 { animation: LoadingSpinner-pop-animation 2s infinite; animation-delay: 0.2s; } /* Fourth Blip */ .LoadingSpinner-blip-4 { animation: LoadingSpinner-pop-animation 2s infinite; animation-delay: 0.3s; } /* Pop Animation for Each Blip */ @keyframes LoadingSpinner-pop-animation { 0% { transform: scale(1.0); } 10% { transform: scale(1.5); } 30% { transform: scale(1.0); } 100% { transform: scale(1.0); } } `; /*------------------------------------------------------------------------*/ /* ------------------------------ Component ----------------------------- */ /*------------------------------------------------------------------------*/ const LoadingSpinner = () => { /*------------------------------------------------------------------------*/ /* ------------------------------- Render ------------------------------- */ /*------------------------------------------------------------------------*/ // Add all four blips to a container return (React__default["default"].createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" }, React__default["default"].createElement("style", null, style$4), React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-1 me-1" }), React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-2 me-1" }), React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-3 me-1" }), React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-4" }))); }; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function __param(paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } } function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); var _, done = false; for (var i = decorators.length - 1; i >= 0; i--) { var context = {}; for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; for (var p in contextIn.access) context.access[p] = contextIn.access[p]; context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); if (kind === "accessor") { if (result === void 0) continue; if (result === null || typeof result !== "object") throw new TypeError("Object expected"); if (_ = accept(result.get)) descriptor.get = _; if (_ = accept(result.set)) descriptor.set = _; if (_ = accept(result.init)) initializers.unshift(_); } else if (_ = accept(result)) { if (kind === "field") initializers.unshift(_); else descriptor[key] = _; } } if (target) Object.defineProperty(target, contextIn.name, descriptor); done = true; } function __runInitializers(thisArg, initializers, value) { var useValue = arguments.length > 2; for (var i = 0; i < initializers.length; i++) { value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); } return useValue ? value : void 0; } function __propKey(x) { return typeof x === "symbol" ? x : "".concat(x); } function __setFunctionName(f, name, prefix) { if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); } function __metadata(metadataKey, metadataValue) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); } function __awaiter$5(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var __createBinding = Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); function __exportStar(m, o) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); } function __values(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); } function __read(o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; } /** @deprecated */ function __spread() { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; } /** @deprecated */ function __spreadArrays() { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; } function __spreadArray(to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); } function __await(v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } function __asyncGenerator(thisArg, _arguments, generator) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var g = generator.apply(thisArg, _arguments || []), i, q = []; return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } function fulfill(value) { resume("next", value); } function reject(value) { resume("throw", value); } function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } } function __asyncDelegator(o) { var i, p; return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } } function __asyncValues(o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; } var __setModuleDefault = Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }; function __importStar(mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; } function __importDefault$b(mod) { return (mod && mod.__esModule) ? mod : { default: mod }; } function __classPrivateFieldGet(receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); } function __classPrivateFieldSet(receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; } function __classPrivateFieldIn(state, receiver) { if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); return typeof state === "function" ? receiver === state : state.has(receiver); } function __addDisposableResource(env, value, async) { if (value !== null && value !== void 0) { if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); var dispose; if (async) { if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); dispose = value[Symbol.asyncDispose]; } if (dispose === void 0) { if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); dispose = value[Symbol.dispose]; } if (typeof dispose !== "function") throw new TypeError("Object not disposable."); env.stack.push({ value: value, dispose: dispose, async: async }); } else if (async) { env.stack.push({ async: true }); } return value; } var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; function __disposeResources(env) { function fail(e) { env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; env.hasError = true; } function next() { while (env.stack.length) { var rec = env.stack.pop(); try { var result = rec.dispose && rec.dispose.call(rec.value); if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); } catch (e) { fail(e); } } if (env.hasError) throw env.error; } return next(); } var tslib_es6 = { __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter: __awaiter$5, __generator, __createBinding, __exportStar, __values, __read, __spread, __spreadArrays, __spreadArray, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault: __importDefault$b, __classPrivateFieldGet, __classPrivateFieldSet, __classPrivateFieldIn, __addDisposableResource, __disposeResources, }; var tslib_es6$1 = /*#__PURE__*/Object.freeze({ __proto__: null, __extends: __extends, get __assign () { return __assign; }, __rest: __rest, __decorate: __decorate, __param: __param, __esDecorate: __esDecorate, __runInitializers: __runInitializers, __propKey: __propKey, __setFunctionName: __setFunctionName, __metadata: __metadata, __awaiter: __awaiter$5, __generator: __generator, __createBinding: __createBinding, __exportStar: __exportStar, __values: __values, __read: __read, __spread: __spread, __spreadArrays: __spreadArrays, __spreadArray: __spreadArray, __await: __await, __asyncGenerator: __asyncGenerator, __asyncDelegator: __asyncDelegator, __asyncValues: __asyncValues, __makeTemplateObject: __makeTemplateObject, __importStar: __importStar, __importDefault: __importDefault$b, __classPrivateFieldGet: __classPrivateFieldGet, __classPrivateFieldSet: __classPrivateFieldSet, __classPrivateFieldIn: __classPrivateFieldIn, __addDisposableResource: __addDisposableResource, __disposeResources: __disposeResources, 'default': tslib_es6 }); /** * Wait for a certain number of ms * @author Gabe Abrams * @param ms number of ms to wait */ const waitMs = (ms = 0) => __awaiter$5(void 0, void 0, void 0, function* () { return new Promise((resolve) => { setTimeout(resolve, ms); }); }); /** * Types of buttons in the modal * @author Gabe Abrams */ var ModalButtonType; (function (ModalButtonType) { ModalButtonType["Okay"] = "okay"; ModalButtonType["Cancel"] = "cancel"; ModalButtonType["Yes"] = "yes"; ModalButtonType["No"] = "no"; ModalButtonType["Abandon"] = "abandon"; ModalButtonType["GoBack"] = "goBack"; ModalButtonType["Continue"] = "continue"; ModalButtonType["ImSure"] = "imSure"; ModalButtonType["Delete"] = "delete"; ModalButtonType["Confirm"] = "confirm"; })(ModalButtonType || (ModalButtonType = {})); var ModalButtonType$1 = ModalButtonType; /** * Modal sizes * @author Gabe Abrams */ var ModalSize; (function (ModalSize) { ModalSize["Small"] = "sm"; ModalSize["Medium"] = "md"; ModalSize["Large"] = "lg"; ModalSize["ExtraLarge"] = "xl"; })(ModalSize || (ModalSize = {})); var ModalSize$1 = ModalSize; /** * Types of modals * @author Gabe Abrams */ var ModalType; (function (ModalType) { ModalType["Okay"] = "okay"; ModalType["OkayCancel"] = "okay-cancel"; ModalType["YesNo"] = "yes-no"; ModalType["YesNoCancel"] = "yes-no-cancel"; ModalType["AbandonGoBack"] = "abandon-goBack"; ModalType["ImSureCancel"] = "imSure-cancel"; ModalType["DeleteCancel"] = "delete-cancel"; ModalType["ConfirmCancel"] = "confirm-cancel"; ModalType["NoButtons"] = "-"; })(ModalType || (ModalType = {})); var ModalType$1 = ModalType; /* eslint-disable react/no-unused-prop-types */ /*------------------------------------------------------------------------*/ /* ------------------------------ Constants ----------------------------- */ /*------------------------------------------------------------------------*/ // Constants const MS_TO_ANIMATE = 200; // Animation duration // Modal type to list of buttons const modalTypeToModalButtonTypes = { [ModalType$1.Okay]: [ ModalButtonType$1.Okay, ], [ModalType$1.OkayCancel]: [ ModalButtonType$1.Okay, ModalButtonType$1.Cancel, ], [ModalType$1.YesNo]: [ ModalButtonType$1.Yes, ModalButtonType$1.No, ], [ModalType$1.YesNoCancel]: [ ModalButtonType$1.Yes, ModalButtonType$1.No, ModalButtonType$1.Cancel, ], [ModalType$1.AbandonGoBack]: [ ModalButtonType$1.Abandon, ModalButtonType$1.GoBack, ], [ModalType$1.ImSureCancel]: [ ModalButtonType$1.ImSure, ModalButtonType$1.Cancel, ], [ModalType$1.DeleteCancel]: [ ModalButtonType$1.Delete, ModalButtonType$1.Cancel, ], [ModalType$1.ConfirmCancel]: [ ModalButtonType$1.Confirm, ModalButtonType$1.Cancel, ], }; /** * Get button type styling and labels * @author Gabe Abrams * @returns map of button type to label and variant */ const getModalButtonTypeToLabelAndVariant = () => { return { [ModalButtonType$1.Okay]: { label: 'Okay', variant: (Variant$1.Dark), }, [ModalButtonType$1.Cancel]: { label: 'Cancel', variant: Variant$1.Secondary, }, [ModalButtonType$1.Yes]: { label: 'Yes', variant: (Variant$1.Dark), }, [ModalButtonType$1.No]: { label: 'No', variant: Variant$1.Secondary, }, [ModalButtonType$1.Abandon]: { label: 'Abandon Changes', variant: Variant$1.Warning, }, [ModalButtonType$1.GoBack]: { label: 'Go Back', variant: Variant$1.Secondary, }, [ModalButtonType$1.Continue]: { label: 'Continue', variant: (Variant$1.Dark), }, [ModalButtonType$1.ImSure]: { label: 'I am sure', variant: Variant$1.Warning, }, [ModalButtonType$1.Delete]: { label: 'Yes, Delete', variant: Variant$1.Danger, }, [ModalButtonType$1.Confirm]: { label: 'Confirm', variant: (Variant$1.Dark), }, }; }; /*------------------------------------------------------------------------*/ /* -------------------------------- Style ------------------------------- */ /*------------------------------------------------------------------------*/ const style$3 = ` .Modal-backdrop { position: fixed; top: 0; left: 0; width: 100vw; height: 200vh; background-color: rgba(0, 0, 0, 0.7); } .Modal-fading-in { animation-name: Modal-fading-in; animation-duration: ${Math.floor(MS_TO_ANIMATE * 2)}ms; animation-iteration-count: 1; animation-fill-mode: both; animation-timing-function: ease-out; } @keyframes Modal-fading-in { 0% { opacity: 0; } 100% { opacity: 1; } } .Modal-animating-in { animation-name: Modal-animating-in; animation-duration: ${MS_TO_ANIMATE}ms; animation-iteration-count: 1; animation-fill-mode: both; animation-timing-function: ease-out; } @keyframes Modal-animating-in { 0% { transform: scale(1.05) translate(0, -1.5rem); opacity: 0; } 100% { transform: scale(1) translate(0, 0); opacity: 1; } } .Modal-animating-pop { animation-name: Modal-animating-pop; animation-duration: ${MS_TO_ANIMATE}ms; animation-iteration-count: 1; animation-fill-mode: both; animation-timing-function: ease-in-out; } @keyframes Modal-animating-pop { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.05); opacity: 0.9; } 100% { transform: scale(1); opacity: 1; } } .modal-dialog-scrollable { height: 100% !important; } `; /*------------------------------------------------------------------------*/ /* ------------------------------ Component ----------------------------- */ /*------------------------------------------------------------------------*/ const Modal = (props) => { /*------------------------------------------------------------------------*/ /* -------------------------------- Setup ------------------------------- */ /*------------------------------------------------------------------------*/ var _a; /* -------------- Props ------------- */ const { type = ModalType$1.NoButtons, size = ModalSize$1.Large, title, children, onClose, dontAllowBackdropExit, dontShowXButton, onTopOfOtherModals, } = props; /* -------------- State ------------- */ // True if animation is in use const [animatingIn, setAnimatingIn] = React.useState(true); const [animatingPop, setAnimatingPop] = React.useState(false); // Keep track of whether modal is still mounted const mounted = React.useRef(false); /*------------------------------------------------------------------------*/ /* ------------------------- Lifecycle Functions ------------------------ */ /*------------------------------------------------------------------------*/ /** * Mount * @author Gabe Abrams */ React.useEffect(() => { (() => __awaiter$5(void 0, void 0, void 0, function* () { // Set defaults setAnimatingIn(true); setAnimatingPop(false); // Wait for animation yield waitMs(MS_TO_ANIMATE); // Update to state after animated in if (mounted.current) { setAnimatingIn(false); } }))(); return () => { mounted.current = false; }; }, []); /*------------------------------------------------------------------------*/ /* ------------------------- Component Functions ------------------------ */ /*------------------------------------------------------------------------*/ /** * Handles the closing of the modal * @author Gabe Abrams * @param modalButtonType the button that was clicked when closing the * modal */ const handleClose = (modalButtonType) => __awaiter$5(void 0, void 0, void 0, function* () { // Don't close if no handler if (!onClose) { return; } onClose(modalButtonType); }); /*------------------------------------------------------------------------*/ /* ------------------------------- Render ------------------------------- */ /*------------------------------------------------------------------------*/ // Get list of buttons for this modal type const ModalButtonTypes = (_a = modalTypeToModalButtonTypes[type]) !== null && _a !== void 0 ? _a : []; // Get map of button type to label and variant const ModalButtonTypeToLabelAndVariant = getModalButtonTypeToLabelAndVariant(); // Create buttons const buttons = ModalButtonTypes.map((modalButtonType, i) => { // Get default style let { label, variant, } = ModalButtonTypeToLabelAndVariant[modalButtonType]; // Override with customizations const newLabel = props[`${modalButtonType}Label`]; if (newLabel) { label = newLabel; } const newVariant = props[`${modalButtonType}Variant`]; if (newVariant) { variant = newVariant; } // Check if this button is last const last = (i === ModalButtonTypes.length - 1); // Create the button return (React__default["default"].createElement("button", { key: modalButtonType, type: "button", className: `Modal-${modalButtonType}-button btn btn-${variant} ${last ? '' : 'me-1'}`, onClick: () => { handleClose(modalButtonType); } }, label)); }); // Put all buttons in a footer const footer = ((buttons && buttons.length) ? (React__default["default"].createElement("div", null, buttons)) : undefined); // Choose an animation let animationClass = ''; let backdropAnimationClass = ''; if (animatingIn) { animationClass = 'Modal-animating-in'; backdropAnimationClass = 'Modal-fading-in'; } else if (animatingPop) { animationClass = 'Modal-animating-pop'; } // Render the modal return (React__default["default"].createElement("div", { className: "modal show modal-dialog-scrollable modal-dialog-centered", tabIndex: -1, style: { zIndex: (onTopOfOtherModals ? 5000000001 : 5000000000), display: 'block', margin: 'auto', left: 0, right: 0, } }, React__default["default"].createElement("style", null, style$3), React__default["default"].createElement("div", { className: `Modal-backdrop ${backdropAnimationClass}`, style: { zIndex: 5000000003, }, onClick: () => __awaiter$5(void 0, void 0, void 0, function* () { // Skip if exit via backdrop not allowed if (dontAllowBackdropExit || !onClose) { // Show pop animation if (!animatingPop) { setAnimatingPop(true); // Wait then stop pop animation yield waitMs(MS_TO_ANIMATE); setAnimatingPop(false); } return; } // Handle close handleClose(ModalButtonType$1.Cancel); }) }), React__default["default"].createElement("div", { className: `modal-dialog modal-${size} ${animationClass}`, style: { zIndex: 5000000002, } }, React__default["default"].createElement("div", { className: "modal-content", style: { borderColor: (undefined), } }, React__default["default"].createElement("div", { className: "modal-header", style: { color: (undefined), backgroundColor: (undefined), borderBottom: (undefined), } }, React__default["default"].createElement("h5", { className: "modal-title", style: { fontWeight: 'bold', } }, title), (onClose && !dontShowXButton) && (React__default["default"].createElement("button", { type: "button", className: "Modal-x-button btn-close", "aria-label": "Close", style: { backgroundColor: (undefined), }, onClick: () => { // Handle close handleClose(ModalButtonType$1.Cancel); } }))), children && (React__default["default"].createElement("div", { className: "modal-body", style: { color: (undefined), backgroundColor: (undefined), } }, children)), footer && (React__default["default"].createElement("div", { className: "modal-footer pt-1 pb-1", style: { color: (undefined), backgroundColor: (undefined), borderTop: (undefined), } }, footer)))))); }; /** * A radio selection button * @author Gabe Abrams */ /*------------------------------------------------------------------------*/ /* ------------------------------ Component ----------------------------- */ /*------------------------------------------------------------------------*/ const RadioButton = (props) => { /*------------------------------------------------------------------------*/ /* -------------------------------- Setup ------------------------------- */ /*------------------------------------------------------------------------*/ /* -------------- Props ------------- */ const { text, onSelected, ariaLabel, title, selected, id, noMarginOnRight, selectedVariant = (Variant$1.Secondary), unselectedVariant = (Variant$1.Light), small, } = props; /*------------------------------------------------------------------------*/ /* ------------------------------- Render ------------------------------- */ /*------------------------------------------------------------------------*/ /*----------------------------------------*/ /* --------------- Main UI -------------- */ /*----------------------------------------*/ return (React__default["default"].createElement("button", { type: "button", id: id, title: title, className: `btn btn-${selected ? selectedVariant : unselectedVariant}${selected ? ' selected' : ''}${small ? ' btn-sm' : ''} m-0${noMarginOnRight ? '' : ' me-1'}`, "aria-label": `${ariaLabel}${selected ? ': currently selected' : ''}`, onClick: () => { if (!selected) { onSelected(); } } }, React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: selected ? freeSolidSvgIcons.faDotCircle : freeRegularSvgIcons.faCircle, className: "me-1" }), text)); }; /** * An error with a code * @author Gabe Abrams */ class ErrorWithCode$2 extends Error { constructor(message, code) { super(message); this.name = 'ErrorWithCode'; this.code = code; } } // Highest error = DCHUI5 /** * Enumerates the possible errors for the dce-check-in-ui/client. * @author Benedikt Arnarsson */ var ErrorCode$2; (function (ErrorCode) { ErrorCode["InvalidURL"] = "DCHUI1"; ErrorCode["EventNotFound"] = "DCHUI2"; ErrorCode["EventNotHeldInPerson"] = "DCHUI3"; ErrorCode["OccurrenceNotSetUpToday"] = "DCHUI4"; ErrorCode["UnknownCheckInError"] = "DCHUI5"; })(ErrorCode$2 || (ErrorCode$2 = {})); var ErrorCode$3 = ErrorCode$2; /*------------------------------------------------------------------------*/ /* ------------------------------ Constants ----------------------------- */ /*------------------------------------------------------------------------*/ /*----------------------------------------*/ /* ---------- Adjustable Params --------- */ /*----------------------------------------*/ // Width of generated image const WIDTH_PX = 800; // Card styling const BACKGROUND_COLOR = '#A41034'; // Harvard Crimson const WIDTH_TO_HEIGHT_RATIO = 1.2; const CARD_BORDER_RADIUS_RATIO = 0.06; // Text styling const TEXT_COLOR = 'white'; const TEXT = 'Scan to Check In'; const TEXT_SIZE_RATIO = 0.11; const TEXT_TO_TOP_BORDER_RATIO = 0.1; // QR code styling const CARD_TO_QR_CODE_WIDTH_RATIO = 0.85; const QR_BORDER_RADIUS_RATIO = 0.04; /*----------------------------------------*/ /* ---- Dynamically-generated Params ---- */ /*----------------------------------------*/ // Don't customize the look here, these are based on params above // Canvas size const canvasWidth = WIDTH_PX * window.devicePixelRatio; const canvasHeight = canvasWidth * WIDTH_TO_HEIGHT_RATIO; // Card size and location const cardWidth = WIDTH_PX; const cardHeight = WIDTH_TO_HEIGHT_RATIO * WIDTH_PX; const cardRadius = CARD_BORDER_RADIUS_RATIO * WIDTH_PX; // Text size and location const textFontSize = TEXT_SIZE_RATIO * WIDTH_PX; const textX = WIDTH_PX / 2; const textY = TEXT_TO_TOP_BORDER_RATIO * WIDTH_PX; // Sub-text size and location const subTextFontSize = textFontSize / 1.6; const subTextX = textX; const subTextY = 2 * textY; // QR code size and location const qrWidth = WIDTH_PX * CARD_TO_QR_CODE_WIDTH_RATIO; const qrX = WIDTH_PX * (1 - CARD_TO_QR_CODE_WIDTH_RATIO) / 2; const qrY = (WIDTH_PX * WIDTH_TO_HEIGHT_RATIO) - qrX - (WIDTH_PX * CARD_TO_QR_CODE_WIDTH_RATIO) + (TEXT_TO_TOP_BORDER_RATIO * WIDTH_PX / 5.25); const qrRadius = QR_BORDER_RADIUS_RATIO * WIDTH_PX; /*------------------------------------------------------------------------*/ /* ---------------------------- QR Generator ---------------------------- */ /*------------------------------------------------------------------------*/ /** * Create a QR code card, with specified text, QR code value, and background color. * Could be made server-side via the node-canvas package * @author Benedikt Arnarsson * @author Gabe Abrams * @param value the URL which the QR code will hold * @returns the dataURL representing the QR card image */ const getQrCardImg = (value, subText = '') => __awaiter$5(void 0, void 0, void 0, function* () { // Create invisible canvas // Reference: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); context.canvas.hidden = true; // Configure canvas size // See SO: https://stackoverflow.com/a/65124939 canvas.width = canvasWidth; canvas.height = canvasHeight; context.scale(window.devicePixelRatio, window.devicePixelRatio); // Card background context.beginPath(); context.fillStyle = BACKGROUND_COLOR; context.roundRect(0, 0, cardWidth, cardHeight, cardRadius); context.stroke(); context.fill(); // QR background context.beginPath(); context.fillStyle = 'white'; context.strokeStyle = 'white'; context.roundRect(qrX, qrY, qrWidth, qrWidth, qrRadius); context.stroke(); context.fill(); // Text context.font = `bold ${textFontSize}px arial`; context.textAlign = 'center'; context.textBaseline = 'middle'; context.fillStyle = TEXT_COLOR; context.fillText(TEXT, textX, textY); // Sub-text const formattedSubText = (subText.length >= 15 ? `${subText.substring(0, 15)}...` : subText); context.font = `bold ${subTextFontSize}px arial`; context.textAlign = 'center'; context.textBaseline = 'middle'; context.fillStyle = TEXT_COLOR; context.fillText(formattedSubText, subTextX, subTextY); // QR code // > Generate QR code image const qrCodeDataURL = yield QRCode__default["default"].toDataURL(value, { width: qrWidth, margin: 2, color: { light: '#ffffff00', // white, fully transparent }, }); // > Convert to HTML Image const qrImg = new Image(); qrImg.src = qrCodeDataURL; // > Wait for image to process/load yield new Promise((resolve) => { qrImg.onload = resolve; }); // > Draw image to canvas context.drawImage(qrImg, qrX, qrY, qrWidth, qrWidth); // Return data URL and destroy canvas const qrCard = canvas.toDataURL(); canvas.remove(); return qrCard; }); /** * Displays a QR code card, with your choice of URL and specified width. * @author Benedikt Arnarsson * @author Gabe Abrams */ /*------------------------------------------------------------------------*/ /* -------------------------------- State ------------------------------- */ /*------------------------------------------------------------------------*/ /* -------------- Views ------------- */ var View$5; (function (View) { // When the QR code is being generated View["Loading"] = "Loading"; // Display the QR code View["Displaying"] = "Displaying"; })(View$5 || (View$5 = {})); /* ------------- Actions ------------ */ // Types of actions var ActionType$6; (function (ActionType) { // Set QR code data URL (and stop loading, if applicable) ActionType["DisplayQrCode"] = "DisplayQrCode"; // Start loading QR code ActionType["StartLoading"] = "StartLoading"; })(ActionType$6 || (ActionType$6 = {})); /** * Reducer for setting the QR code * @author Benedikt Arnarsson * @param state current state * @param action action to execute * @returns updated state */ const reducer$6 = (state, action) => { switch (action.type) { case ActionType$6.DisplayQrCode: { return { view: View$5.Displaying, qrCode: action.qrCodeDataURL, }; } case ActionType$6.StartLoading: { return { view: Vie