@local-civics/mgmt-ui 0.1.196 → 0.1.197

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.js CHANGED
@@ -62,7 +62,7 @@ var __objRest$2 = (source, exclude) => {
62
62
  }
63
63
  return target;
64
64
  };
65
- const useStyles$w = core.createStyles((theme) => ({
65
+ const useStyles$v = core.createStyles((theme) => ({
66
66
  user: {
67
67
  display: "block",
68
68
  width: "100%",
@@ -73,7 +73,7 @@ const useStyles$w = core.createStyles((theme) => ({
73
73
  }));
74
74
  function UserButton(_a) {
75
75
  var _b = _a, { image, name, email, icon } = _b, others = __objRest$2(_b, ["image", "name", "email", "icon"]);
76
- const { classes } = useStyles$w();
76
+ const { classes } = useStyles$v();
77
77
  return /* @__PURE__ */ React__namespace.createElement(core.Group, __spreadValues$e({ className: classes.user }, others), /* @__PURE__ */ React__namespace.createElement(core.Avatar, { src: image, radius: "xl" }), /* @__PURE__ */ React__namespace.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", weight: 500 }, name), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", size: "xs" }, email)));
78
78
  }
79
79
 
@@ -84,7 +84,7 @@ const compact = (num) => {
84
84
  }).format(num || 0);
85
85
  };
86
86
 
87
- const useStyles$v = core.createStyles((theme, _params, getRef) => {
87
+ const useStyles$u = core.createStyles((theme, _params, getRef) => {
88
88
  const icon = getRef("icon");
89
89
  return {
90
90
  control: {
@@ -137,7 +137,7 @@ const useStyles$v = core.createStyles((theme, _params, getRef) => {
137
137
  };
138
138
  });
139
139
  function LinksGroup({ icon: Icon, href, label, initiallyOpened, links, active, notifications }) {
140
- const { classes, theme, cx } = useStyles$v();
140
+ const { classes, theme, cx } = useStyles$u();
141
141
  const hasLinks = Array.isArray(links) && links.length > 0;
142
142
  const hasActiveLinks = Array.isArray(links) && links.map((l) => !!active && active === `${label}/${l.label}`).reduce((a, b) => a || b, false);
143
143
  const [opened, setOpened] = React.useState(initiallyOpened || hasActiveLinks || false);
@@ -201,7 +201,7 @@ var __spreadValues$d = (a, b) => {
201
201
  return a;
202
202
  };
203
203
  var __spreadProps$9 = (a, b) => __defProps$9(a, __getOwnPropDescs$9(b));
204
- const useStyles$u = core.createStyles((theme, _params, getRef) => {
204
+ const useStyles$t = core.createStyles((theme, _params, getRef) => {
205
205
  const icon = getRef("icon");
206
206
  return {
207
207
  navbar: {
@@ -302,7 +302,7 @@ const TRIAL_PAGES = [
302
302
  "Badges"
303
303
  ];
304
304
  function Navbar(props) {
305
- const { classes, cx } = useStyles$u();
305
+ const { classes, cx } = useStyles$t();
306
306
  const [burgerOpen, setBurgerOpen] = React__namespace.useState(false);
307
307
  const toggle = () => setBurgerOpen(!burgerOpen);
308
308
  const links = data.map((item) => {
@@ -345,7 +345,7 @@ function Navbar(props) {
345
345
  } }, /* @__PURE__ */ React__namespace.createElement(icons.IconLogout, { className: classes.linkIcon, stroke: 1.5 }), /* @__PURE__ */ React__namespace.createElement("span", null, "Logout"))))));
346
346
  }
347
347
 
348
- const useStyles$t = core.createStyles((theme) => ({
348
+ const useStyles$s = core.createStyles((theme) => ({
349
349
  inner: {
350
350
  paddingTop: theme.spacing.xl,
351
351
  paddingBottom: theme.spacing.xl * 4
@@ -381,7 +381,7 @@ const useStyles$t = core.createStyles((theme) => ({
381
381
  }
382
382
  }));
383
383
  const GettingStarted = (props) => {
384
- const { classes } = useStyles$t();
384
+ const { classes } = useStyles$s();
385
385
  return /* @__PURE__ */ React__namespace.createElement(
386
386
  core.Modal,
387
387
  {
@@ -395,7 +395,7 @@ const GettingStarted = (props) => {
395
395
  );
396
396
  };
397
397
 
398
- const useStyles$s = core.createStyles((theme) => ({
398
+ const useStyles$r = core.createStyles((theme) => ({
399
399
  title: {
400
400
  fontSize: 34,
401
401
  fontWeight: 900,
@@ -436,7 +436,7 @@ const useStyles$s = core.createStyles((theme) => ({
436
436
  }
437
437
  }));
438
438
  const SwitchAccount = (props) => {
439
- const { classes, theme } = useStyles$s();
439
+ const { classes, theme } = useStyles$r();
440
440
  const options = props.accounts.map((a) => {
441
441
  return /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick && props.onClick(a.accountId), key: a.accountId, p: theme.spacing.md }, /* @__PURE__ */ React__namespace.createElement(core.Card, { withBorder: true, shadow: "md", radius: "md", className: classes.card, p: "xl" }, a.isAdmin && /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(icons.IconBatteryEco, { size: 50, stroke: 2, color: theme.fn.primaryColor() })), a.isGroupAdmin && !a.isAdmin && /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(icons.IconBooks, { size: 50, stroke: 2, color: theme.fn.primaryColor() })), !a.isAdmin && !a.isGroupAdmin && /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(icons.IconBackpack, { size: 50, stroke: 2, color: theme.fn.primaryColor() })), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "lg", weight: 500, className: classes.cardTitle, mt: "md" }, a.name), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", color: "dimmed", mt: "sm" }, a.isAdmin ? "Admin" : a.isGroupAdmin ? "Educator" : "Student")));
442
442
  });
@@ -453,7 +453,7 @@ const SwitchAccount = (props) => {
453
453
  );
454
454
  };
455
455
 
456
- const useStyles$r = core.createStyles((theme) => ({
456
+ const useStyles$q = core.createStyles((theme) => ({
457
457
  root: {
458
458
  display: "flex",
459
459
  backgroundImage: `linear-gradient(-60deg, ${theme.colors[theme.primaryColor][4]} 0%, ${theme.colors[theme.primaryColor][7]} 100%)`,
@@ -497,7 +497,7 @@ const useStyles$r = core.createStyles((theme) => ({
497
497
  }
498
498
  }));
499
499
  const StatsGroup = ({ data, footer }) => {
500
- const { classes } = useStyles$r();
500
+ const { classes } = useStyles$q();
501
501
  const stats = data.map((stat) => {
502
502
  const value = (() => {
503
503
  if (stat.unit === "%") {
@@ -517,7 +517,7 @@ const Tabs = (props) => {
517
517
  return /* @__PURE__ */ React__namespace.createElement(core.Tabs, { value: props.value, onTabChange: props.onChange }, /* @__PURE__ */ React__namespace.createElement(core.Tabs.List, null, tabs));
518
518
  };
519
519
 
520
- const useStyles$q = core.createStyles((theme) => ({
520
+ const useStyles$p = core.createStyles((theme) => ({
521
521
  button: {
522
522
  borderTopRightRadius: 0,
523
523
  borderBottomRightRadius: 0,
@@ -532,7 +532,7 @@ const useStyles$q = core.createStyles((theme) => ({
532
532
  }
533
533
  }));
534
534
  const SplitButton$5 = (props) => {
535
- const { classes, theme } = useStyles$q();
535
+ const { classes, theme } = useStyles$p();
536
536
  theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
537
537
  return /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(
538
538
  core.Button,
@@ -560,7 +560,7 @@ const SplitButton$5 = (props) => {
560
560
  ));
561
561
  };
562
562
 
563
- const useStyles$p = core.createStyles((theme) => ({
563
+ const useStyles$o = core.createStyles((theme) => ({
564
564
  wrapper: {
565
565
  display: "flex",
566
566
  alignItems: "center",
@@ -611,7 +611,7 @@ const useStyles$p = core.createStyles((theme) => ({
611
611
  }
612
612
  }));
613
613
  const PlaceholderBanner = (props) => {
614
- const { classes } = useStyles$p();
614
+ const { classes } = useStyles$o();
615
615
  const title = props.title || "Nothing to display";
616
616
  const description = props.description || "We don't have anything to show you here just yet. Add data, check back later, or adjust your search.";
617
617
  return /* @__PURE__ */ React__namespace.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React__namespace.createElement("div", { className: classes.body }, /* @__PURE__ */ React__namespace.createElement(core.Title, { className: classes.title }, props.loading ? "Loading..." : title), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", color: "dimmed" }, props.loading ? "Hold on, we're loading your data." : description)), /* @__PURE__ */ React__namespace.createElement(core.Image, { src: `https://cdn.localcivics.io/illustrations/${props.icon}.svg`, className: classes.image }));
@@ -781,7 +781,7 @@ function Table$j(props) {
781
781
  ));
782
782
  }
783
783
 
784
- const useStyles$o = core.createStyles((theme) => ({
784
+ const useStyles$n = core.createStyles((theme) => ({
785
785
  title: {
786
786
  fontSize: 34,
787
787
  fontWeight: 900,
@@ -794,7 +794,7 @@ const useStyles$o = core.createStyles((theme) => ({
794
794
  }
795
795
  }));
796
796
  const Badge = (props) => {
797
- const { classes } = useStyles$o();
797
+ const { classes } = useStyles$n();
798
798
  const [tab, setTab] = React.useState("lessons");
799
799
  const numberOfStudents = props.students.length;
800
800
  const numberOfBadges = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length : 0;
@@ -892,7 +892,7 @@ function Table$i(props) {
892
892
  return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { horizontalSpacing: 0, verticalSpacing: 0, sx: { minWidth: 700 } }, /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
893
893
  }
894
894
 
895
- const useStyles$n = core.createStyles((theme) => ({
895
+ const useStyles$m = core.createStyles((theme) => ({
896
896
  title: {
897
897
  fontSize: 34,
898
898
  fontWeight: 900,
@@ -905,7 +905,7 @@ const useStyles$n = core.createStyles((theme) => ({
905
905
  }
906
906
  }));
907
907
  const Badges = (props) => {
908
- const { classes } = useStyles$n();
908
+ const { classes } = useStyles$m();
909
909
  return /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid, null, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "auto" }, /* @__PURE__ */ React__namespace.createElement(core.Badge, { variant: "filled", size: "lg" }, "Badges"), /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, "Badges and micro-credentials"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Key milestones that reflect skill development, micro-credentials, or academic progress"))), /* @__PURE__ */ React__namespace.createElement(
910
910
  core.Autocomplete,
911
911
  {
@@ -1272,7 +1272,7 @@ var __spreadValues$a = (a, b) => {
1272
1272
  return a;
1273
1273
  };
1274
1274
  var __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b));
1275
- const useStyles$m = core.createStyles((theme) => ({
1275
+ const useStyles$l = core.createStyles((theme) => ({
1276
1276
  title: {
1277
1277
  fontSize: 34,
1278
1278
  fontWeight: 900,
@@ -1305,7 +1305,7 @@ const useStyles$m = core.createStyles((theme) => ({
1305
1305
  }
1306
1306
  }));
1307
1307
  const Class = (props) => {
1308
- const { classes } = useStyles$m();
1308
+ const { classes } = useStyles$l();
1309
1309
  const form$1 = form.useForm({
1310
1310
  initialValues: {
1311
1311
  classId: "",
@@ -1406,7 +1406,7 @@ const Class = (props) => {
1406
1406
  ))))));
1407
1407
  };
1408
1408
  const DropzoneButton$1 = (props) => {
1409
- const { classes, theme } = useStyles$m();
1409
+ const { classes, theme } = useStyles$l();
1410
1410
  const openRef = React__namespace.useRef(null);
1411
1411
  const [loading, setLoading] = React__namespace.useState(false);
1412
1412
  const onDrop = React__namespace.useCallback((acceptedFiles) => {
@@ -1452,21 +1452,6 @@ const DropzoneButton$1 = (props) => {
1452
1452
  } }, "Select file"));
1453
1453
  };
1454
1454
 
1455
- const useStyles$l = core.createStyles((theme) => ({
1456
- th: { padding: "0 !important" },
1457
- control: {
1458
- width: "100%",
1459
- padding: `${theme.spacing.xs}px ${theme.spacing.md}px`,
1460
- "&:hover": {
1461
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[0]
1462
- }
1463
- }
1464
- }));
1465
- function Th({ children, reversed, sorted, onSort }) {
1466
- const { classes } = useStyles$l();
1467
- const Icon = sorted ? reversed ? icons.IconChevronUp : icons.IconChevronDown : icons.IconSelector;
1468
- return /* @__PURE__ */ React__namespace.createElement("th", { className: classes.th }, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: onSort, className: classes.control }, /* @__PURE__ */ React__namespace.createElement(core.Group, { position: "apart", noWrap: true, spacing: "xs" }, /* @__PURE__ */ React__namespace.createElement(core.Text, { weight: 500, size: "sm", sx: { whiteSpace: "nowrap" } }, children), /* @__PURE__ */ React__namespace.createElement(core.Center, null, /* @__PURE__ */ React__namespace.createElement(Icon, { size: 14, stroke: 1.5 })))));
1469
- }
1470
1455
  function Table$b(props) {
1471
1456
  const { items: sortedItems, requestSort, sortConfig } = useSortableData(props.items);
1472
1457
  if (props.items.length === 0) {
@@ -1488,24 +1473,49 @@ function Table$b(props) {
1488
1473
  confirmProps: { color: "red" },
1489
1474
  onConfirm: () => props.onDeleteClass(group)
1490
1475
  });
1491
- const rows = sortedItems.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.classId }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { component: reactRouterDom.Link, to: row.href }, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: 14 }, row.name))), /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: 14 }, row.description)), /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: 14 }, row.numberOfStudents || 0)), /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0, position: "right" }, /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { color: "red" }, /* @__PURE__ */ React__namespace.createElement(icons.IconTrash, { onClick: () => openDeleteModal(row), size: 16, stroke: 1.5 }))))));
1492
- return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: 20, sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement(
1493
- Th,
1494
- {
1495
- sorted: sortConfig.key === "name",
1496
- reversed: sortConfig.direction === "desc",
1497
- onSort: () => requestSort("name")
1498
- },
1499
- "Class Name"
1500
- ), /* @__PURE__ */ React__namespace.createElement("th", { style: { padding: "7px 16px" } }, /* @__PURE__ */ React__namespace.createElement(core.Text, { weight: 500, size: "sm" }, "Description")), /* @__PURE__ */ React__namespace.createElement(
1501
- Th,
1476
+ const sortStatus = {
1477
+ columnAccessor: sortConfig.key,
1478
+ direction: sortConfig.direction === "desc" ? "desc" : "asc"
1479
+ };
1480
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React__namespace.createElement(
1481
+ mantineDatatable.DataTable,
1502
1482
  {
1503
- sorted: sortConfig.key === "numberOfStudents",
1504
- reversed: sortConfig.direction === "desc",
1505
- onSort: () => requestSort("numberOfStudents")
1506
- },
1507
- "# of Students"
1508
- ), /* @__PURE__ */ React__namespace.createElement("th", null))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
1483
+ withBorder: false,
1484
+ borderRadius: "sm",
1485
+ verticalSpacing: "sm",
1486
+ sx: { minWidth: 700 },
1487
+ highlightOnHover: true,
1488
+ striped: true,
1489
+ records: sortedItems,
1490
+ idAccessor: "classId",
1491
+ sortStatus,
1492
+ onSortStatusChange: (status) => requestSort(status.columnAccessor),
1493
+ columns: [
1494
+ {
1495
+ accessor: "name",
1496
+ title: "Class Name",
1497
+ sortable: true,
1498
+ render: (row) => /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { component: reactRouterDom.Link, to: row.href }, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: 14, weight: 500 }, row.name))
1499
+ },
1500
+ {
1501
+ accessor: "description",
1502
+ title: "Description",
1503
+ render: (row) => /* @__PURE__ */ React__namespace.createElement(core.Text, { size: 14 }, row.description)
1504
+ },
1505
+ {
1506
+ accessor: "numberOfStudents",
1507
+ title: "# of Students",
1508
+ sortable: true,
1509
+ render: (row) => /* @__PURE__ */ React__namespace.createElement(core.Text, { size: 14 }, row.numberOfStudents || 0)
1510
+ },
1511
+ {
1512
+ accessor: "actions",
1513
+ title: "",
1514
+ render: (row) => /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0, position: "right" }, /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { color: "red", onClick: () => openDeleteModal(row) }, /* @__PURE__ */ React__namespace.createElement(icons.IconTrash, { size: 16, stroke: 1.5 })))
1515
+ }
1516
+ ]
1517
+ }
1518
+ ));
1509
1519
  }
1510
1520
 
1511
1521
  var __defProp$9 = Object.defineProperty;
@@ -2094,6 +2104,11 @@ function Table$6(props) {
2094
2104
  status: item.isComplete ? 2 : item.isStarted ? 1 : 0
2095
2105
  }));
2096
2106
  }, [props.items]);
2107
+ const { items: sortedItems, requestSort, sortConfig } = useSortableData(preparedItems);
2108
+ const sortStatus = {
2109
+ columnAccessor: sortConfig.key,
2110
+ direction: sortConfig.direction === "desc" ? "desc" : "asc"
2111
+ };
2097
2112
  if (props.items.length === 0) {
2098
2113
  return /* @__PURE__ */ React__namespace.createElement(
2099
2114
  PlaceholderBanner,
@@ -2105,11 +2120,6 @@ function Table$6(props) {
2105
2120
  }
2106
2121
  );
2107
2122
  }
2108
- const { items: sortedItems, requestSort, sortConfig } = useSortableData(preparedItems);
2109
- const sortStatus = {
2110
- columnAccessor: sortConfig.key,
2111
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
2112
- };
2113
2123
  return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React__namespace.createElement(
2114
2124
  mantineDatatable.DataTable,
2115
2125
  {