@local-civics/mgmt-ui 0.1.257 → 0.1.258

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { useState, useMemo } from 'react';
3
- import { IconChevronRight, IconVideo, IconSwitchHorizontal, IconLogout, IconHome2, IconCategory2, IconRoute, IconAlbum, IconLambda, IconClipboard, IconMessageCircle, IconClipboardCheck, IconBuilding, IconBooks, IconBackpack, IconSearch, IconArrowLeft, IconClipboardCopy, IconTableExport, IconCaretDown, IconCaretUp, IconChevronDown, IconCheck, IconTrash, IconPlus, IconLink, IconDownload, IconCloudUpload, IconInfoCircle, IconPlaylistAdd, IconPointer, IconX, IconScribble, IconSchool, IconPodium, IconBriefcase, IconPresentation, IconNews, IconTools, IconBrandInstagram, IconBrandLinkedin, IconBrandFacebook, IconChevronLeft, IconRefresh } from '@tabler/icons';
3
+ import { IconChevronRight, IconVideo, IconSwitchHorizontal, IconLogout, IconHome2, IconCategory2, IconRoute, IconAlbum, IconLambda, IconClipboard, IconMessageCircle, IconClipboardCheck, IconBuilding, IconBooks, IconBackpack, IconSearch, IconArrowLeft, IconClipboardCopy, IconTableExport, IconCaretDown, IconCaretUp, IconChevronDown, IconCheck, IconTrash, IconPlus, IconLink, IconDownload, IconCloudUpload, IconInfoCircle, IconPlaylistAdd, IconExternalLink, IconPointer, IconX, IconScribble, IconSchool, IconPodium, IconBriefcase, IconPresentation, IconNews, IconTools, IconBrandInstagram, IconBrandLinkedin, IconBrandFacebook, IconChevronLeft, IconRefresh } from '@tabler/icons';
4
4
  import { Avatar, createStyles, Modal, Center, Loader, Container, Group, Button, Title, Text, Image, Drawer, Divider, TextInput, Tooltip, ActionIcon, SimpleGrid, Badge as Badge$1, Card, UnstyledButton, Overlay, Stack as Stack$5, ThemeIcon, Checkbox, Autocomplete, createEmotionCache, MantineProvider, AppShell } from '@mantine/core';
5
5
  import { Link } from 'react-router-dom';
6
6
  import 'external-svg-loader';
@@ -1204,6 +1204,41 @@ function Table$8(props) {
1204
1204
  ))));
1205
1205
  }
1206
1206
 
1207
+ const isUrl = (value) => /^https?:\/\/\S+$/i.test(value.trim());
1208
+ const isUpload = (value) => /\/\/cdn\.localcivics\.io\/v1\/store\//i.test(value);
1209
+ const hostOf = (value) => {
1210
+ try {
1211
+ return new URL(value).hostname.replace(/^www\./, "");
1212
+ } catch (e) {
1213
+ return value;
1214
+ }
1215
+ };
1216
+ function AnswerValue(props) {
1217
+ const values = (props.answer || []).filter((v) => typeof v === "string" && v.trim() !== "");
1218
+ const text = values.filter((v) => !isUrl(v));
1219
+ const links = values.filter(isUrl);
1220
+ if (values.length === 0) {
1221
+ return props.emptyText ? /* @__PURE__ */ React.createElement("div", { className: props.className }, props.emptyText) : null;
1222
+ }
1223
+ return /* @__PURE__ */ React.createElement("div", { className: `flex flex-col gap-2 ${props.className || ""}` }, text.length > 0 && /* @__PURE__ */ React.createElement("div", null, text.join(", ")), links.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, links.map((link) => {
1224
+ const upload = isUpload(link);
1225
+ return /* @__PURE__ */ React.createElement(
1226
+ "a",
1227
+ {
1228
+ key: link,
1229
+ href: link,
1230
+ download: upload || void 0,
1231
+ target: "_blank",
1232
+ rel: "noopener noreferrer",
1233
+ title: link,
1234
+ className: "flex w-fit items-center gap-1 rounded-md border border-slate-200 px-2.5 py-1.5 text-[11px] font-bold text-slate-600 no-underline hover:bg-slate-50"
1235
+ },
1236
+ upload ? /* @__PURE__ */ React.createElement(IconDownload, { size: 12, stroke: 2 }) : /* @__PURE__ */ React.createElement(IconExternalLink, { size: 12, stroke: 2 }),
1237
+ upload ? "Download" : `Open link (${hostOf(link)})`
1238
+ );
1239
+ })));
1240
+ }
1241
+
1207
1242
  function Table$7(props) {
1208
1243
  const { items: sortedItems, requestSort, sortConfig } = useSortableData(props.items);
1209
1244
  if (props.items.length === 0) {
@@ -1226,7 +1261,7 @@ function Table$7(props) {
1226
1261
  className: `px-5 py-4 ${i < row.questions.length - 1 || row.reflection ? "border-b border-slate-100" : ""}`
1227
1262
  },
1228
1263
  /* @__PURE__ */ React.createElement("div", { className: "text-xs font-semibold text-slate-500" }, q.questionName),
1229
- /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-600" }, q.answer.join(", "))
1264
+ /* @__PURE__ */ React.createElement(AnswerValue, { answer: q.answer, className: "mt-1 text-xs text-slate-600" })
1230
1265
  )), row.reflection && /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-4 px-5 py-4" }, /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs font-semibold text-slate-500" }, "Reflection"), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-600" }, row.reflection)), !!row.rating && /* @__PURE__ */ React.createElement("div", { className: "shrink-0 rounded-full bg-gold-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, row.rating.toLocaleString()))));
1231
1266
  })));
1232
1267
  }
@@ -1475,7 +1510,7 @@ const SplitButton$3 = (props) => {
1475
1510
  function Stack$3(props) {
1476
1511
  const hasAnswers = props.items.length > 0;
1477
1512
  const hasReflection = !!props.reflection;
1478
- return /* @__PURE__ */ React.createElement(Link, { to: props.href, state: props.state, className: "flex flex-col gap-4 no-underline" }, hasAnswers ? props.items.map((row) => /* @__PURE__ */ React.createElement("div", { key: row.questionName }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, row.questionName), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-600" }, row.answer.join(", ") || "No answer."))) : !hasReflection ? /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, "No question responses recorded yet.") : null, hasReflection && /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, "Reflection"), !!props.rating && /* @__PURE__ */ React.createElement("div", { className: "shrink-0 rounded-full bg-gold-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, props.rating)), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-600" }, props.reflection)), /* @__PURE__ */ React.createElement("div", { className: "text-xs font-bold text-dark-blue-400 hover:underline" }, "View full response \u2192"));
1513
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4" }, hasAnswers ? props.items.map((row) => /* @__PURE__ */ React.createElement("div", { key: row.questionName }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, row.questionName), /* @__PURE__ */ React.createElement(AnswerValue, { answer: row.answer, emptyText: "No answer.", className: "mt-1 text-sm text-slate-600" }))) : !hasReflection ? /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, "No question responses recorded yet.") : null, hasReflection && /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, "Reflection"), !!props.rating && /* @__PURE__ */ React.createElement("div", { className: "shrink-0 rounded-full bg-gold-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, props.rating)), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-600" }, props.reflection)), /* @__PURE__ */ React.createElement(Link, { to: props.href, state: props.state, className: "w-fit text-xs font-bold text-dark-blue-400 no-underline hover:underline" }, "View full response \u2192"));
1479
1514
  }
1480
1515
 
1481
1516
  var __defProp$d = Object.defineProperty;