@local-civics/mgmt-ui 0.1.71 → 0.1.72

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.d.ts CHANGED
@@ -227,8 +227,8 @@ type DashboardProps = {
227
227
  lessons: Item$b[];
228
228
  classId: string;
229
229
  percentageOfAccountsCreated: number;
230
- percentageOfBadgesEarned: number;
231
- percentageOfLessonsCompleted: number;
230
+ numberOfBadgesEarned: number;
231
+ numberOfLessonsCompleted: number;
232
232
  onClassChange: (classId: string) => void;
233
233
  onViewStudentProfile: (student: Item$f) => void;
234
234
  onBadgeClick: (badge: Item$c) => void;
@@ -275,7 +275,6 @@ type ClassProps = {
275
275
  percentageOfAccountsCreated: number;
276
276
  numberOfBadgesEarned: number;
277
277
  numberOfLessonsCompleted: number;
278
- withClassLink?: boolean;
279
278
  onBackClick: () => void;
280
279
  onCreateMembers: (members: MemberItem[]) => void;
281
280
  onDeleteMember: (student: MemberItem) => void;
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ function _interopNamespaceDefault(e) {
32
32
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
33
33
  var papa__namespace = /*#__PURE__*/_interopNamespaceDefault(papa);
34
34
 
35
- const useStyles$n = core.createStyles((theme) => ({
35
+ const useStyles$m = core.createStyles((theme) => ({
36
36
  link: {
37
37
  width: 50,
38
38
  height: 50,
@@ -60,7 +60,7 @@ const data$1 = [
60
60
  { icon: icons.IconLambda, label: "Lessons", href: "/lessons" }
61
61
  ];
62
62
  const NavbarLink = ({ icon: Icon, label, active, onClick }) => {
63
- const { classes, cx } = useStyles$n();
63
+ const { classes, cx } = useStyles$m();
64
64
  return /* @__PURE__ */ React__namespace.createElement(core.Tooltip, { label, position: "right", transitionDuration: 0 }, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick, className: cx(classes.link, { [classes.active]: active }) }, /* @__PURE__ */ React__namespace.createElement(Icon, { stroke: 1.5 })));
65
65
  };
66
66
  const Navbar = (props) => {
@@ -119,7 +119,7 @@ var __objRest$1 = (source, exclude) => {
119
119
  }
120
120
  return target;
121
121
  };
122
- const useStyles$m = core.createStyles((theme) => ({
122
+ const useStyles$l = core.createStyles((theme) => ({
123
123
  user: {
124
124
  display: "block",
125
125
  width: "100%",
@@ -130,7 +130,7 @@ const useStyles$m = core.createStyles((theme) => ({
130
130
  }));
131
131
  function UserButton(_a) {
132
132
  var _b = _a, { image, name, email, icon } = _b, others = __objRest$1(_b, ["image", "name", "email", "icon"]);
133
- const { classes } = useStyles$m();
133
+ const { classes } = useStyles$l();
134
134
  return /* @__PURE__ */ React__namespace.createElement(core.Group, __spreadValues$6({ 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)));
135
135
  }
136
136
 
@@ -141,7 +141,7 @@ const compact = (num) => {
141
141
  }).format(num || 0);
142
142
  };
143
143
 
144
- const useStyles$l = core.createStyles((theme, _params, getRef) => {
144
+ const useStyles$k = core.createStyles((theme, _params, getRef) => {
145
145
  const icon = getRef("icon");
146
146
  return {
147
147
  control: {
@@ -194,7 +194,7 @@ const useStyles$l = core.createStyles((theme, _params, getRef) => {
194
194
  };
195
195
  });
196
196
  function LinksGroup({ icon: Icon, href, label, initiallyOpened, links, active, notifications }) {
197
- const { classes, theme, cx } = useStyles$l();
197
+ const { classes, theme, cx } = useStyles$k();
198
198
  const hasLinks = Array.isArray(links) && links.length > 0;
199
199
  const hasActiveLinks = Array.isArray(links) && links.map((l) => !!active && active === `${label}/${l.label}`).reduce((a, b) => a || b, false);
200
200
  const [opened, setOpened] = React.useState(initiallyOpened || hasActiveLinks || false);
@@ -258,7 +258,7 @@ var __spreadValues$5 = (a, b) => {
258
258
  return a;
259
259
  };
260
260
  var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
261
- const useStyles$k = core.createStyles((theme, _params, getRef) => {
261
+ const useStyles$j = core.createStyles((theme, _params, getRef) => {
262
262
  const icon = getRef("icon");
263
263
  return {
264
264
  navbar: {
@@ -352,7 +352,7 @@ const data = [
352
352
  }
353
353
  ];
354
354
  function NestedNavbar(props) {
355
- const { classes, cx } = useStyles$k();
355
+ const { classes, cx } = useStyles$j();
356
356
  const [burgerOpen, setBurgerOpen] = React__namespace.useState(false);
357
357
  const toggle = () => setBurgerOpen(!burgerOpen);
358
358
  const links = data.map((item) => {
@@ -389,7 +389,7 @@ function NestedNavbar(props) {
389
389
  } }, /* @__PURE__ */ React__namespace.createElement(icons.IconLogout, { className: classes.linkIcon, stroke: 1.5 }), /* @__PURE__ */ React__namespace.createElement("span", null, "Logout"))))));
390
390
  }
391
391
 
392
- const useStyles$j = core.createStyles((theme) => ({
392
+ const useStyles$i = core.createStyles((theme) => ({
393
393
  title: {
394
394
  fontSize: 34,
395
395
  fontWeight: 900,
@@ -430,7 +430,7 @@ const useStyles$j = core.createStyles((theme) => ({
430
430
  }
431
431
  }));
432
432
  const SwitchAccount = (props) => {
433
- const { classes, theme } = useStyles$j();
433
+ const { classes, theme } = useStyles$i();
434
434
  const options = props.accounts.map((a) => {
435
435
  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")));
436
436
  });
@@ -447,7 +447,7 @@ const SwitchAccount = (props) => {
447
447
  );
448
448
  };
449
449
 
450
- const useStyles$i = core.createStyles((theme) => ({
450
+ const useStyles$h = core.createStyles((theme) => ({
451
451
  root: {
452
452
  display: "flex",
453
453
  backgroundImage: `linear-gradient(-60deg, ${theme.colors[theme.primaryColor][4]} 0%, ${theme.colors[theme.primaryColor][7]} 100%)`,
@@ -494,7 +494,7 @@ const useStyles$i = core.createStyles((theme) => ({
494
494
  }
495
495
  }));
496
496
  const StatsGroup = ({ data }) => {
497
- const { classes } = useStyles$i();
497
+ const { classes } = useStyles$h();
498
498
  const stats = data.map((stat) => {
499
499
  const value = (() => {
500
500
  if (stat.unit === "%") {
@@ -513,7 +513,7 @@ const Tabs = (props) => {
513
513
  return /* @__PURE__ */ React__namespace.createElement(core.Tabs, { value: props.value, onTabChange: props.onChange }, /* @__PURE__ */ React__namespace.createElement(core.Tabs.List, null, tabs));
514
514
  };
515
515
 
516
- const useStyles$h = core.createStyles((theme) => ({
516
+ const useStyles$g = core.createStyles((theme) => ({
517
517
  button: {
518
518
  borderTopRightRadius: 0,
519
519
  borderBottomRightRadius: 0,
@@ -528,7 +528,7 @@ const useStyles$h = core.createStyles((theme) => ({
528
528
  }
529
529
  }));
530
530
  const SplitButton$3 = (props) => {
531
- const { classes, theme } = useStyles$h();
531
+ const { classes, theme } = useStyles$g();
532
532
  const menuIconColor = theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
533
533
  return /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
534
534
  core.Button,
@@ -565,7 +565,7 @@ const SplitButton$3 = (props) => {
565
565
  ))));
566
566
  };
567
567
 
568
- const useStyles$g = core.createStyles((theme) => ({
568
+ const useStyles$f = core.createStyles((theme) => ({
569
569
  wrapper: {
570
570
  display: "flex",
571
571
  alignItems: "center",
@@ -616,7 +616,7 @@ const useStyles$g = core.createStyles((theme) => ({
616
616
  }
617
617
  }));
618
618
  const PlaceholderBanner = (props) => {
619
- const { classes } = useStyles$g();
619
+ const { classes } = useStyles$f();
620
620
  const title = props.title || "Nothing to display";
621
621
  const description = props.description || "We don't have anything to show you here just yet. Add data, check back later, or adjust your search.";
622
622
  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 }));
@@ -688,7 +688,7 @@ function Table$f(props) {
688
688
  return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Lesson Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Lesson Completion"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
689
689
  }
690
690
 
691
- const useStyles$f = core.createStyles((theme) => ({
691
+ const useStyles$e = core.createStyles((theme) => ({
692
692
  title: {
693
693
  fontSize: 34,
694
694
  fontWeight: 900,
@@ -701,7 +701,7 @@ const useStyles$f = core.createStyles((theme) => ({
701
701
  }
702
702
  }));
703
703
  const Badge = (props) => {
704
- const { classes } = useStyles$f();
704
+ const { classes } = useStyles$e();
705
705
  const [tab, setTab] = React.useState("lessons");
706
706
  const numberOfStudents = props.students.length;
707
707
  const percentageOfBadgesEarned = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length / numberOfStudents : 0;
@@ -798,7 +798,7 @@ function Table$e(props) {
798
798
  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)));
799
799
  }
800
800
 
801
- const useStyles$e = core.createStyles((theme) => ({
801
+ const useStyles$d = core.createStyles((theme) => ({
802
802
  title: {
803
803
  fontSize: 34,
804
804
  fontWeight: 900,
@@ -811,7 +811,7 @@ const useStyles$e = core.createStyles((theme) => ({
811
811
  }
812
812
  }));
813
813
  const Badges = (props) => {
814
- const { classes } = useStyles$e();
814
+ const { classes } = useStyles$d();
815
815
  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" }, "Project-sized skills acquisition and standards alignment."))), /* @__PURE__ */ React__namespace.createElement(
816
816
  core.Autocomplete,
817
817
  {
@@ -945,14 +945,12 @@ const Dashboard = (props) => {
945
945
  unit: "%"
946
946
  },
947
947
  {
948
- title: "BADGE COMPLETION",
949
- value: props.percentageOfBadgesEarned,
950
- unit: "%"
948
+ title: "BADGES EARNED",
949
+ value: props.numberOfBadgesEarned
951
950
  },
952
951
  {
953
- title: "LESSON COMPLETION",
954
- value: props.percentageOfLessonsCompleted,
955
- unit: "%"
952
+ title: "LESSONS COMPLETED",
953
+ value: props.numberOfLessonsCompleted
956
954
  }
957
955
  ] }), /* @__PURE__ */ React__namespace.createElement(
958
956
  core.Select,
@@ -1018,49 +1016,22 @@ const Dashboard = (props) => {
1018
1016
  )))))));
1019
1017
  };
1020
1018
 
1021
- const useStyles$d = core.createStyles((theme) => ({
1022
- button: {
1023
- borderTopRightRadius: 0,
1024
- borderBottomRightRadius: 0,
1025
- marginLeft: 0,
1026
- marginRight: 0
1027
- },
1028
- menuControl: {
1029
- borderTopLeftRadius: 0,
1030
- borderBottomLeftRadius: 0,
1031
- border: 0,
1032
- borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
1033
- }
1034
- }));
1035
1019
  const SplitButton$2 = (props) => {
1036
- const { classes, theme } = useStyles$d();
1037
- const menuIconColor = theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
1038
- const hasMenu = !!props.withClassLink;
1039
- return /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
1020
+ return /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(
1040
1021
  core.Button,
1041
1022
  {
1042
- className: hasMenu ? classes.button : "",
1043
1023
  leftIcon: /* @__PURE__ */ React__namespace.createElement(icons.IconPlaylistAdd, { size: 14 }),
1044
1024
  onClick: props.onAddMembersClick
1045
1025
  },
1046
1026
  "Add students"
1047
- ), hasMenu && /* @__PURE__ */ React__namespace.createElement(core.Menu, { transition: "pop", position: "bottom-end" }, /* @__PURE__ */ React__namespace.createElement(core.Menu.Target, null, /* @__PURE__ */ React__namespace.createElement(
1048
- core.ActionIcon,
1049
- {
1050
- variant: "filled",
1051
- color: theme.primaryColor,
1052
- size: 36,
1053
- className: classes.menuControl
1054
- },
1055
- /* @__PURE__ */ React__namespace.createElement(icons.IconChevronDown, { size: 16, stroke: 1.5 })
1056
- )), /* @__PURE__ */ React__namespace.createElement(core.Menu.Dropdown, null, !!props.withClassLink && /* @__PURE__ */ React__namespace.createElement(
1057
- core.Menu.Item,
1027
+ ), /* @__PURE__ */ React__namespace.createElement(
1028
+ core.Button,
1058
1029
  {
1059
- icon: /* @__PURE__ */ React__namespace.createElement(icons.IconClipboardCopy, { size: 16, stroke: 1.5, color: menuIconColor }),
1030
+ leftIcon: /* @__PURE__ */ React__namespace.createElement(icons.IconClipboardCopy, { size: 14 }),
1060
1031
  onClick: props.onCopyClassLinkClick
1061
1032
  },
1062
1033
  "Copy class link"
1063
- ))));
1034
+ ));
1064
1035
  };
1065
1036
 
1066
1037
  function Table$8(props) {
@@ -1087,9 +1058,9 @@ function Table$8(props) {
1087
1058
  core.Select,
1088
1059
  {
1089
1060
  size: "sm",
1090
- value: row.isAdmin ? "admin" : "student",
1061
+ value: row.isAdmin ? "educator" : "student",
1091
1062
  onChange: (value) => props.onRoleChange && props.onRoleChange(row, value),
1092
- data: [{ value: "student", label: "Student" }, { value: "admin", label: "Admin" }]
1063
+ data: [{ value: "student", label: "Student" }, { value: "educator", label: "Educator" }]
1093
1064
  }
1094
1065
  ))), /* @__PURE__ */ React__namespace.createElement("td", null, row.badgesEarned), /* @__PURE__ */ React__namespace.createElement("td", null, row.lessonsCompleted), /* @__PURE__ */ React__namespace.createElement("td", null, row.hasAccount && /* @__PURE__ */ React__namespace.createElement(icons.IconCheck, { color: "green" })), /* @__PURE__ */ React__namespace.createElement("td", null, row.lastActivity ? relativeTimeFromDates(row.lastActivity) : ""), /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0, position: "right" }, !row.readonly && !!props.onDelete && /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { color: "red" }, /* @__PURE__ */ React__namespace.createElement(icons.IconTrash, { onClick: () => openDeleteModal(row), size: 16, stroke: 1.5 }))))));
1095
1066
  return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea, null, /* @__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("th", null, "Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Role"), /* @__PURE__ */ React__namespace.createElement("th", null, "Badges Earned"), /* @__PURE__ */ React__namespace.createElement("th", null, "Lessons Completed"), /* @__PURE__ */ React__namespace.createElement("th", null, "Account Created?"), /* @__PURE__ */ React__namespace.createElement("th", null, "Last Active"), /* @__PURE__ */ React__namespace.createElement("th", null))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
@@ -1215,7 +1186,6 @@ const Class = (props) => {
1215
1186
  )), /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "Class"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "content" }, !props.loading && /* @__PURE__ */ React__namespace.createElement(
1216
1187
  SplitButton$2,
1217
1188
  {
1218
- withClassLink: props.withClassLink,
1219
1189
  onAddMembersClick: () => setOpened(true),
1220
1190
  onCopyClassLinkClick: props.onCopyLinkClick
1221
1191
  }