@local-civics/mgmt-ui 0.1.55 → 0.1.57

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
@@ -6,8 +6,8 @@ import * as React from 'react';
6
6
  */
7
7
  interface Item$i {
8
8
  lessonName: string;
9
+ completion: number;
9
10
  isStarted?: boolean;
10
- isComplete?: boolean;
11
11
  }
12
12
 
13
13
  /**
@@ -59,6 +59,8 @@ type BadgeProps = {
59
59
  onPreviewClick: () => void;
60
60
  onUserClick: (user: BadgeUserItem) => void;
61
61
  onLessonClick: (lesson: Item$g) => void;
62
+ onCopyLinkClick: () => void;
63
+ onExportDataClick: () => void;
62
64
  };
63
65
  /**
64
66
  * Badge
@@ -207,8 +209,9 @@ type ClassProps = {
207
209
  description: string;
208
210
  students: StudentItem[];
209
211
  percentageOfAccountsCreated: number;
210
- percentageOfBadgesEarned: number;
211
- percentageOfLessonsCompleted: number;
212
+ numberOfBadgesEarned: number;
213
+ numberOfLessonsCompleted: number;
214
+ withClassLink?: boolean;
212
215
  onBackClick: () => void;
213
216
  onCreateStudents: (students: StudentItem[]) => void;
214
217
  onDeleteStudent: (student: StudentItem) => void;
@@ -394,6 +397,8 @@ type LessonProps = {
394
397
  onClassChange: (classId: string) => void;
395
398
  onPreviewClick: () => void;
396
399
  onUserClick: (user: LessonUserItem) => void;
400
+ onCopyLinkClick: () => void;
401
+ onExportDataClick: () => void;
397
402
  };
398
403
  /**
399
404
  * Lesson
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ function _interopNamespaceDefault(e) {
31
31
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
32
32
  var papa__namespace = /*#__PURE__*/_interopNamespaceDefault(papa);
33
33
 
34
- const useStyles$d = core.createStyles((theme) => ({
34
+ const useStyles$f = core.createStyles((theme) => ({
35
35
  root: {
36
36
  display: "flex",
37
37
  backgroundImage: `linear-gradient(-60deg, ${theme.colors[theme.primaryColor][4]} 0%, ${theme.colors[theme.primaryColor][7]} 100%)`,
@@ -78,7 +78,7 @@ const useStyles$d = core.createStyles((theme) => ({
78
78
  }
79
79
  }));
80
80
  const StatsGroup = ({ data }) => {
81
- const { classes } = useStyles$d();
81
+ const { classes } = useStyles$f();
82
82
  const stats = data.map((stat) => {
83
83
  const value = (() => {
84
84
  if (stat.unit === "%") {
@@ -97,7 +97,58 @@ const Tabs = (props) => {
97
97
  return /* @__PURE__ */ React__namespace.createElement(core.Tabs, { value: props.value, onTabChange: props.onChange }, /* @__PURE__ */ React__namespace.createElement(core.Tabs.List, null, tabs));
98
98
  };
99
99
 
100
- const useStyles$c = core.createStyles((theme) => ({
100
+ const useStyles$e = core.createStyles((theme) => ({
101
+ button: {
102
+ borderTopRightRadius: 0,
103
+ borderBottomRightRadius: 0,
104
+ marginLeft: 0,
105
+ marginRight: 0
106
+ },
107
+ menuControl: {
108
+ borderTopLeftRadius: 0,
109
+ borderBottomLeftRadius: 0,
110
+ border: 0,
111
+ borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
112
+ }
113
+ }));
114
+ const SplitButton$2 = (props) => {
115
+ const { classes, theme } = useStyles$e();
116
+ const menuIconColor = theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
117
+ return /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
118
+ core.Button,
119
+ {
120
+ className: classes.button,
121
+ variant: "gradient",
122
+ onClick: props.onPreviewClick
123
+ },
124
+ "Preview"
125
+ ), /* @__PURE__ */ React__namespace.createElement(core.Menu, { transition: "pop", position: "bottom-end" }, /* @__PURE__ */ React__namespace.createElement(core.Menu.Target, null, /* @__PURE__ */ React__namespace.createElement(
126
+ core.ActionIcon,
127
+ {
128
+ variant: "gradient",
129
+ color: theme.primaryColor,
130
+ size: 36,
131
+ className: classes.menuControl
132
+ },
133
+ /* @__PURE__ */ React__namespace.createElement(icons.IconChevronDown, { size: 16, stroke: 1.5 })
134
+ )), /* @__PURE__ */ React__namespace.createElement(core.Menu.Dropdown, null, /* @__PURE__ */ React__namespace.createElement(
135
+ core.Menu.Item,
136
+ {
137
+ icon: /* @__PURE__ */ React__namespace.createElement(icons.IconClipboardCopy, { size: 16, stroke: 1.5, color: menuIconColor }),
138
+ onClick: props.onCopyLinkClick
139
+ },
140
+ "Copy link"
141
+ ), /* @__PURE__ */ React__namespace.createElement(
142
+ core.Menu.Item,
143
+ {
144
+ icon: /* @__PURE__ */ React__namespace.createElement(icons.IconTableExport, { size: 16, stroke: 1.5, color: menuIconColor }),
145
+ onClick: props.onExportDataClick
146
+ },
147
+ "Export data (.csv)"
148
+ ))));
149
+ };
150
+
151
+ const useStyles$d = core.createStyles((theme) => ({
101
152
  wrapper: {
102
153
  display: "flex",
103
154
  alignItems: "center",
@@ -148,7 +199,7 @@ const useStyles$c = core.createStyles((theme) => ({
148
199
  }
149
200
  }));
150
201
  const PlaceholderBanner = (props) => {
151
- const { classes } = useStyles$c();
202
+ const { classes } = useStyles$d();
152
203
  const title = props.title || "Nothing to display";
153
204
  const description = props.description || "We don't have anything to show you here just yet. Add data, check back later, or adjust your search.";
154
205
  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 }));
@@ -158,7 +209,7 @@ function Stack$2(props) {
158
209
  if (props.items.length === 0) {
159
210
  return null;
160
211
  }
161
- const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { span: 6 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { color: "dark.4", size: "lg" }, row.lessonName)), /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { span: 6 }, !!row.isComplete && /* @__PURE__ */ React__namespace.createElement(core.Badge, { variant: "filled" }, "Complete"), !row.isComplete && !row.isStarted && /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "red", variant: "filled" }, "Not started"), !row.isComplete && !!row.isStarted && /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "violet", variant: "filled" }, "In progress"))));
212
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { span: 6 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { color: "dark.4", size: "lg" }, row.lessonName)), /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { span: 6 }, row.completion >= 1 && /* @__PURE__ */ React__namespace.createElement(core.Badge, { variant: "filled" }, "Complete"), row.completion === 0 && !row.isStarted && /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "red", variant: "filled" }, "Not started"), row.completion > 0 && row.completion < 1 && /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "violet", variant: "filled" }, Math.round((row.completion + Number.EPSILON) * 100), "% Complete"))));
162
213
  return /* @__PURE__ */ React__namespace.createElement(core.Grid, { grow: true, gutter: "lg", sx: { padding: 20, minWidth: 700 } }, rows);
163
214
  }
164
215
 
@@ -185,6 +236,7 @@ function Table$f(props) {
185
236
  striped: true,
186
237
  highlightOnHover: true,
187
238
  records: props.items,
239
+ idAccessor: "userId",
188
240
  columns: [{
189
241
  accessor: "name",
190
242
  title: "Student Name",
@@ -219,7 +271,7 @@ function Table$e(props) {
219
271
  return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__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)));
220
272
  }
221
273
 
222
- const useStyles$b = core.createStyles((theme) => ({
274
+ const useStyles$c = core.createStyles((theme) => ({
223
275
  title: {
224
276
  fontSize: 34,
225
277
  fontWeight: 900,
@@ -232,7 +284,7 @@ const useStyles$b = core.createStyles((theme) => ({
232
284
  }
233
285
  }));
234
286
  const Badge = (props) => {
235
- const { classes } = useStyles$b();
287
+ const { classes } = useStyles$c();
236
288
  const [tab, setTab] = React.useState("lessons");
237
289
  const numberOfStudents = props.students.length;
238
290
  const percentageOfBadgesEarned = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length / numberOfStudents : 0;
@@ -245,12 +297,12 @@ const Badge = (props) => {
245
297
  },
246
298
  "Badges"
247
299
  ), /* @__PURE__ */ React__namespace.createElement(core.Group, null, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "Badge"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), /* @__PURE__ */ React__namespace.createElement(core.Stack, { ml: "auto" }, /* @__PURE__ */ React__namespace.createElement(
248
- core.Button,
300
+ SplitButton$2,
249
301
  {
250
- variant: "gradient",
251
- onClick: props.onPreviewClick
252
- },
253
- "Preview"
302
+ onPreviewClick: props.onPreviewClick,
303
+ onCopyLinkClick: props.onCopyLinkClick,
304
+ onExportDataClick: props.onExportDataClick
305
+ }
254
306
  ))))), /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(core.Stack, null, /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
255
307
  {
256
308
  title: "BADGE COMPLETION",
@@ -330,7 +382,7 @@ function Table$d(props) {
330
382
  return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { horizontalSpacing: 0, verticalSpacing: 0, sx: { minWidth: 700 } }, /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
331
383
  }
332
384
 
333
- const useStyles$a = core.createStyles((theme) => ({
385
+ const useStyles$b = core.createStyles((theme) => ({
334
386
  title: {
335
387
  fontSize: 34,
336
388
  fontWeight: 900,
@@ -343,7 +395,7 @@ const useStyles$a = core.createStyles((theme) => ({
343
395
  }
344
396
  }));
345
397
  const Badges = (props) => {
346
- const { classes } = useStyles$a();
398
+ const { classes } = useStyles$b();
347
399
  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(
348
400
  core.Autocomplete,
349
401
  {
@@ -551,7 +603,7 @@ const Dashboard = (props) => {
551
603
  )))))));
552
604
  };
553
605
 
554
- const useStyles$9 = core.createStyles((theme) => ({
606
+ const useStyles$a = core.createStyles((theme) => ({
555
607
  button: {
556
608
  borderTopRightRadius: 0,
557
609
  borderBottomRightRadius: 0,
@@ -565,18 +617,19 @@ const useStyles$9 = core.createStyles((theme) => ({
565
617
  borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
566
618
  }
567
619
  }));
568
- const SplitButton = (props) => {
569
- const { classes, theme } = useStyles$9();
620
+ const SplitButton$1 = (props) => {
621
+ const { classes, theme } = useStyles$a();
570
622
  const menuIconColor = theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
623
+ const hasMenu = !!props.withClassLink;
571
624
  return /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
572
625
  core.Button,
573
626
  {
574
- className: classes.button,
627
+ className: hasMenu ? classes.button : "",
575
628
  leftIcon: /* @__PURE__ */ React__namespace.createElement(icons.IconPlaylistAdd, { size: 14 }),
576
629
  onClick: props.onAddStudentsClick
577
630
  },
578
631
  "Add students"
579
- ), /* @__PURE__ */ React__namespace.createElement(core.Menu, { transition: "pop", position: "bottom-end" }, /* @__PURE__ */ React__namespace.createElement(core.Menu.Target, null, /* @__PURE__ */ React__namespace.createElement(
632
+ ), hasMenu && /* @__PURE__ */ React__namespace.createElement(core.Menu, { transition: "pop", position: "bottom-end" }, /* @__PURE__ */ React__namespace.createElement(core.Menu.Target, null, /* @__PURE__ */ React__namespace.createElement(
580
633
  core.ActionIcon,
581
634
  {
582
635
  variant: "filled",
@@ -585,7 +638,7 @@ const SplitButton = (props) => {
585
638
  className: classes.menuControl
586
639
  },
587
640
  /* @__PURE__ */ React__namespace.createElement(icons.IconChevronDown, { size: 16, stroke: 1.5 })
588
- )), /* @__PURE__ */ React__namespace.createElement(core.Menu.Dropdown, null, /* @__PURE__ */ React__namespace.createElement(
641
+ )), /* @__PURE__ */ React__namespace.createElement(core.Menu.Dropdown, null, !!props.withClassLink && /* @__PURE__ */ React__namespace.createElement(
589
642
  core.Menu.Item,
590
643
  {
591
644
  icon: /* @__PURE__ */ React__namespace.createElement(icons.IconClipboardCopy, { size: 16, stroke: 1.5, color: menuIconColor }),
@@ -638,7 +691,7 @@ var __spreadValues$3 = (a, b) => {
638
691
  return a;
639
692
  };
640
693
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
641
- const useStyles$8 = core.createStyles((theme) => ({
694
+ const useStyles$9 = core.createStyles((theme) => ({
642
695
  title: {
643
696
  fontSize: 34,
644
697
  fontWeight: 900,
@@ -668,7 +721,7 @@ const useStyles$8 = core.createStyles((theme) => ({
668
721
  }
669
722
  }));
670
723
  const Class = (props) => {
671
- const { classes } = useStyles$8();
724
+ const { classes } = useStyles$9();
672
725
  const form$1 = form.useForm({
673
726
  initialValues: {
674
727
  classId: "",
@@ -732,8 +785,9 @@ const Class = (props) => {
732
785
  },
733
786
  "Classes"
734
787
  ), /* @__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(
735
- SplitButton,
788
+ SplitButton$1,
736
789
  {
790
+ withClassLink: props.withClassLink,
737
791
  onAddStudentsClick: () => setOpened(true),
738
792
  onCopyClassLinkClick: props.onCopyLinkClick
739
793
  }
@@ -748,14 +802,12 @@ const Class = (props) => {
748
802
  unit: "%"
749
803
  },
750
804
  {
751
- title: "BADGE COMPLETION",
752
- value: props.percentageOfBadgesEarned,
753
- unit: "%"
805
+ title: "BADGES EARNED",
806
+ value: props.numberOfBadgesEarned
754
807
  },
755
808
  {
756
- title: "LESSON COMPLETION",
757
- value: props.percentageOfLessonsCompleted,
758
- unit: "%"
809
+ title: "LESSONS COMPLETED",
810
+ value: props.numberOfLessonsCompleted
759
811
  }
760
812
  ] }), /* @__PURE__ */ React__namespace.createElement(
761
813
  Table$7,
@@ -768,7 +820,7 @@ const Class = (props) => {
768
820
  ))))));
769
821
  };
770
822
  const DropzoneButton = (props) => {
771
- const { classes, theme } = useStyles$8();
823
+ const { classes, theme } = useStyles$9();
772
824
  const openRef = React__namespace.useRef(null);
773
825
  const [loading, setLoading] = React__namespace.useState(false);
774
826
  const onDrop = React__namespace.useCallback((acceptedFiles) => {
@@ -854,7 +906,7 @@ var __spreadValues$2 = (a, b) => {
854
906
  }
855
907
  return a;
856
908
  };
857
- const useStyles$7 = core.createStyles((theme) => ({
909
+ const useStyles$8 = core.createStyles((theme) => ({
858
910
  title: {
859
911
  fontSize: 34,
860
912
  fontWeight: 900,
@@ -867,7 +919,7 @@ const useStyles$7 = core.createStyles((theme) => ({
867
919
  }
868
920
  }));
869
921
  const Classes = (props) => {
870
- const { classes } = useStyles$7();
922
+ const { classes } = useStyles$8();
871
923
  const form$1 = form.useForm({
872
924
  initialValues: {
873
925
  classId: "",
@@ -930,7 +982,7 @@ const Classes = (props) => {
930
982
  ))))));
931
983
  };
932
984
 
933
- const useStyles$6 = core.createStyles((theme) => ({
985
+ const useStyles$7 = core.createStyles((theme) => ({
934
986
  title: {
935
987
  fontSize: 34,
936
988
  fontWeight: 900,
@@ -944,7 +996,7 @@ const useStyles$6 = core.createStyles((theme) => ({
944
996
  }
945
997
  }));
946
998
  const UserInfo = (props) => {
947
- const { classes } = useStyles$6();
999
+ const { classes } = useStyles$7();
948
1000
  return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(core.Title, { className: classes.title }, props.name), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "xs" }, props.impactStatement));
949
1001
  };
950
1002
 
@@ -1065,7 +1117,7 @@ const Student = (props) => {
1065
1117
  ))))));
1066
1118
  };
1067
1119
 
1068
- const useStyles$5 = core.createStyles((theme, props) => {
1120
+ const useStyles$6 = core.createStyles((theme, props) => {
1069
1121
  const from = props.from || "blue";
1070
1122
  const to = props.to || "green";
1071
1123
  return {
@@ -1093,7 +1145,7 @@ const useStyles$5 = core.createStyles((theme, props) => {
1093
1145
  };
1094
1146
  });
1095
1147
  function CardGradient(props) {
1096
- const { classes } = useStyles$5(props);
1148
+ const { classes } = useStyles$6(props);
1097
1149
  const from = props.from || "blue";
1098
1150
  const to = props.to || "green";
1099
1151
  const icon = props.icon || /* @__PURE__ */ React__namespace.createElement(icons.IconColorSwatch, { size: 28, stroke: 1.5 });
@@ -1137,7 +1189,7 @@ var __objRest = (source, exclude) => {
1137
1189
  }
1138
1190
  return target;
1139
1191
  };
1140
- const useStyles$4 = core.createStyles((theme) => ({
1192
+ const useStyles$5 = core.createStyles((theme) => ({
1141
1193
  card: {
1142
1194
  height: 240,
1143
1195
  backgroundSize: "cover",
@@ -1182,7 +1234,7 @@ const TenantBanner = (_a) => {
1182
1234
  "style",
1183
1235
  "className"
1184
1236
  ]);
1185
- const { classes, cx, theme } = useStyles$4();
1237
+ const { classes, cx, theme } = useStyles$5();
1186
1238
  return /* @__PURE__ */ React__namespace.createElement(
1187
1239
  core.Card,
1188
1240
  __spreadValues$1({
@@ -1280,6 +1332,57 @@ function Table$2(props) {
1280
1332
  return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__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, "Student Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Reflection"), /* @__PURE__ */ React__namespace.createElement("th", null, "Rating"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
1281
1333
  }
1282
1334
 
1335
+ const useStyles$4 = core.createStyles((theme) => ({
1336
+ button: {
1337
+ borderTopRightRadius: 0,
1338
+ borderBottomRightRadius: 0,
1339
+ marginLeft: 0,
1340
+ marginRight: 0
1341
+ },
1342
+ menuControl: {
1343
+ borderTopLeftRadius: 0,
1344
+ borderBottomLeftRadius: 0,
1345
+ border: 0,
1346
+ borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
1347
+ }
1348
+ }));
1349
+ const SplitButton = (props) => {
1350
+ const { classes, theme } = useStyles$4();
1351
+ const menuIconColor = theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
1352
+ return /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
1353
+ core.Button,
1354
+ {
1355
+ className: classes.button,
1356
+ variant: "gradient",
1357
+ onClick: props.onPreviewClick
1358
+ },
1359
+ "Preview"
1360
+ ), /* @__PURE__ */ React__namespace.createElement(core.Menu, { transition: "pop", position: "bottom-end" }, /* @__PURE__ */ React__namespace.createElement(core.Menu.Target, null, /* @__PURE__ */ React__namespace.createElement(
1361
+ core.ActionIcon,
1362
+ {
1363
+ variant: "gradient",
1364
+ color: theme.primaryColor,
1365
+ size: 36,
1366
+ className: classes.menuControl
1367
+ },
1368
+ /* @__PURE__ */ React__namespace.createElement(icons.IconChevronDown, { size: 16, stroke: 1.5 })
1369
+ )), /* @__PURE__ */ React__namespace.createElement(core.Menu.Dropdown, null, /* @__PURE__ */ React__namespace.createElement(
1370
+ core.Menu.Item,
1371
+ {
1372
+ icon: /* @__PURE__ */ React__namespace.createElement(icons.IconClipboardCopy, { size: 16, stroke: 1.5, color: menuIconColor }),
1373
+ onClick: props.onCopyLinkClick
1374
+ },
1375
+ "Copy link"
1376
+ ), /* @__PURE__ */ React__namespace.createElement(
1377
+ core.Menu.Item,
1378
+ {
1379
+ icon: /* @__PURE__ */ React__namespace.createElement(icons.IconTableExport, { size: 16, stroke: 1.5, color: menuIconColor }),
1380
+ onClick: props.onExportDataClick
1381
+ },
1382
+ "Export data (.csv)"
1383
+ ))));
1384
+ };
1385
+
1283
1386
  function Stack$1(props) {
1284
1387
  if (props.items.length === 0) {
1285
1388
  return null;
@@ -1310,6 +1413,7 @@ function Table$1(props) {
1310
1413
  withColumnBorders: true,
1311
1414
  striped: true,
1312
1415
  highlightOnHover: true,
1416
+ idAccessor: "userId",
1313
1417
  records: props.items,
1314
1418
  columns: [{
1315
1419
  accessor: "name",
@@ -1420,12 +1524,12 @@ const Lesson = (props) => {
1420
1524
  },
1421
1525
  "Lessons"
1422
1526
  ), /* @__PURE__ */ React__namespace.createElement(core.Group, null, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "Lesson"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), /* @__PURE__ */ React__namespace.createElement(core.Stack, { ml: "auto" }, /* @__PURE__ */ React__namespace.createElement(
1423
- core.Button,
1527
+ SplitButton,
1424
1528
  {
1425
- variant: "gradient",
1426
- onClick: props.onPreviewClick
1427
- },
1428
- "Preview"
1529
+ onPreviewClick: props.onPreviewClick,
1530
+ onCopyLinkClick: props.onCopyLinkClick,
1531
+ onExportDataClick: props.onExportDataClick
1532
+ }
1429
1533
  ))))), /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(core.Stack, null, /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
1430
1534
  {
1431
1535
  title: "LESSON COMPLETION",