@local-civics/mgmt-ui 0.1.212 → 0.1.213

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
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var React = require('react');
4
- var core = require('@mantine/core');
5
4
  var icons = require('@tabler/icons');
5
+ var core = require('@mantine/core');
6
6
  var reactRouterDom = require('react-router-dom');
7
7
  var notifications = require('@mantine/notifications');
8
8
  var mantineDatatable = require('mantine-datatable');
@@ -15,66 +15,65 @@ var reactCharts = require('react-charts');
15
15
  var hooks = require('@mantine/hooks');
16
16
 
17
17
  function _interopNamespaceDefault(e) {
18
- var n = Object.create(null);
19
- if (e) {
20
- Object.keys(e).forEach(function (k) {
21
- if (k !== 'default') {
22
- var d = Object.getOwnPropertyDescriptor(e, k);
23
- Object.defineProperty(n, k, d.get ? d : {
24
- enumerable: true,
25
- get: function () { return e[k]; }
26
- });
27
- }
18
+ var n = Object.create(null);
19
+ if (e) {
20
+ Object.keys(e).forEach(function (k) {
21
+ if (k !== 'default') {
22
+ var d = Object.getOwnPropertyDescriptor(e, k);
23
+ Object.defineProperty(n, k, d.get ? d : {
24
+ enumerable: true,
25
+ get: function () { return e[k]; }
28
26
  });
29
- }
30
- n.default = e;
31
- return Object.freeze(n);
27
+ }
28
+ });
29
+ }
30
+ n.default = e;
31
+ return Object.freeze(n);
32
32
  }
33
33
 
34
34
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
35
35
  var papa__namespace = /*#__PURE__*/_interopNamespaceDefault(papa);
36
36
 
37
- var __defProp$f = Object.defineProperty;
38
- var __getOwnPropSymbols$f = Object.getOwnPropertySymbols;
39
- var __hasOwnProp$f = Object.prototype.hasOwnProperty;
40
- var __propIsEnum$f = Object.prototype.propertyIsEnumerable;
41
- var __defNormalProp$f = (obj, key, value) => key in obj ? __defProp$f(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
42
- var __spreadValues$f = (a, b) => {
43
- for (var prop in b || (b = {}))
44
- if (__hasOwnProp$f.call(b, prop))
45
- __defNormalProp$f(a, prop, b[prop]);
46
- if (__getOwnPropSymbols$f)
47
- for (var prop of __getOwnPropSymbols$f(b)) {
48
- if (__propIsEnum$f.call(b, prop))
49
- __defNormalProp$f(a, prop, b[prop]);
50
- }
51
- return a;
52
- };
53
- var __objRest$2 = (source, exclude) => {
54
- var target = {};
55
- for (var prop in source)
56
- if (__hasOwnProp$f.call(source, prop) && exclude.indexOf(prop) < 0)
57
- target[prop] = source[prop];
58
- if (source != null && __getOwnPropSymbols$f)
59
- for (var prop of __getOwnPropSymbols$f(source)) {
60
- if (exclude.indexOf(prop) < 0 && __propIsEnum$f.call(source, prop))
61
- target[prop] = source[prop];
37
+ function styleInject(css, ref) {
38
+ if ( ref === void 0 ) ref = {};
39
+ var insertAt = ref.insertAt;
40
+
41
+ if (!css || typeof document === 'undefined') { return; }
42
+
43
+ var head = document.head || document.getElementsByTagName('head')[0];
44
+ var style = document.createElement('style');
45
+ style.type = 'text/css';
46
+
47
+ if (insertAt === 'top') {
48
+ if (head.firstChild) {
49
+ head.insertBefore(style, head.firstChild);
50
+ } else {
51
+ head.appendChild(style);
62
52
  }
63
- return target;
64
- };
65
- const useStyles$v = core.createStyles((theme) => ({
66
- user: {
67
- display: "block",
68
- width: "100%",
69
- padding: theme.spacing.md,
70
- cursor: "default",
71
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black
53
+ } else {
54
+ head.appendChild(style);
72
55
  }
73
- }));
74
- function UserButton(_a) {
75
- var _b = _a, { image, name, email, icon } = _b, others = __objRest$2(_b, ["image", "name", "email", "icon"]);
76
- const { classes } = useStyles$v();
77
- return /* @__PURE__ */ React__namespace.createElement(core.Group, __spreadValues$f({ 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)));
56
+
57
+ if (style.styleSheet) {
58
+ style.styleSheet.cssText = css;
59
+ } else {
60
+ style.appendChild(document.createTextNode(css));
61
+ }
62
+ }
63
+
64
+ var css_248z = "@font-face{font-family:ProximaNova;src:url(https://cdn.localcivics.io/fonts/ProximaNova.otf) format(\"opentype\")}@font-face{font-family:ProximaNova;font-weight:700;src:url(https://cdn.localcivics.io/fonts/ProximaNovaBold.otf) format(\"opentype\")}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.\\!relative{position:relative!important}.m-3{margin:.75rem}.mx-auto{margin-left:auto;margin-right:auto}.mt-1{margin-top:.25rem}.mt-6{margin-top:1.5rem}.mt-2{margin-top:.5rem}.mt-1\\.5{margin-top:.375rem}.ml-\\[29px\\]{margin-left:29px}.mt-0\\.5{margin-top:.125rem}.mt-0{margin-top:0}.block{display:block}.inline{display:inline}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-full{height:100%}.h-8{height:2rem}.h-7{height:1.75rem}.h-screen{height:100vh}.h-\\[30px\\]{height:30px}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.w-8{width:2rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-7{width:1.75rem}.w-screen{width:100vw}.w-\\[230px\\]{width:230px}.w-24{width:6rem}.w-\\[30px\\]{width:30px}.min-w-0{min-width:0}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.rotate-90{--tw-rotate:90deg}.rotate-90,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.grid-cols-\\[2\\.2fr_1\\.2fr_1fr_1\\.2fr_1fr_0\\.6fr\\]{grid-template-columns:2.2fr 1.2fr 1fr 1.2fr 1fr .6fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-5{gap:1.25rem}.gap-2\\.5{gap:.625rem}.gap-2{gap:.5rem}.gap-4{gap:1rem}.gap-1{gap:.25rem}.gap-1\\.5{gap:.375rem}.gap-3{gap:.75rem}.gap-0\\.5{gap:.125rem}.gap-0{gap:0}.gap-x-10{-moz-column-gap:2.5rem;column-gap:2.5rem}.gap-y-4{row-gap:1rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.25rem*var(--tw-space-y-reverse));margin-top:calc(.25rem*(1 - var(--tw-space-y-reverse)))}.space-y-1\\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.375rem*var(--tw-space-y-reverse));margin-top:calc(.375rem*(1 - var(--tw-space-y-reverse)))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-none{overscroll-behavior:none}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-xl{border-radius:.75rem}.rounded-lg{border-radius:.5rem}.rounded-full{border-radius:9999px}.rounded-md{border-radius:.375rem}.rounded-2xl{border-radius:1rem}.rounded-\\[10px\\]{border-radius:10px}.rounded-\\[8px\\]{border-radius:8px}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-l{border-left-width:1px}.border-none{border-style:none}.border-slate-200{--tw-border-opacity:1;border-color:rgb(226 232 240/var(--tw-border-opacity))}.border-slate-100{--tw-border-opacity:1;border-color:rgb(241 245 249/var(--tw-border-opacity))}.border-sky-blue-400\\/30{border-color:rgba(59,208,242,.3)}.border-mint-400\\/30{border-color:rgba(30,226,175,.3)}.border-gold-400\\/30{border-color:rgba(255,212,77,.3)}.border-transparent{border-color:transparent}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-transparent{background-color:transparent}.bg-dark-blue-400{--tw-bg-opacity:1;background-color:rgb(35 42 58/var(--tw-bg-opacity))}.bg-mint-400\\/20{background-color:rgba(30,226,175,.2)}.bg-gold-400\\/15{background-color:rgba(255,212,77,.15)}.bg-sky-blue-400\\/15{background-color:rgba(59,208,242,.15)}.bg-sky-blue-400\\/25{background-color:rgba(59,208,242,.25)}.bg-mint-400\\/15{background-color:rgba(30,226,175,.15)}.bg-mint-400\\/25{background-color:rgba(30,226,175,.25)}.bg-gold-400\\/25{background-color:rgba(255,212,77,.25)}.bg-slate-50{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.from-gold-400{--tw-gradient-from:#ffd44d;--tw-gradient-to:rgba(255,212,77,0);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-dark-blue-600{--tw-gradient-from:#0a0f2e;--tw-gradient-to:rgba(10,15,46,0);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-sky-blue-400\\/15{--tw-gradient-from:rgba(59,208,242,.15);--tw-gradient-to:rgba(59,208,242,0);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.via-dark-blue-400{--tw-gradient-to:rgba(35,42,58,0);--tw-gradient-stops:var(--tw-gradient-from),#232a3a,var(--tw-gradient-to)}.to-\\[\\#f5c300\\]{--tw-gradient-to:#f5c300}.to-sky-blue-400{--tw-gradient-to:#3bd0f2}.to-mint-400\\/15{--tw-gradient-to:rgba(30,226,175,.15)}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-8{padding:2rem}.p-4{padding:1rem}.p-2\\.5{padding:.625rem}.p-2{padding:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-8{padding-bottom:2rem;padding-top:2rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-4{padding-bottom:1rem;padding-top:1rem}.px-3\\.5{padding-left:.875rem;padding-right:.875rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-2\\.5{padding-bottom:.625rem;padding-top:.625rem}.py-3\\.5{padding-bottom:.875rem;padding-top:.875rem}.px-2\\.5{padding-left:.625rem;padding-right:.625rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.px-8{padding-left:2rem;padding-right:2rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.py-0\\.5{padding-bottom:.125rem;padding-top:.125rem}.py-0{padding-bottom:0;padding-top:0}.pl-2\\.5{padding-left:.625rem}.pl-2{padding-left:.5rem}.text-center{text-align:center}.font-proxima{font-family:ProximaNova}.text-2xl{font-size:1.5rem;line-height:2rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-\\[10px\\]{font-size:10px}.text-\\[10\\.5px\\]{font-size:10.5px}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\\[11px\\]{font-size:11px}.text-\\[11\\.5px\\]{font-size:11.5px}.font-extrabold{font-weight:800}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-black{font-weight:900}.uppercase{text-transform:uppercase}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-dark-blue-400{--tw-text-opacity:1;color:rgb(35 42 58/var(--tw-text-opacity))}.text-slate-500{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.text-sky-blue-400{--tw-text-opacity:1;color:rgb(59 208 242/var(--tw-text-opacity))}.text-slate-600{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-mint-400{--tw-text-opacity:1;color:rgb(30 226 175/var(--tw-text-opacity))}.text-slate-300{--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}.text-white\\/70{color:hsla(0,0%,100%,.7)}.text-gold-400{--tw-text-opacity:1;color:rgb(255 212 77/var(--tw-text-opacity))}.underline{text-decoration-line:underline}.no-underline{text-decoration-line:none}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow-\\[0_3px_12px_rgba\\(255\\2c 212\\2c 77\\2c 0\\.35\\)\\],.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-\\[0_3px_12px_rgba\\(255\\2c 212\\2c 77\\2c 0\\.35\\)\\]{--tw-shadow:0 3px 12px rgba(255,212,77,.35);--tw-shadow-colored:0 3px 12px var(--tw-shadow-color)}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.shadow,.shadow-\\[0_2px_10px_rgba\\(30\\2c 226\\2c 175\\2c 0\\.15\\)\\]{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-\\[0_2px_10px_rgba\\(30\\2c 226\\2c 175\\2c 0\\.15\\)\\]{--tw-shadow:0 2px 10px rgba(30,226,175,.15);--tw-shadow-colored:0 2px 10px var(--tw-shadow-color)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}*,:after,:before{border-style:solid;border-width:0}.placeholder\\:text-slate-400::-moz-placeholder{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.placeholder\\:text-slate-400::placeholder{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.hover\\:bg-slate-50:hover{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity))}.hover\\:bg-red-50:hover{--tw-bg-opacity:1;background-color:rgb(254 242 242/var(--tw-bg-opacity))}.hover\\:text-red-500:hover{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.hover\\:text-slate-500:hover{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.disabled\\:opacity-50:disabled{opacity:.5}";
65
+ styleInject(css_248z);
66
+
67
+ function UserButton({ image, name, email }) {
68
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "m-3 flex items-center gap-2.5 rounded-xl border border-mint-400/30 bg-gradient-to-r from-sky-blue-400/15 to-mint-400/15 p-2.5 shadow-[0_2px_10px_rgba(30,226,175,0.15)]" }, /* @__PURE__ */ React__namespace.createElement(
69
+ core.Avatar,
70
+ {
71
+ src: image,
72
+ radius: "xl",
73
+ size: 32,
74
+ styles: { placeholder: { color: "#232A3A", backgroundColor: "rgba(30,226,175,0.2)" } }
75
+ }
76
+ ), /* @__PURE__ */ React__namespace.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "truncate text-xs font-bold text-dark-blue-400" }, name), /* @__PURE__ */ React__namespace.createElement("div", { className: "truncate text-[10px] text-slate-500" }, email)));
78
77
  }
79
78
 
80
79
  const compact = (num) => {
@@ -84,217 +83,96 @@ const compact = (num) => {
84
83
  }).format(num || 0);
85
84
  };
86
85
 
87
- const useStyles$u = core.createStyles((theme, _params, getRef) => {
88
- const icon = getRef("icon");
89
- return {
90
- control: {
91
- fontWeight: 500,
92
- width: "100%",
93
- padding: `${theme.spacing.xs}px ${theme.spacing.md}px`,
94
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
95
- fontSize: theme.fontSizes.sm,
96
- "&:hover": {
97
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.colors.gray[0],
98
- color: theme.colorScheme === "dark" ? theme.white : theme.black
99
- }
100
- },
101
- controlButton: {
102
- cursor: "pointer"
103
- },
104
- badge: {
105
- pointerEvents: "none"
106
- },
107
- link: {
108
- fontWeight: 500,
109
- display: "block",
110
- textDecoration: "none",
111
- padding: `${theme.spacing.xs}px ${theme.spacing.md}px`,
112
- paddingLeft: 31,
113
- marginLeft: 30,
114
- fontSize: theme.fontSizes.sm,
115
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.colors.gray[7],
116
- borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[3]}`,
117
- "&:hover": {
118
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.colors.gray[0],
119
- color: theme.colorScheme === "dark" ? theme.white : theme.black
120
- }
121
- },
122
- linkActive: {
123
- "&, &:hover": {
124
- backgroundColor: theme.fn.variant({ variant: "light", color: theme.primaryColor }).background,
125
- color: theme.fn.variant({ variant: "light", color: theme.primaryColor }).color,
126
- [`& .${icon}`]: {
127
- color: theme.fn.variant({ variant: "light", color: theme.primaryColor }).color
128
- }
129
- }
130
- },
131
- chevron: {
132
- transition: "transform 200ms ease"
133
- },
134
- linkIcon: {
135
- ref: icon
136
- }
137
- };
138
- });
139
- function LinksGroup({ icon: Icon, href, label, initiallyOpened, links, active, notifications }) {
140
- const { classes, theme, cx } = useStyles$u();
86
+ const ACCENT_CLASSNAMES = {
87
+ cyan: {
88
+ row: "bg-sky-blue-400/15 border-sky-blue-400/30",
89
+ chip: "bg-sky-blue-400/25",
90
+ icon: "text-sky-blue-400",
91
+ pill: "bg-sky-blue-400/15 text-dark-blue-400"
92
+ },
93
+ mint: {
94
+ row: "bg-mint-400/15 border-mint-400/30",
95
+ chip: "bg-mint-400/25",
96
+ icon: "text-mint-400",
97
+ pill: "bg-mint-400/15 text-dark-blue-400"
98
+ },
99
+ gold: {
100
+ row: "bg-gold-400/15 border-gold-400/30",
101
+ chip: "bg-gold-400/25",
102
+ icon: "text-gold-400",
103
+ pill: "bg-gold-400/15 text-dark-blue-400"
104
+ }
105
+ };
106
+ function LinksGroup({ icon: Icon, href, label, accent = "cyan", initiallyOpened, links, active, notifications }) {
141
107
  const hasLinks = Array.isArray(links) && links.length > 0;
142
108
  const hasActiveLinks = Array.isArray(links) && links.map((l) => !!active && active === `${label}/${l.label}`).reduce((a, b) => a || b, false);
143
109
  const [opened, setOpened] = React.useState(initiallyOpened || hasActiveLinks || false);
144
110
  React__namespace.useEffect(() => {
145
111
  setOpened(hasActiveLinks);
146
112
  }, [hasActiveLinks]);
147
- const ChevronIcon = theme.dir === "ltr" ? icons.IconChevronRight : icons.IconChevronLeft;
113
+ const isActive = !!active && !hasLinks && label === active;
114
+ const accentClasses = ACCENT_CLASSNAMES[accent];
148
115
  const items = (hasLinks ? links : []).map((link) => {
116
+ const linkActive = !!active && active === `${label}/${link.label}`;
149
117
  return /* @__PURE__ */ React__namespace.createElement(
150
- core.Box,
118
+ reactRouterDom.Link,
151
119
  {
152
- className: cx(classes.link, { [classes.linkActive]: !!active && active === `${label}/${link.label}` }),
153
- key: link.label
120
+ key: link.label,
121
+ to: link.href,
122
+ className: `flex items-center justify-between gap-2 rounded-[8px] border px-3 py-2 text-xs no-underline transition-colors ${linkActive ? `${accentClasses.row} font-bold text-dark-blue-400` : "border-transparent font-medium text-slate-500 hover:bg-slate-50"}`
154
123
  },
155
- /* @__PURE__ */ React__namespace.createElement(core.Group, { position: "apart", spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(core.Text, { component: reactRouterDom.Link, to: link.href }, link.label), !!link.notifications && /* @__PURE__ */ React__namespace.createElement(core.Badge, { size: "sm", variant: "filled", className: classes.badge }, compact(link.notifications)))
124
+ link.label,
125
+ !!link.notifications && /* @__PURE__ */ React__namespace.createElement("span", { className: `rounded-full px-2 py-0.5 text-[10px] font-bold ${accentClasses.pill}` }, compact(link.notifications))
156
126
  );
157
127
  });
158
- return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(
159
- core.Group,
128
+ const rowInner = /* @__PURE__ */ React__namespace.createElement("div", { className: "flex flex-1 items-center gap-2.5" }, /* @__PURE__ */ React__namespace.createElement("div", { className: `flex h-[30px] w-[30px] shrink-0 items-center justify-center rounded-lg ${isActive ? accentClasses.chip : "bg-slate-50"}` }, /* @__PURE__ */ React__namespace.createElement(Icon, { size: 14, stroke: isActive ? 2.2 : 1.75, className: isActive ? accentClasses.icon : "text-slate-400" })), /* @__PURE__ */ React__namespace.createElement("span", { className: `flex-1 text-xs ${isActive ? "font-bold text-dark-blue-400" : "font-medium text-slate-500"}` }, label));
129
+ return /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement(
130
+ "div",
160
131
  {
161
- className: cx(classes.control, {
162
- [classes.linkActive]: !!active && !hasLinks && label === active,
163
- [classes.controlButton]: hasLinks
164
- }),
165
- onClick: () => setOpened((o) => !o),
166
- position: "apart",
167
- spacing: 0
132
+ onClick: () => hasLinks && setOpened((o) => !o),
133
+ className: `flex items-center gap-2.5 rounded-[10px] border px-3.5 py-2.5 transition-colors ${isActive ? accentClasses.row : "border-transparent hover:bg-slate-50"} ${hasLinks ? "cursor-pointer" : ""}`
168
134
  },
169
- /* @__PURE__ */ React__namespace.createElement(core.Box, { sx: { display: "flex", alignItems: "center" } }, /* @__PURE__ */ React__namespace.createElement(core.ThemeIcon, { variant: "light", size: 30 }, /* @__PURE__ */ React__namespace.createElement(Icon, { className: classes.linkIcon, size: 18 })), /* @__PURE__ */ React__namespace.createElement(core.Box, { ml: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Text, { component: reactRouterDom.Link, to: href }, label))),
170
- !!notifications && /* @__PURE__ */ React__namespace.createElement(core.Badge, { size: "sm", variant: "filled", className: classes.badge }, compact(notifications)),
135
+ hasLinks ? rowInner : /* @__PURE__ */ React__namespace.createElement(reactRouterDom.Link, { to: href, className: "flex flex-1 items-center gap-2.5 no-underline" }, rowInner),
136
+ !!notifications && /* @__PURE__ */ React__namespace.createElement("span", { className: `rounded-full px-2 py-0.5 text-[10px] font-bold ${accentClasses.pill}` }, compact(notifications)),
171
137
  hasLinks && /* @__PURE__ */ React__namespace.createElement(
172
- ChevronIcon,
138
+ icons.IconChevronRight,
173
139
  {
174
- className: classes.chevron,
175
- size: 14,
176
- stroke: 1.5,
177
- style: {
178
- transform: opened ? `rotate(${theme.dir === "rtl" ? -90 : 90}deg)` : "none"
179
- }
140
+ size: 13,
141
+ stroke: 2.2,
142
+ className: `shrink-0 text-slate-300 transition-transform ${opened ? "rotate-90" : ""}`
180
143
  }
181
144
  )
182
- ), hasLinks ? /* @__PURE__ */ React__namespace.createElement(core.Collapse, { in: opened }, items) : null);
145
+ ), hasLinks && opened && /* @__PURE__ */ React__namespace.createElement("div", { className: "ml-[29px] mt-0.5 flex flex-col gap-0.5 border-l border-slate-100 pl-2.5" }, items));
183
146
  }
184
147
 
185
- var __defProp$e = Object.defineProperty;
186
- var __defProps$a = Object.defineProperties;
187
- var __getOwnPropDescs$a = Object.getOwnPropertyDescriptors;
188
- var __getOwnPropSymbols$e = Object.getOwnPropertySymbols;
189
- var __hasOwnProp$e = Object.prototype.hasOwnProperty;
190
- var __propIsEnum$e = Object.prototype.propertyIsEnumerable;
191
- var __defNormalProp$e = (obj, key, value) => key in obj ? __defProp$e(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
192
- var __spreadValues$e = (a, b) => {
148
+ var __defProp$d = Object.defineProperty;
149
+ var __defProps$9 = Object.defineProperties;
150
+ var __getOwnPropDescs$9 = Object.getOwnPropertyDescriptors;
151
+ var __getOwnPropSymbols$d = Object.getOwnPropertySymbols;
152
+ var __hasOwnProp$d = Object.prototype.hasOwnProperty;
153
+ var __propIsEnum$d = Object.prototype.propertyIsEnumerable;
154
+ var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
155
+ var __spreadValues$d = (a, b) => {
193
156
  for (var prop in b || (b = {}))
194
- if (__hasOwnProp$e.call(b, prop))
195
- __defNormalProp$e(a, prop, b[prop]);
196
- if (__getOwnPropSymbols$e)
197
- for (var prop of __getOwnPropSymbols$e(b)) {
198
- if (__propIsEnum$e.call(b, prop))
199
- __defNormalProp$e(a, prop, b[prop]);
157
+ if (__hasOwnProp$d.call(b, prop))
158
+ __defNormalProp$d(a, prop, b[prop]);
159
+ if (__getOwnPropSymbols$d)
160
+ for (var prop of __getOwnPropSymbols$d(b)) {
161
+ if (__propIsEnum$d.call(b, prop))
162
+ __defNormalProp$d(a, prop, b[prop]);
200
163
  }
201
164
  return a;
202
165
  };
203
- var __spreadProps$a = (a, b) => __defProps$a(a, __getOwnPropDescs$a(b));
204
- const useStyles$t = core.createStyles((theme, _params, getRef) => {
205
- const icon = getRef("icon");
206
- return {
207
- navbar: {
208
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.white
209
- },
210
- navHeader: {
211
- [`@media (max-width: ${theme.breakpoints.sm}px)`]: {
212
- height: 71,
213
- position: "absolute",
214
- top: 0
215
- }
216
- },
217
- navBody: {
218
- [`@media (max-width: ${theme.breakpoints.sm}px)`]: {
219
- display: "none"
220
- }
221
- },
222
- burger: {
223
- [theme.fn.largerThan("sm")]: {
224
- display: "none"
225
- }
226
- },
227
- header: {
228
- padding: theme.spacing.md,
229
- paddingTop: 0,
230
- marginLeft: -theme.spacing.md,
231
- marginRight: -theme.spacing.md,
232
- color: theme.colorScheme === "dark" ? theme.white : theme.black,
233
- borderBottom: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[3]}`
234
- },
235
- link: __spreadProps$a(__spreadValues$e({}, theme.fn.focusStyles()), {
236
- display: "flex",
237
- alignItems: "center",
238
- textDecoration: "none",
239
- fontSize: theme.fontSizes.sm,
240
- color: theme.colorScheme === "dark" ? theme.colors.dark[1] : theme.colors.gray[7],
241
- padding: `${theme.spacing.xs}px ${theme.spacing.sm}px`,
242
- borderRadius: theme.radius.sm,
243
- fontWeight: 500,
244
- "&:hover": {
245
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[0],
246
- color: theme.colorScheme === "dark" ? theme.white : theme.black,
247
- [`& .${icon}`]: {
248
- color: theme.colorScheme === "dark" ? theme.white : theme.black
249
- }
250
- }
251
- }),
252
- linkIcon: {
253
- ref: icon,
254
- color: theme.colorScheme === "dark" ? theme.colors.dark[2] : theme.colors.gray[6],
255
- marginRight: theme.spacing.sm
256
- },
257
- links: {
258
- marginLeft: -theme.spacing.md,
259
- marginRight: -theme.spacing.md
260
- },
261
- user: {
262
- margin: theme.spacing.md,
263
- marginLeft: 0,
264
- marginRight: 0
265
- },
266
- linksInner: {
267
- paddingBottom: theme.spacing.xl
268
- },
269
- footer: {
270
- paddingTop: theme.spacing.md,
271
- paddingBottom: theme.spacing.md,
272
- borderTop: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[2]}`
273
- },
274
- active: {
275
- "&, &:hover": {
276
- backgroundColor: theme.fn.variant({ variant: "light", color: theme.primaryColor }).background,
277
- color: theme.fn.variant({ variant: "light", color: theme.primaryColor }).color
278
- }
279
- }
280
- };
281
- });
166
+ var __spreadProps$9 = (a, b) => __defProps$9(a, __getOwnPropDescs$9(b));
282
167
  const data = [
283
- { label: "Home", icon: icons.IconHome2 },
284
- { label: "Dashboard", icon: icons.IconGauge },
285
- { label: "Classes", icon: icons.IconCategory2 },
286
- { label: "Pathways", icon: icons.IconRoute },
287
- { label: "Badges", icon: icons.IconAlbum },
288
- { label: "Lessons", icon: icons.IconLambda },
289
- { label: "File Locker", icon: icons.IconClipboard },
290
- {
291
- label: "Organization",
292
- icon: icons.IconBuilding,
293
- links: [
294
- { label: "Overview" },
295
- { label: "People" }
296
- ]
297
- }
168
+ { label: "Home", icon: icons.IconHome2, accent: "cyan" },
169
+ { label: "Dashboard", icon: icons.IconGauge, accent: "mint" },
170
+ { label: "Classes", icon: icons.IconCategory2, accent: "gold" },
171
+ { label: "Pathways", icon: icons.IconRoute, accent: "cyan" },
172
+ { label: "Badges", icon: icons.IconAlbum, accent: "mint" },
173
+ { label: "Lessons", icon: icons.IconLambda, accent: "gold" },
174
+ { label: "File Locker", icon: icons.IconClipboard, accent: "cyan" },
175
+ { label: "Organization", icon: icons.IconBuilding, accent: "gold", links: [{ label: "Overview" }, { label: "People" }] }
298
176
  ];
299
177
  const TRIAL_PAGES = [
300
178
  "Home",
@@ -302,9 +180,6 @@ const TRIAL_PAGES = [
302
180
  "Badges"
303
181
  ];
304
182
  function Navbar(props) {
305
- const { classes, cx } = useStyles$t();
306
- const [burgerOpen, setBurgerOpen] = React__namespace.useState(false);
307
- const toggle = () => setBurgerOpen(!burgerOpen);
308
183
  const links = data.map((item) => {
309
184
  const context = props.links[item.label] || { notifications: 0, href: "" };
310
185
  if (context.hidden || props.trial && TRIAL_PAGES.indexOf(item.label) === -1) {
@@ -315,37 +190,32 @@ function Navbar(props) {
315
190
  }
316
191
  return /* @__PURE__ */ React__namespace.createElement(
317
192
  LinksGroup,
318
- __spreadProps$a(__spreadValues$e(__spreadValues$e({
193
+ __spreadProps$9(__spreadValues$d(__spreadValues$d({
319
194
  key: item.label,
320
195
  active: props.active
321
196
  }, item), context), {
322
197
  links: (item.links || []).map((link) => {
323
- return __spreadValues$e(__spreadValues$e({}, link), props.links[`${item.label}/${link.label}`] || { notifications: 0, href: "" });
198
+ return __spreadValues$d(__spreadValues$d({}, link), props.links[`${item.label}/${link.label}`] || { notifications: 0, href: "" });
324
199
  })
325
200
  })
326
201
  );
327
202
  });
328
- return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(core.Navbar, { width: { sm: 300 }, p: "md", className: cx(classes.navbar, { [classes.navHeader]: !burgerOpen }) }, /* @__PURE__ */ React__namespace.createElement(core.Navbar.Section, { className: classes.header }, /* @__PURE__ */ React__namespace.createElement(core.Group, { position: "apart" }, /* @__PURE__ */ React__namespace.createElement(core.Center, null, /* @__PURE__ */ React__namespace.createElement(core.Avatar, { color: "blue", radius: "sm" }, /* @__PURE__ */ React__namespace.createElement("div", { style: { width: 15, marginLeft: "auto", marginRight: "auto" } }, /* @__PURE__ */ React__namespace.createElement(core.Image, { fit: "contain", src: "https://cdn.localcivics.io/brand/l.png" })))), /* @__PURE__ */ React__namespace.createElement(core.Group, { position: "apart" }, /* @__PURE__ */ React__namespace.createElement(core.Code, { sx: { fontWeight: 700 } }, props.version), !!props.trial && /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "violet", radius: "xs" }, "Trial"), /* @__PURE__ */ React__namespace.createElement(core.Burger, { opened: burgerOpen, onClick: toggle, className: classes.burger, size: "sm" })))), /* @__PURE__ */ React__namespace.createElement("div", { className: cx({ [classes.navBody]: !burgerOpen }) }, !props.loading && /* @__PURE__ */ React__namespace.createElement(
329
- UserButton,
330
- {
331
- className: classes.user,
332
- image: props.image,
333
- name: props.name,
334
- email: props.email
335
- }
336
- ), /* @__PURE__ */ React__namespace.createElement(core.Navbar.Section, { grow: true, className: classes.links, component: core.ScrollArea }, /* @__PURE__ */ React__namespace.createElement("div", { className: classes.linksInner }, links)), !props.loading && /* @__PURE__ */ React__namespace.createElement(core.Navbar.Section, { className: classes.footer }, props.trial && /* @__PURE__ */ React__namespace.createElement("a", { href: "#", className: classes.link, onClick: (event) => {
337
- event.preventDefault();
338
- props.onGettingStarted();
339
- } }, /* @__PURE__ */ React__namespace.createElement(icons.IconVideo, { className: classes.linkIcon, stroke: 1.5 }), /* @__PURE__ */ React__namespace.createElement("span", null, "Getting started")), !!props.onSwitchAccounts && /* @__PURE__ */ React__namespace.createElement("a", { href: "#", className: classes.link, onClick: (event) => {
340
- event.preventDefault();
341
- props.onSwitchAccounts && props.onSwitchAccounts();
342
- } }, /* @__PURE__ */ React__namespace.createElement(icons.IconSwitchHorizontal, { className: classes.linkIcon, stroke: 1.5 }), /* @__PURE__ */ React__namespace.createElement("span", null, "Change account")), /* @__PURE__ */ React__namespace.createElement("a", { href: "#", className: classes.link, onClick: (event) => {
343
- event.preventDefault();
344
- props.onLogout();
345
- } }, /* @__PURE__ */ React__namespace.createElement(icons.IconLogout, { className: classes.linkIcon, stroke: 1.5 }), /* @__PURE__ */ React__namespace.createElement("span", null, "Logout"))))));
203
+ return /* @__PURE__ */ React__namespace.createElement("nav", { className: "flex h-full w-[230px] shrink-0 flex-col border-r border-slate-200 bg-white" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "flex items-center justify-between border-b border-slate-100 p-4" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "w-24" }, /* @__PURE__ */ React__namespace.createElement("img", { className: "w-full object-contain", src: "https://cdn.localcivics.io/brand/localcivics.png", alt: "Logo" })), !!props.trial && /* @__PURE__ */ React__namespace.createElement("span", { className: "rounded-full bg-gold-400/15 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, "Trial")), !props.loading && /* @__PURE__ */ React__namespace.createElement(UserButton, { image: props.image, name: props.name, email: props.email }), /* @__PURE__ */ React__namespace.createElement("div", { className: "flex flex-1 flex-col gap-0.5 overflow-y-auto p-2.5" }, links), !props.loading && /* @__PURE__ */ React__namespace.createElement("div", { className: "flex flex-col gap-0.5 border-t border-slate-200 p-2.5" }, props.trial && /* @__PURE__ */ React__namespace.createElement(UtilLink, { label: "Getting started", icon: icons.IconVideo, onClick: props.onGettingStarted }), !!props.onSwitchAccounts && /* @__PURE__ */ React__namespace.createElement(UtilLink, { label: "Change account", icon: icons.IconSwitchHorizontal, onClick: props.onSwitchAccounts }), /* @__PURE__ */ React__namespace.createElement(UtilLink, { label: "Logout", icon: icons.IconLogout, onClick: props.onLogout })));
346
204
  }
205
+ const UtilLink = (props) => {
206
+ const Icon = props.icon;
207
+ return /* @__PURE__ */ React__namespace.createElement(
208
+ "div",
209
+ {
210
+ onClick: props.onClick,
211
+ className: "flex cursor-pointer items-center gap-2.5 rounded-[10px] px-3.5 py-2 text-slate-400 hover:bg-slate-50 hover:text-slate-500"
212
+ },
213
+ /* @__PURE__ */ React__namespace.createElement(Icon, { size: 13, stroke: 1.75 }),
214
+ /* @__PURE__ */ React__namespace.createElement("span", { className: "text-[11.5px]" }, props.label)
215
+ );
216
+ };
347
217
 
348
- const useStyles$s = core.createStyles((theme) => ({
218
+ const useStyles$o = core.createStyles((theme) => ({
349
219
  inner: {
350
220
  paddingTop: theme.spacing.xl,
351
221
  paddingBottom: theme.spacing.xl * 4
@@ -381,7 +251,7 @@ const useStyles$s = core.createStyles((theme) => ({
381
251
  }
382
252
  }));
383
253
  const GettingStarted = (props) => {
384
- const { classes } = useStyles$s();
254
+ const { classes } = useStyles$o();
385
255
  return /* @__PURE__ */ React__namespace.createElement(
386
256
  core.Modal,
387
257
  {
@@ -395,7 +265,7 @@ const GettingStarted = (props) => {
395
265
  );
396
266
  };
397
267
 
398
- const useStyles$r = core.createStyles((theme) => ({
268
+ const useStyles$n = core.createStyles((theme) => ({
399
269
  title: {
400
270
  fontSize: 34,
401
271
  fontWeight: 900,
@@ -436,7 +306,7 @@ const useStyles$r = core.createStyles((theme) => ({
436
306
  }
437
307
  }));
438
308
  const SwitchAccount = (props) => {
439
- const { classes, theme } = useStyles$r();
309
+ const { classes, theme } = useStyles$n();
440
310
  const options = props.accounts.map((a) => {
441
311
  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
312
  });
@@ -453,51 +323,7 @@ const SwitchAccount = (props) => {
453
323
  );
454
324
  };
455
325
 
456
- const useStyles$q = core.createStyles((theme) => ({
457
- root: {
458
- display: "flex",
459
- backgroundImage: `linear-gradient(-60deg, ${theme.colors[theme.primaryColor][4]} 0%, ${theme.colors[theme.primaryColor][7]} 100%)`,
460
- padding: theme.spacing.xl * 1.5,
461
- borderRadius: theme.radius.md
462
- },
463
- title: {
464
- color: theme.white,
465
- textTransform: "uppercase",
466
- fontWeight: 700,
467
- fontSize: theme.fontSizes.sm
468
- },
469
- count: {
470
- color: theme.white,
471
- fontSize: 32,
472
- lineHeight: 1,
473
- fontWeight: 700,
474
- marginBottom: theme.spacing.md,
475
- fontFamily: `Greycliff CF, ${theme.fontFamily}`
476
- },
477
- description: {
478
- color: theme.colors[theme.primaryColor][0],
479
- fontSize: theme.fontSizes.sm,
480
- marginTop: 5
481
- },
482
- stat: {
483
- flex: 1,
484
- "& + &": {
485
- paddingLeft: theme.spacing.xl,
486
- marginLeft: theme.spacing.xl,
487
- borderLeft: `1px solid ${theme.colors[theme.primaryColor][3]}`,
488
- [theme.fn.smallerThan("sm")]: {
489
- paddingLeft: 0,
490
- marginLeft: 0,
491
- borderLeft: 0,
492
- paddingTop: theme.spacing.xl,
493
- marginTop: theme.spacing.xl,
494
- borderTop: `1px solid ${theme.colors[theme.primaryColor][3]}`
495
- }
496
- }
497
- }
498
- }));
499
326
  const StatsGroup = ({ data, footer }) => {
500
- const { classes } = useStyles$q();
501
327
  const stats = data.map((stat) => {
502
328
  const value = (() => {
503
329
  if (stat.unit === "%") {
@@ -506,9 +332,9 @@ const StatsGroup = ({ data, footer }) => {
506
332
  return stat.value;
507
333
  })();
508
334
  const safeValue = Number.isFinite(value) ? value : 0;
509
- return /* @__PURE__ */ React__namespace.createElement("div", { key: stat.title, className: classes.stat }, /* @__PURE__ */ React__namespace.createElement(core.Text, { className: classes.count }, safeValue.toLocaleString(), stat.unit), /* @__PURE__ */ React__namespace.createElement(core.Text, { className: classes.title }, stat.title));
335
+ return /* @__PURE__ */ React__namespace.createElement("div", { key: stat.title }, /* @__PURE__ */ React__namespace.createElement("div", { className: "text-3xl font-black text-white" }, safeValue.toLocaleString(), stat.unit), /* @__PURE__ */ React__namespace.createElement("div", { className: "mt-1.5 text-[11px] font-bold uppercase tracking-wide text-white/70" }, stat.title));
510
336
  });
511
- return /* @__PURE__ */ React__namespace.createElement("div", { className: classes.root }, stats, footer);
337
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "flex flex-wrap gap-x-10 gap-y-4 rounded-2xl bg-gradient-to-br from-dark-blue-600 via-dark-blue-400 to-sky-blue-400 px-8 py-6" }, stats, footer);
512
338
  };
513
339
 
514
340
  const Tabs = (props) => {
@@ -517,7 +343,7 @@ const Tabs = (props) => {
517
343
  return /* @__PURE__ */ React__namespace.createElement(core.Tabs, { value: props.value, onTabChange: props.onChange }, /* @__PURE__ */ React__namespace.createElement(core.Tabs.List, null, tabs));
518
344
  };
519
345
 
520
- const useStyles$p = core.createStyles((theme) => ({
346
+ const useStyles$m = core.createStyles((theme) => ({
521
347
  button: {
522
348
  borderTopRightRadius: 0,
523
349
  borderBottomRightRadius: 0,
@@ -531,8 +357,8 @@ const useStyles$p = core.createStyles((theme) => ({
531
357
  borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
532
358
  }
533
359
  }));
534
- const SplitButton$5 = (props) => {
535
- const { classes, theme } = useStyles$p();
360
+ const SplitButton$4 = (props) => {
361
+ const { classes, theme } = useStyles$m();
536
362
  theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
537
363
  return /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(
538
364
  core.Button,
@@ -560,7 +386,7 @@ const SplitButton$5 = (props) => {
560
386
  ));
561
387
  };
562
388
 
563
- const useStyles$o = core.createStyles((theme) => ({
389
+ const useStyles$l = core.createStyles((theme) => ({
564
390
  wrapper: {
565
391
  display: "flex",
566
392
  alignItems: "center",
@@ -611,7 +437,7 @@ const useStyles$o = core.createStyles((theme) => ({
611
437
  }
612
438
  }));
613
439
  const PlaceholderBanner = (props) => {
614
- const { classes } = useStyles$o();
440
+ const { classes } = useStyles$l();
615
441
  const title = props.title || "Nothing to display";
616
442
  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
443
  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 }));
@@ -663,28 +489,28 @@ function useSortableData(items, config = { key: "", direction: null }) {
663
489
  return { items: sortedItems, requestSort, sortConfig };
664
490
  }
665
491
 
666
- var __defProp$d = Object.defineProperty;
667
- var __defProps$9 = Object.defineProperties;
668
- var __getOwnPropDescs$9 = Object.getOwnPropertyDescriptors;
669
- var __getOwnPropSymbols$d = Object.getOwnPropertySymbols;
670
- var __hasOwnProp$d = Object.prototype.hasOwnProperty;
671
- var __propIsEnum$d = Object.prototype.propertyIsEnumerable;
672
- var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
673
- var __spreadValues$d = (a, b) => {
492
+ var __defProp$c = Object.defineProperty;
493
+ var __defProps$8 = Object.defineProperties;
494
+ var __getOwnPropDescs$8 = Object.getOwnPropertyDescriptors;
495
+ var __getOwnPropSymbols$c = Object.getOwnPropertySymbols;
496
+ var __hasOwnProp$c = Object.prototype.hasOwnProperty;
497
+ var __propIsEnum$c = Object.prototype.propertyIsEnumerable;
498
+ var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
499
+ var __spreadValues$c = (a, b) => {
674
500
  for (var prop in b || (b = {}))
675
- if (__hasOwnProp$d.call(b, prop))
676
- __defNormalProp$d(a, prop, b[prop]);
677
- if (__getOwnPropSymbols$d)
678
- for (var prop of __getOwnPropSymbols$d(b)) {
679
- if (__propIsEnum$d.call(b, prop))
680
- __defNormalProp$d(a, prop, b[prop]);
501
+ if (__hasOwnProp$c.call(b, prop))
502
+ __defNormalProp$c(a, prop, b[prop]);
503
+ if (__getOwnPropSymbols$c)
504
+ for (var prop of __getOwnPropSymbols$c(b)) {
505
+ if (__propIsEnum$c.call(b, prop))
506
+ __defNormalProp$c(a, prop, b[prop]);
681
507
  }
682
508
  return a;
683
509
  };
684
- var __spreadProps$9 = (a, b) => __defProps$9(a, __getOwnPropDescs$9(b));
510
+ var __spreadProps$8 = (a, b) => __defProps$8(a, __getOwnPropDescs$8(b));
685
511
  function Table$k(props) {
686
512
  const preparedItems = React__namespace.useMemo(() => {
687
- return props.items.map((item) => __spreadProps$9(__spreadValues$d({}, item), {
513
+ return props.items.map((item) => __spreadProps$8(__spreadValues$c({}, item), {
688
514
  status: item.isComplete ? 1 : 0
689
515
  }));
690
516
  }, [props.items]);
@@ -781,7 +607,7 @@ function Table$j(props) {
781
607
  ));
782
608
  }
783
609
 
784
- const useStyles$n = core.createStyles((theme) => ({
610
+ const useStyles$k = core.createStyles((theme) => ({
785
611
  title: {
786
612
  fontSize: 34,
787
613
  fontWeight: 900,
@@ -794,7 +620,7 @@ const useStyles$n = core.createStyles((theme) => ({
794
620
  }
795
621
  }));
796
622
  const Badge = (props) => {
797
- const { classes } = useStyles$n();
623
+ const { classes } = useStyles$k();
798
624
  const [tab, setTab] = React.useState("lessons");
799
625
  const numberOfStudents = props.students.length;
800
626
  const numberOfBadges = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length : 0;
@@ -808,7 +634,7 @@ const Badge = (props) => {
808
634
  },
809
635
  "Back"
810
636
  )), /* @__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")), !props.trial && /* @__PURE__ */ React__namespace.createElement(core.Stack, { ml: "auto" }, /* @__PURE__ */ React__namespace.createElement(
811
- SplitButton$5,
637
+ SplitButton$4,
812
638
  {
813
639
  href: props.href,
814
640
  onCopyLinkClick: props.onCopyLinkClick,
@@ -861,65 +687,34 @@ const Badge = (props) => {
861
687
  };
862
688
 
863
689
  function Table$i(props) {
690
+ if (props.loading) {
691
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "text-sm text-slate-400" }, "Loading\u2026");
692
+ }
864
693
  if (props.items.length === 0) {
865
- return /* @__PURE__ */ React__namespace.createElement(
866
- PlaceholderBanner,
867
- {
868
- title: "No badges to display",
869
- description: "We don't have any badges to show you just yet.",
870
- loading: props.loading,
871
- icon: "badges"
872
- }
873
- );
694
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "rounded-xl border border-slate-200 bg-white p-8 text-center text-sm text-slate-400 shadow-sm" }, "No badges to display.");
874
695
  }
875
- const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.badgeId }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(
876
- core.UnstyledButton,
696
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm" }, props.items.map((row, i) => /* @__PURE__ */ React__namespace.createElement(
697
+ reactRouterDom.Link,
877
698
  {
878
- component: reactRouterDom.Link,
699
+ key: row.badgeId,
879
700
  to: row.href,
880
- sx: (theme) => ({
881
- display: "block",
882
- width: "100%",
883
- padding: theme.spacing.md,
884
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
885
- "&:hover": {
886
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.colors.gray[1]
887
- }
888
- })
701
+ className: `block px-5 py-4 no-underline hover:bg-slate-50 ${i < props.items.length - 1 ? "border-b border-slate-100" : ""}`
889
702
  },
890
- /* @__PURE__ */ React__namespace.createElement(core.Group, null, /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xs", color: "dimmed" }, row.description)))
891
- ))));
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)));
703
+ /* @__PURE__ */ React__namespace.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, row.name),
704
+ row.description && /* @__PURE__ */ React__namespace.createElement("div", { className: "mt-1 text-xs leading-relaxed text-slate-500" }, row.description)
705
+ )));
893
706
  }
894
707
 
895
- const useStyles$m = core.createStyles((theme) => ({
896
- title: {
897
- fontSize: 34,
898
- fontWeight: 900,
899
- [theme.fn.smallerThan("sm")]: {
900
- fontSize: 24
901
- }
902
- },
903
- description: {
904
- maxWidth: 600
905
- }
906
- }));
907
708
  const Badges = (props) => {
908
- const { classes } = useStyles$m();
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
- core.Autocomplete,
709
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "mx-auto flex max-w-4xl flex-col gap-5 px-4 py-8" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React__namespace.createElement("h1", { className: "text-2xl font-extrabold tracking-tight text-dark-blue-400" }, "Badges and micro-credentials"), /* @__PURE__ */ React__namespace.createElement("p", { className: "text-sm text-slate-500" }, "Project-sized skills acquisition and standards alignment.")), /* @__PURE__ */ React__namespace.createElement("div", { className: "flex items-center gap-2.5 rounded-xl border border-slate-200 bg-white px-4 py-3 shadow-sm" }, /* @__PURE__ */ React__namespace.createElement(icons.IconSearch, { size: 15, stroke: 1.75, className: "text-slate-400" }), /* @__PURE__ */ React__namespace.createElement(
710
+ "input",
911
711
  {
712
+ type: "text",
912
713
  placeholder: "Search for a badge that fits your needs",
913
- data: props.badges.map((item) => item.name),
914
- onChange: props.onAutocompleteChange
714
+ onChange: (e) => props.onAutocompleteChange(e.target.value),
715
+ className: "flex-1 border-none bg-transparent text-sm text-dark-blue-400 outline-none placeholder:text-slate-400"
915
716
  }
916
- ), /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(
917
- Table$i,
918
- {
919
- loading: props.loading,
920
- items: props.badges
921
- }
922
- ))));
717
+ )), /* @__PURE__ */ React__namespace.createElement(Table$i, { loading: props.loading, items: props.badges }));
923
718
  };
924
719
 
925
720
  function Table$h(props) {
@@ -1098,154 +893,69 @@ const Dashboard = (props) => {
1098
893
  {
1099
894
  loading: props.loading,
1100
895
  items: props.lessons,
1101
- onClick: props.onLessonClick
1102
- }
1103
- ), tab === "students" && /* @__PURE__ */ React__namespace.createElement(
1104
- Table$h,
1105
- {
1106
- loading: props.loading,
1107
- items: props.students,
1108
- onViewProfile: props.onViewStudentProfile
1109
- }
1110
- )))))));
1111
- };
1112
-
1113
- const SplitButton$4 = (props) => {
1114
- return /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(
1115
- core.Button,
1116
- {
1117
- leftIcon: /* @__PURE__ */ React__namespace.createElement(icons.IconPlaylistAdd, { size: 14 }),
1118
- onClick: props.onAddMembersClick
1119
- },
1120
- "Add students"
1121
- ), /* @__PURE__ */ React__namespace.createElement(
1122
- core.Button,
1123
- {
1124
- leftIcon: /* @__PURE__ */ React__namespace.createElement(icons.IconClipboardCopy, { size: 14 }),
1125
- onClick: props.onCopyClassLinkClick
1126
- },
1127
- "Copy link"
1128
- ), /* @__PURE__ */ React__namespace.createElement(
1129
- core.Button,
1130
- {
1131
- leftIcon: /* @__PURE__ */ React__namespace.createElement(icons.IconTableExport, { size: 14 }),
1132
- onClick: props.onExportDataClick
1133
- },
1134
- "Export data (.csv)"
1135
- ));
1136
- };
1137
-
1138
- var __defProp$c = Object.defineProperty;
1139
- var __defProps$8 = Object.defineProperties;
1140
- var __getOwnPropDescs$8 = Object.getOwnPropertyDescriptors;
1141
- var __getOwnPropSymbols$c = Object.getOwnPropertySymbols;
1142
- var __hasOwnProp$c = Object.prototype.hasOwnProperty;
1143
- var __propIsEnum$c = Object.prototype.propertyIsEnumerable;
1144
- var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1145
- var __spreadValues$c = (a, b) => {
1146
- for (var prop in b || (b = {}))
1147
- if (__hasOwnProp$c.call(b, prop))
1148
- __defNormalProp$c(a, prop, b[prop]);
1149
- if (__getOwnPropSymbols$c)
1150
- for (var prop of __getOwnPropSymbols$c(b)) {
1151
- if (__propIsEnum$c.call(b, prop))
1152
- __defNormalProp$c(a, prop, b[prop]);
1153
- }
1154
- return a;
1155
- };
1156
- var __spreadProps$8 = (a, b) => __defProps$8(a, __getOwnPropDescs$8(b));
1157
- function Table$c(props) {
1158
- const preparedItems = React__namespace.useMemo(() => {
1159
- return props.items.map((item) => __spreadProps$8(__spreadValues$c({}, item), {
1160
- fullName: item.givenName && item.familyName ? `${item.givenName} ${item.familyName}`.toLowerCase() : item.email.toLowerCase()
1161
- }));
1162
- }, [props.items]);
1163
- console.groupEnd();
1164
- const { items: sortedItems, requestSort, sortConfig } = useSortableData(preparedItems);
1165
- if (props.items.length === 0) {
1166
- return /* @__PURE__ */ React__namespace.createElement(
1167
- PlaceholderBanner,
1168
- {
1169
- title: "No members to display",
1170
- description: "You have not rostered any students yet.",
1171
- loading: props.loading,
1172
- icon: "groups"
1173
- }
1174
- );
1175
- }
1176
- const sortStatus = {
1177
- columnAccessor: sortConfig.key,
1178
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
1179
- };
1180
- const openDeleteModal = (student) => modals.openConfirmModal({
1181
- title: `Remove "${student.givenName && student.familyName ? `${student.givenName} ${student.familyName}` : student.email}" from this class?`,
1182
- centered: true,
1183
- children: /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm" }, "Click confirm if you want to remove the student from this specific class. This will NOT remove the student from the Tech Platform."),
1184
- labels: { confirm: "Remove Student", cancel: "Cancel" },
1185
- confirmProps: { color: "red" },
1186
- onConfirm: () => props.onDelete && props.onDelete(student)
1187
- });
1188
- return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea, null, /* @__PURE__ */ React__namespace.createElement(
1189
- mantineDatatable.DataTable,
896
+ onClick: props.onLessonClick
897
+ }
898
+ ), tab === "students" && /* @__PURE__ */ React__namespace.createElement(
899
+ Table$h,
1190
900
  {
1191
- verticalSpacing: 20,
1192
- sx: { minWidth: 700 },
1193
- highlightOnHover: true,
1194
- striped: true,
1195
- records: sortedItems,
1196
- idAccessor: "email",
1197
- sortStatus,
1198
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
1199
- columns: [
1200
- {
1201
- accessor: "fullName",
1202
- title: "Name",
1203
- sortable: true,
1204
- render: (row) => /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { component: reactRouterDom.Link, to: row.href }, /* @__PURE__ */ React__namespace.createElement(core.Group, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(core.Avatar, { size: 40, src: row.avatar, radius: 40 }), /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", weight: 500 }, row.givenName && row.familyName ? `${row.givenName} ${row.familyName}` : row.email), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xs", color: "dimmed" }, row.email))))
1205
- },
1206
- {
1207
- accessor: "isAdmin",
1208
- title: "Role",
1209
- sortable: true,
1210
- render: (row) => /* @__PURE__ */ React__namespace.createElement(core.Box, { maw: 150 }, /* @__PURE__ */ React__namespace.createElement(
1211
- core.Select,
1212
- {
1213
- size: "sm",
1214
- disabled: row.readonly,
1215
- value: row.isAdmin ? "educator" : "student",
1216
- onChange: (value) => props.onRoleChange && props.onRoleChange(row, value),
1217
- data: [
1218
- { label: "Student", value: "student" },
1219
- { label: "Educator", value: "educator" }
1220
- ]
1221
- }
1222
- ))
1223
- },
1224
- {
1225
- accessor: "badgesEarned",
1226
- title: "Badges Earned",
1227
- sortable: true
1228
- },
901
+ loading: props.loading,
902
+ items: props.students,
903
+ onViewProfile: props.onViewStudentProfile
904
+ }
905
+ )))))));
906
+ };
907
+
908
+ const openDeleteModal = (student, onDelete) => modals.openConfirmModal({
909
+ title: `Remove "${student.givenName && student.familyName ? `${student.givenName} ${student.familyName}` : student.email}" from this class?`,
910
+ centered: true,
911
+ children: /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm" }, "Click confirm if you want to remove the student from this specific class. This will NOT remove the student from the Tech Platform."),
912
+ labels: { confirm: "Remove Student", cancel: "Cancel" },
913
+ confirmProps: { color: "red" },
914
+ onConfirm: () => onDelete(student)
915
+ });
916
+ function Table$c(props) {
917
+ if (props.loading) {
918
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "text-sm text-slate-400" }, "Loading\u2026");
919
+ }
920
+ if (props.items.length === 0) {
921
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "rounded-xl border border-slate-200 bg-white p-8 text-center text-sm text-slate-400 shadow-sm" }, "You have not rostered any students yet.");
922
+ }
923
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "grid grid-cols-[2.2fr_1.2fr_1fr_1.2fr_1fr_0.6fr] gap-3 border-b border-slate-100 px-5 py-3 text-[10px] font-bold uppercase tracking-wide text-slate-400" }, /* @__PURE__ */ React__namespace.createElement("div", null, "Name"), /* @__PURE__ */ React__namespace.createElement("div", null, "Role"), /* @__PURE__ */ React__namespace.createElement("div", null, "Badges Earned"), /* @__PURE__ */ React__namespace.createElement("div", null, "Lessons Completed"), /* @__PURE__ */ React__namespace.createElement("div", null, "Account Created?"), /* @__PURE__ */ React__namespace.createElement("div", null)), props.items.map((row, i) => {
924
+ var _a, _b;
925
+ const name = row.givenName && row.familyName ? `${row.givenName} ${row.familyName}` : row.email;
926
+ const initials = (((_a = row.givenName) == null ? void 0 : _a[0]) || row.email[0] || "?") + (((_b = row.familyName) == null ? void 0 : _b[0]) || "");
927
+ return /* @__PURE__ */ React__namespace.createElement(
928
+ "div",
929
+ {
930
+ key: row.email,
931
+ className: `grid grid-cols-[2.2fr_1.2fr_1fr_1.2fr_1fr_0.6fr] items-center gap-3 px-5 py-3.5 ${i < props.items.length - 1 ? "border-b border-slate-100" : ""}`
932
+ },
933
+ /* @__PURE__ */ React__namespace.createElement(reactRouterDom.Link, { to: row.href, className: "flex min-w-0 items-center gap-2.5 no-underline" }, row.avatar ? /* @__PURE__ */ React__namespace.createElement("img", { className: "h-8 w-8 shrink-0 rounded-full object-cover", src: row.avatar, alt: name }) : /* @__PURE__ */ React__namespace.createElement("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-mint-400/20 text-[10px] font-bold text-dark-blue-400" }, initials.toUpperCase()), /* @__PURE__ */ React__namespace.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "truncate text-xs font-bold text-dark-blue-400" }, name), /* @__PURE__ */ React__namespace.createElement("div", { className: "truncate text-[10.5px] text-slate-400" }, row.email))),
934
+ /* @__PURE__ */ React__namespace.createElement(
935
+ "select",
1229
936
  {
1230
- accessor: "lessonsCompleted",
1231
- title: "Lessons Completed",
1232
- sortable: true
937
+ disabled: row.readonly,
938
+ value: row.isAdmin ? "educator" : "student",
939
+ onChange: (e) => props.onRoleChange && props.onRoleChange(row, e.target.value),
940
+ className: "w-fit rounded-lg border border-slate-200 bg-white px-2.5 py-1.5 text-xs font-medium text-slate-600 disabled:opacity-50"
1233
941
  },
942
+ /* @__PURE__ */ React__namespace.createElement("option", { value: "student" }, "Student"),
943
+ /* @__PURE__ */ React__namespace.createElement("option", { value: "educator" }, "Educator")
944
+ ),
945
+ /* @__PURE__ */ React__namespace.createElement("div", { className: "text-xs font-bold text-dark-blue-400" }, row.badgesEarned),
946
+ /* @__PURE__ */ React__namespace.createElement("div", { className: "text-xs font-bold text-dark-blue-400" }, row.lessonsCompleted),
947
+ /* @__PURE__ */ React__namespace.createElement("div", null, row.hasAccount && /* @__PURE__ */ React__namespace.createElement(icons.IconCheck, { size: 16, stroke: 3, className: "text-mint-400" })),
948
+ /* @__PURE__ */ React__namespace.createElement("div", null, !row.readonly && !!props.onDelete && /* @__PURE__ */ React__namespace.createElement(
949
+ "button",
1234
950
  {
1235
- accessor: "hasAccount",
1236
- title: "Account Created?",
1237
- sortable: true,
1238
- render: (row) => row.hasAccount ? /* @__PURE__ */ React__namespace.createElement(icons.IconCheck, { color: "green" }) : null
951
+ type: "button",
952
+ onClick: () => openDeleteModal(row, props.onDelete),
953
+ className: "flex h-7 w-7 items-center justify-center rounded-md text-slate-300 hover:bg-red-50 hover:text-red-500"
1239
954
  },
1240
- {
1241
- accessor: "actions",
1242
- title: "",
1243
- textAlignment: "right",
1244
- render: (row) => /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0, position: "right" }, !row.readonly && !!props.onDelete && /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { color: "red", onClick: () => openDeleteModal(row) }, /* @__PURE__ */ React__namespace.createElement(icons.IconTrash, { size: 16, stroke: 1.5 })))
1245
- }
1246
- ]
1247
- }
1248
- ));
955
+ /* @__PURE__ */ React__namespace.createElement(icons.IconTrash, { size: 14, stroke: 1.75 })
956
+ ))
957
+ );
958
+ }));
1249
959
  }
1250
960
 
1251
961
  var __defProp$b = Object.defineProperty;
@@ -1267,112 +977,46 @@ var __spreadValues$b = (a, b) => {
1267
977
  return a;
1268
978
  };
1269
979
  var __spreadProps$7 = (a, b) => __defProps$7(a, __getOwnPropDescs$7(b));
1270
- const useStyles$l = core.createStyles((theme) => ({
1271
- title: {
1272
- fontSize: 34,
1273
- fontWeight: 900,
1274
- [theme.fn.smallerThan("sm")]: {
1275
- fontSize: 24
1276
- }
1277
- },
1278
- description: {
1279
- maxWidth: 600
1280
- },
1281
- autocomplete: {
1282
- maxWidth: 400
1283
- },
1284
- wrapper: {
1285
- position: "relative",
1286
- marginBottom: 30
1287
- },
1288
- dropzone: {
1289
- borderWidth: 1,
1290
- paddingBottom: 50
1291
- },
1292
- icon: {
1293
- color: theme.colorScheme === "dark" ? theme.colors.dark[3] : theme.colors.gray[4]
1294
- },
1295
- control: {
1296
- position: "absolute",
1297
- width: 250,
1298
- left: "calc(50% - 125px)",
1299
- bottom: -20
1300
- }
1301
- }));
1302
980
  const Class = (props) => {
1303
- const { classes } = useStyles$l();
1304
- const form$1 = form.useForm({
1305
- initialValues: {
1306
- classId: "",
1307
- userId: "",
1308
- email: "",
1309
- givenName: "",
1310
- familyName: "",
1311
- avatar: "",
1312
- role: "",
1313
- readonly: false,
1314
- lastActivity: null,
1315
- hasAccount: false,
1316
- lessonsCompleted: 0,
1317
- badgesEarned: 0,
1318
- href: "",
1319
- isAdmin: false
1320
- },
1321
- validate: {
1322
- email: (value) => /^\S+@\S+$/.test(value) && props.members.filter((u) => u.email === value).length === 0 ? null : "Invalid email"
1323
- }
1324
- });
1325
981
  const [opened, setOpened] = React.useState(false);
1326
982
  return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(
1327
983
  core.Drawer,
1328
984
  {
1329
985
  opened,
1330
986
  onClose: () => setOpened(false),
1331
- title: /* @__PURE__ */ React__namespace.createElement(core.Title, { size: "h5" }, "Add students"),
987
+ title: "Add students",
1332
988
  padding: "xl",
1333
989
  size: "xl"
1334
990
  },
1335
- /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(DropzoneButton$1, __spreadProps$7(__spreadValues$b({}, props), { close: () => setOpened(false) })), /* @__PURE__ */ React__namespace.createElement(core.Divider, { label: "or", labelPosition: "center", my: "md", variant: "dashed" }), /* @__PURE__ */ React__namespace.createElement("form", { onSubmit: form$1.onSubmit(() => {
1336
- const values = form$1.values;
1337
- form$1.reset();
1338
- setOpened(false);
1339
- props.onCreateMembers && props.onCreateMembers([values]);
1340
- }) }, /* @__PURE__ */ React__namespace.createElement(core.Stack, null, /* @__PURE__ */ React__namespace.createElement(
1341
- core.TextInput,
1342
- __spreadValues$b({
1343
- withAsterisk: true,
1344
- label: "Email",
1345
- placeholder: "Email"
1346
- }, form$1.getInputProps("email"))
1347
- ), /* @__PURE__ */ React__namespace.createElement(core.Group, { grow: true }, /* @__PURE__ */ React__namespace.createElement(
1348
- core.TextInput,
1349
- __spreadValues$b({
1350
- label: "Given name",
1351
- placeholder: "Given name"
1352
- }, form$1.getInputProps("givenName"))
1353
- ), /* @__PURE__ */ React__namespace.createElement(
1354
- core.TextInput,
1355
- __spreadValues$b({
1356
- label: "Family name",
1357
- placeholder: "Family name"
1358
- }, form$1.getInputProps("familyName"))
1359
- )), /* @__PURE__ */ React__namespace.createElement(core.Button, { type: "submit", fullWidth: true, mt: "md" }, "Submit"))))
1360
- ), /* @__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.UnstyledButton, { onClick: props.onBackClick }, /* @__PURE__ */ React__namespace.createElement(
1361
- core.Badge,
991
+ /* @__PURE__ */ React__namespace.createElement(DropzoneButton$1, __spreadProps$7(__spreadValues$b({}, props), { close: () => setOpened(false) }))
992
+ ), /* @__PURE__ */ React__namespace.createElement("div", { className: "mx-auto flex max-w-5xl flex-col gap-5 px-4 py-8" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "flex flex-wrap items-start justify-between gap-4" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React__namespace.createElement("div", { onClick: props.onBackClick, className: "flex w-max cursor-pointer items-center gap-1 text-xs font-bold text-sky-blue-400" }, /* @__PURE__ */ React__namespace.createElement(icons.IconArrowLeft, { size: 13, stroke: 2.5 }), "Back"), /* @__PURE__ */ React__namespace.createElement("h1", { className: "text-2xl font-extrabold tracking-tight text-dark-blue-400" }, props.displayName || "Class"), /* @__PURE__ */ React__namespace.createElement("p", { className: "text-sm text-slate-500" }, props.description || "No description")), !props.loading && /* @__PURE__ */ React__namespace.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React__namespace.createElement(
993
+ "button",
1362
994
  {
1363
- variant: "filled",
1364
- leftSection: /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React__namespace.createElement(icons.IconArrowLeft, { size: 14 })),
1365
- size: "lg"
995
+ type: "button",
996
+ onClick: () => setOpened(true),
997
+ className: "flex items-center gap-1.5 rounded-lg border border-slate-200 bg-white px-3.5 py-2 text-xs font-bold text-slate-600 hover:bg-slate-50"
1366
998
  },
1367
- "Back"
1368
- )), /* @__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(
1369
- SplitButton$4,
999
+ /* @__PURE__ */ React__namespace.createElement(icons.IconPlus, { size: 13, stroke: 2 }),
1000
+ "Add students"
1001
+ ), /* @__PURE__ */ React__namespace.createElement(
1002
+ "button",
1370
1003
  {
1371
- onAddMembersClick: () => setOpened(true),
1372
- onCopyClassLinkClick: props.onCopyLinkClick,
1373
- onExportDataClick: props.onExportDataClick
1374
- }
1375
- ))), /* @__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, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
1004
+ type: "button",
1005
+ onClick: props.onCopyLinkClick,
1006
+ className: "flex items-center gap-1.5 rounded-lg border border-slate-200 bg-white px-3.5 py-2 text-xs font-bold text-slate-600 hover:bg-slate-50"
1007
+ },
1008
+ /* @__PURE__ */ React__namespace.createElement(icons.IconLink, { size: 13, stroke: 2 }),
1009
+ "Copy class link"
1010
+ ), /* @__PURE__ */ React__namespace.createElement(
1011
+ "button",
1012
+ {
1013
+ type: "button",
1014
+ onClick: props.onExportDataClick,
1015
+ className: "flex items-center gap-1.5 rounded-lg bg-gradient-to-r from-gold-400 to-[#f5c300] px-3.5 py-2 text-xs font-bold text-dark-blue-400 shadow-[0_3px_12px_rgba(255,212,77,0.35)]"
1016
+ },
1017
+ /* @__PURE__ */ React__namespace.createElement(icons.IconDownload, { size: 13, stroke: 2 }),
1018
+ "Export data (.csv)"
1019
+ ))), /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
1376
1020
  {
1377
1021
  title: "# OF STUDENTS",
1378
1022
  value: props.members.filter((a) => !a.isAdmin).length
@@ -1398,10 +1042,30 @@ const Class = (props) => {
1398
1042
  onDelete: props.onDeleteMember,
1399
1043
  onRoleChange: props.onChangeUserRole
1400
1044
  }
1401
- ))))));
1045
+ )));
1402
1046
  };
1403
1047
  const DropzoneButton$1 = (props) => {
1404
- const { classes, theme } = useStyles$l();
1048
+ const form$1 = form.useForm({
1049
+ initialValues: {
1050
+ classId: "",
1051
+ userId: "",
1052
+ email: "",
1053
+ givenName: "",
1054
+ familyName: "",
1055
+ avatar: "",
1056
+ role: "",
1057
+ readonly: false,
1058
+ lastActivity: null,
1059
+ hasAccount: false,
1060
+ lessonsCompleted: 0,
1061
+ badgesEarned: 0,
1062
+ href: "",
1063
+ isAdmin: false
1064
+ },
1065
+ validate: {
1066
+ email: (value) => /^\S+@\S+$/.test(value) && props.members.filter((u) => u.email === value).length === 0 ? null : "Invalid email"
1067
+ }
1068
+ });
1405
1069
  const openRef = React__namespace.useRef(null);
1406
1070
  const [loading, setLoading] = React__namespace.useState(false);
1407
1071
  const onDrop = React__namespace.useCallback((acceptedFiles) => {
@@ -1422,29 +1086,59 @@ const DropzoneButton$1 = (props) => {
1422
1086
  });
1423
1087
  });
1424
1088
  }, []);
1425
- return /* @__PURE__ */ React__namespace.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React__namespace.createElement(
1089
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "flex flex-col gap-4" }, /* @__PURE__ */ React__namespace.createElement(
1426
1090
  dropzone.Dropzone,
1427
1091
  {
1428
1092
  loading,
1429
1093
  openRef,
1430
1094
  onDrop,
1431
- className: classes.dropzone,
1432
- radius: "md",
1433
1095
  accept: [dropzone.MIME_TYPES.csv],
1434
1096
  maxSize: 5 * 1024 ** 2
1435
1097
  },
1436
- /* @__PURE__ */ React__namespace.createElement("div", { style: { pointerEvents: "none" } }, /* @__PURE__ */ React__namespace.createElement(core.Group, { position: "center" }, /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Accept, null, /* @__PURE__ */ React__namespace.createElement(icons.IconDownload, { size: 50, color: theme.colors[theme.primaryColor][6], stroke: 1.5 })), /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Reject, null, /* @__PURE__ */ React__namespace.createElement(icons.IconX, { size: 50, color: theme.colors.red[6], stroke: 1.5 })), /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Idle, null, /* @__PURE__ */ React__namespace.createElement(
1437
- icons.IconCloudUpload,
1438
- {
1439
- size: 50,
1440
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
1441
- stroke: 1.5
1442
- }
1443
- ))), /* @__PURE__ */ React__namespace.createElement(core.Text, { align: "center", weight: 700, size: "lg", mt: "xl" }, /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Accept, null, "Drop files here"), /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Reject, null, "Csv file less than 5mb"), /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Idle, null, "Upload multiple")), /* @__PURE__ */ React__namespace.createElement(core.Text, { align: "center", size: "sm", mt: "xs", color: "dimmed" }, "Drag'n'drop files here to upload. We can accept only ", /* @__PURE__ */ React__namespace.createElement("i", null, ".csv"), " files that are less than 5mb in size."))
1444
- ), /* @__PURE__ */ React__namespace.createElement(core.Button, { className: classes.control, size: "md", radius: "xl", onClick: () => {
1445
- var _a;
1446
- return (_a = openRef.current) == null ? void 0 : _a.call(openRef);
1447
- } }, "Select file"));
1098
+ /* @__PURE__ */ React__namespace.createElement("div", { style: { pointerEvents: "none" } }, /* @__PURE__ */ React__namespace.createElement(core.Group, { position: "center" }, /* @__PURE__ */ React__namespace.createElement(icons.IconCloudUpload, { size: 50, stroke: 1.5 })), /* @__PURE__ */ React__namespace.createElement("p", { className: "mt-6 text-center text-lg font-bold text-dark-blue-400" }, "Upload multiple"), /* @__PURE__ */ React__namespace.createElement("p", { className: "mt-2 text-center text-sm text-slate-400" }, "Drag'n'drop files here to upload. We can accept only ", /* @__PURE__ */ React__namespace.createElement("i", null, ".csv"), " files that are less than 5mb in size."))
1099
+ ), /* @__PURE__ */ React__namespace.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React__namespace.createElement(
1100
+ "button",
1101
+ {
1102
+ type: "button",
1103
+ onClick: () => {
1104
+ var _a;
1105
+ return (_a = openRef.current) == null ? void 0 : _a.call(openRef);
1106
+ },
1107
+ className: "rounded-full bg-dark-blue-400 px-6 py-2.5 text-xs font-bold text-white"
1108
+ },
1109
+ "Select file"
1110
+ )), /* @__PURE__ */ React__namespace.createElement(core.Divider, { label: "or", labelPosition: "center", my: "md", variant: "dashed" }), /* @__PURE__ */ React__namespace.createElement("form", { onSubmit: form$1.onSubmit(() => {
1111
+ const values = form$1.values;
1112
+ form$1.reset();
1113
+ props.close();
1114
+ props.onCreateMembers && props.onCreateMembers([values]);
1115
+ }) }, /* @__PURE__ */ React__namespace.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React__namespace.createElement(
1116
+ core.TextInput,
1117
+ __spreadValues$b({
1118
+ withAsterisk: true,
1119
+ label: "Email",
1120
+ placeholder: "Email"
1121
+ }, form$1.getInputProps("email"))
1122
+ ), /* @__PURE__ */ React__namespace.createElement(core.Group, { grow: true }, /* @__PURE__ */ React__namespace.createElement(
1123
+ core.TextInput,
1124
+ __spreadValues$b({
1125
+ label: "Given name",
1126
+ placeholder: "Given name"
1127
+ }, form$1.getInputProps("givenName"))
1128
+ ), /* @__PURE__ */ React__namespace.createElement(
1129
+ core.TextInput,
1130
+ __spreadValues$b({
1131
+ label: "Family name",
1132
+ placeholder: "Family name"
1133
+ }, form$1.getInputProps("familyName"))
1134
+ )), /* @__PURE__ */ React__namespace.createElement(
1135
+ "button",
1136
+ {
1137
+ type: "submit",
1138
+ className: "mt-2 rounded-lg bg-dark-blue-400 px-4 py-2.5 text-xs font-bold text-white"
1139
+ },
1140
+ "Submit"
1141
+ ))));
1448
1142
  };
1449
1143
 
1450
1144
  function Table$b(props) {
@@ -1529,7 +1223,7 @@ var __spreadValues$a = (a, b) => {
1529
1223
  }
1530
1224
  return a;
1531
1225
  };
1532
- const useStyles$k = core.createStyles((theme) => ({
1226
+ const useStyles$j = core.createStyles((theme) => ({
1533
1227
  title: {
1534
1228
  fontSize: 34,
1535
1229
  fontWeight: 900,
@@ -1542,7 +1236,7 @@ const useStyles$k = core.createStyles((theme) => ({
1542
1236
  }
1543
1237
  }));
1544
1238
  const Classes = (props) => {
1545
- const { classes } = useStyles$k();
1239
+ const { classes } = useStyles$j();
1546
1240
  const form$1 = form.useForm({
1547
1241
  initialValues: {
1548
1242
  classId: "",
@@ -1613,7 +1307,7 @@ const Classes = (props) => {
1613
1307
  ))))));
1614
1308
  };
1615
1309
 
1616
- const useStyles$j = core.createStyles((theme) => ({
1310
+ const useStyles$i = core.createStyles((theme) => ({
1617
1311
  title: {
1618
1312
  fontSize: 34,
1619
1313
  fontWeight: 900,
@@ -1627,7 +1321,7 @@ const useStyles$j = core.createStyles((theme) => ({
1627
1321
  }
1628
1322
  }));
1629
1323
  const UserInfo = (props) => {
1630
- const { classes } = useStyles$j();
1324
+ const { classes } = useStyles$i();
1631
1325
  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));
1632
1326
  };
1633
1327
 
@@ -1765,7 +1459,7 @@ const Student = (props) => {
1765
1459
  ))))));
1766
1460
  };
1767
1461
 
1768
- const useStyles$i = core.createStyles((theme, props) => {
1462
+ const useStyles$h = core.createStyles((theme, props) => {
1769
1463
  const from = props.from || "blue";
1770
1464
  const to = props.to || "green";
1771
1465
  return {
@@ -1793,7 +1487,7 @@ const useStyles$i = core.createStyles((theme, props) => {
1793
1487
  };
1794
1488
  });
1795
1489
  function CardGradient(props) {
1796
- const { classes } = useStyles$i(props);
1490
+ const { classes } = useStyles$h(props);
1797
1491
  const from = props.from || "blue";
1798
1492
  const to = props.to || "green";
1799
1493
  const icon = props.icon || /* @__PURE__ */ React__namespace.createElement(icons.IconColorSwatch, { size: 28, stroke: 1.5 });
@@ -1837,7 +1531,7 @@ var __objRest$1 = (source, exclude) => {
1837
1531
  }
1838
1532
  return target;
1839
1533
  };
1840
- const useStyles$h = core.createStyles((theme) => ({
1534
+ const useStyles$g = core.createStyles((theme) => ({
1841
1535
  card: {
1842
1536
  height: 240,
1843
1537
  backgroundSize: "cover",
@@ -1882,7 +1576,7 @@ const TenantBanner = (_a) => {
1882
1576
  "className",
1883
1577
  "code"
1884
1578
  ]);
1885
- const { classes, cx, theme } = useStyles$h();
1579
+ const { classes, cx, theme } = useStyles$g();
1886
1580
  const handleCopy = async () => {
1887
1581
  if (!code)
1888
1582
  return;
@@ -2022,7 +1716,7 @@ function Table$7(props) {
2022
1716
  ));
2023
1717
  }
2024
1718
 
2025
- const useStyles$g = core.createStyles((theme) => ({
1719
+ const useStyles$f = core.createStyles((theme) => ({
2026
1720
  button: {
2027
1721
  borderTopRightRadius: 0,
2028
1722
  borderBottomRightRadius: 0,
@@ -2037,7 +1731,7 @@ const useStyles$g = core.createStyles((theme) => ({
2037
1731
  }
2038
1732
  }));
2039
1733
  const SplitButton$3 = (props) => {
2040
- const { classes, theme } = useStyles$g();
1734
+ const { classes, theme } = useStyles$f();
2041
1735
  theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
2042
1736
  return /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(
2043
1737
  core.Button,
@@ -2215,7 +1909,7 @@ function Stack$2(props) {
2215
1909
  }
2216
1910
  const truncateWithEllipses = (text, max) => text.substr(0, max - 1) + (text.length > max ? "&hellip;" : "");
2217
1911
 
2218
- const useStyles$f = core.createStyles((theme) => ({
1912
+ const useStyles$e = core.createStyles((theme) => ({
2219
1913
  title: {
2220
1914
  fontSize: 34,
2221
1915
  fontWeight: 900,
@@ -2228,7 +1922,7 @@ const useStyles$f = core.createStyles((theme) => ({
2228
1922
  }
2229
1923
  }));
2230
1924
  const Lesson = (props) => {
2231
- const { classes } = useStyles$f();
1925
+ const { classes } = useStyles$e();
2232
1926
  const [tab, setTab] = React.useState("question");
2233
1927
  const numberOfStudents = props.students.length;
2234
1928
  const numberOfLessons = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length : 0;
@@ -2372,7 +2066,7 @@ function Table$5(props) {
2372
2066
  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)));
2373
2067
  }
2374
2068
 
2375
- const useStyles$e = core.createStyles((theme) => ({
2069
+ const useStyles$d = core.createStyles((theme) => ({
2376
2070
  title: {
2377
2071
  fontSize: 34,
2378
2072
  fontWeight: 900,
@@ -2385,7 +2079,7 @@ const useStyles$e = core.createStyles((theme) => ({
2385
2079
  }
2386
2080
  }));
2387
2081
  const Lessons = (props) => {
2388
- const { classes } = useStyles$e();
2082
+ const { classes } = useStyles$d();
2389
2083
  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" }, "Lessons"), /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, "Lessons"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Bite-sized activities and learning experiences accelerating students achievement"))), /* @__PURE__ */ React__namespace.createElement(
2390
2084
  core.Autocomplete,
2391
2085
  {
@@ -2402,7 +2096,7 @@ const Lessons = (props) => {
2402
2096
  ))));
2403
2097
  };
2404
2098
 
2405
- const useStyles$d = core.createStyles((theme) => ({
2099
+ const useStyles$c = core.createStyles((theme) => ({
2406
2100
  title: {
2407
2101
  fontSize: 22,
2408
2102
  fontWeight: 900,
@@ -2421,7 +2115,7 @@ const useStyles$d = core.createStyles((theme) => ({
2421
2115
  }
2422
2116
  }));
2423
2117
  function AccessCode(props) {
2424
- const { classes } = useStyles$d();
2118
+ const { classes } = useStyles$c();
2425
2119
  return /* @__PURE__ */ React__namespace.createElement(core.Container, { mx: "0", px: "0", size: 460, my: 30 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { className: classes.title }, "Access code"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", size: "sm" }, "Grant access to join your organization"), /* @__PURE__ */ React__namespace.createElement(core.Paper, { withBorder: true, shadow: "md", p: 30, radius: "md", mt: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.TextInput, { value: props.value, readOnly: true }), /* @__PURE__ */ React__namespace.createElement(core.Group, { position: "apart", mt: "lg", className: classes.controls }, /* @__PURE__ */ React__namespace.createElement(
2426
2120
  core.Anchor,
2427
2121
  {
@@ -2449,7 +2143,7 @@ const monthNames = [
2449
2143
  "November",
2450
2144
  "December"
2451
2145
  ];
2452
- const useStyles$c = core.createStyles((theme) => ({
2146
+ const useStyles$b = core.createStyles((theme) => ({
2453
2147
  title: {
2454
2148
  fontSize: 34,
2455
2149
  fontWeight: 900,
@@ -2479,7 +2173,7 @@ const useStyles$c = core.createStyles((theme) => ({
2479
2173
  }
2480
2174
  }));
2481
2175
  const Organization = (props) => {
2482
- const { classes } = useStyles$c();
2176
+ const { classes } = useStyles$b();
2483
2177
  return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__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.UnstyledButton, { onClick: props.onBackClick }, /* @__PURE__ */ React__namespace.createElement(
2484
2178
  core.Badge,
2485
2179
  {
@@ -2505,7 +2199,7 @@ const Organization = (props) => {
2505
2199
  ] }))))));
2506
2200
  };
2507
2201
 
2508
- const useStyles$b = core.createStyles((theme) => ({
2202
+ const useStyles$a = core.createStyles((theme) => ({
2509
2203
  button: {
2510
2204
  borderTopRightRadius: 0,
2511
2205
  borderBottomRightRadius: 0,
@@ -2520,7 +2214,7 @@ const useStyles$b = core.createStyles((theme) => ({
2520
2214
  }
2521
2215
  }));
2522
2216
  const SplitButton$2 = (props) => {
2523
- const { classes, theme } = useStyles$b();
2217
+ const { classes, theme } = useStyles$a();
2524
2218
  const menuIconColor = theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
2525
2219
  const hasMenu = !!props.withOrganizationLink;
2526
2220
  return /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
@@ -2601,7 +2295,7 @@ var __spreadValues$7 = (a, b) => {
2601
2295
  return a;
2602
2296
  };
2603
2297
  var __spreadProps$5 = (a, b) => __defProps$5(a, __getOwnPropDescs$5(b));
2604
- const useStyles$a = core.createStyles((theme) => ({
2298
+ const useStyles$9 = core.createStyles((theme) => ({
2605
2299
  title: {
2606
2300
  fontSize: 34,
2607
2301
  fontWeight: 900,
@@ -2631,7 +2325,7 @@ const useStyles$a = core.createStyles((theme) => ({
2631
2325
  }
2632
2326
  }));
2633
2327
  const People = (props) => {
2634
- const { classes } = useStyles$a();
2328
+ const { classes } = useStyles$9();
2635
2329
  const form$1 = form.useForm({
2636
2330
  initialValues: {
2637
2331
  userId: "",
@@ -2735,7 +2429,7 @@ const People = (props) => {
2735
2429
  ))))));
2736
2430
  };
2737
2431
  const DropzoneButton = (props) => {
2738
- const { classes, theme } = useStyles$a();
2432
+ const { classes, theme } = useStyles$9();
2739
2433
  const openRef = React__namespace.useRef(null);
2740
2434
  const [loading, setLoading] = React__namespace.useState(false);
2741
2435
  const onDrop = React__namespace.useCallback((acceptedFiles) => {
@@ -2781,7 +2475,7 @@ const DropzoneButton = (props) => {
2781
2475
  } }, "Select file"));
2782
2476
  };
2783
2477
 
2784
- const useStyles$9 = core.createStyles((theme) => ({
2478
+ const useStyles$8 = core.createStyles((theme) => ({
2785
2479
  form: {
2786
2480
  backgroundColor: theme.white,
2787
2481
  padding: theme.spacing.xl,
@@ -2844,7 +2538,7 @@ const useStyles$9 = core.createStyles((theme) => ({
2844
2538
  }
2845
2539
  }));
2846
2540
  const StartAnonymousLesson = (props) => {
2847
- const { classes } = useStyles$9();
2541
+ const { classes } = useStyles$8();
2848
2542
  const [name, setName] = React__namespace.useState("");
2849
2543
  return /* @__PURE__ */ React__namespace.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React__namespace.createElement(core.Container, null, /* @__PURE__ */ React__namespace.createElement(core.SimpleGrid, { maw: 960, cols: 2, spacing: 15, breakpoints: [{ maxWidth: "sm", cols: 1 }] }, /* @__PURE__ */ React__namespace.createElement("div", { className: classes.content }, /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "violet" }, "Community"), /* @__PURE__ */ React__namespace.createElement(core.Title, { className: classes.title }, props.title), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", mt: "md" }, props.description), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", mt: "md" }, "You are now part of ", `${props.educatorName}'s`, " Class")), /* @__PURE__ */ React__namespace.createElement("div", { className: classes.form }, /* @__PURE__ */ React__namespace.createElement(
2850
2544
  core.TextInput,
@@ -2901,7 +2595,7 @@ function TaskCard(props) {
2901
2595
  ));
2902
2596
  }
2903
2597
 
2904
- const useStyles$8 = core.createStyles((theme) => ({
2598
+ const useStyles$7 = core.createStyles((theme) => ({
2905
2599
  action: {
2906
2600
  backgroundColor: "inherit",
2907
2601
  ":hover": {
@@ -2920,7 +2614,7 @@ const useStyles$8 = core.createStyles((theme) => ({
2920
2614
  }
2921
2615
  }));
2922
2616
  const TrialHome = (props) => {
2923
- const { classes } = useStyles$8();
2617
+ const { classes } = useStyles$7();
2924
2618
  return /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg" }, /* @__PURE__ */ React__namespace.createElement(core.Badge, null, props.daysRemaining, " day", props.daysRemaining !== 1 ? "s" : "", " left"), /* @__PURE__ */ React__namespace.createElement(
2925
2619
  core.Button,
2926
2620
  {
@@ -2980,7 +2674,7 @@ var __objRest = (source, exclude) => {
2980
2674
  }
2981
2675
  return target;
2982
2676
  };
2983
- const useStyles$7 = core.createStyles((theme, { checked }) => ({
2677
+ const useStyles$6 = core.createStyles((theme, { checked }) => ({
2984
2678
  button: {
2985
2679
  display: "flex",
2986
2680
  alignItems: "center",
@@ -3022,7 +2716,7 @@ function ImageCheckbox(_a) {
3022
2716
  finalValue: false,
3023
2717
  onChange
3024
2718
  });
3025
- const { classes, cx } = useStyles$7({ checked: value });
2719
+ const { classes, cx } = useStyles$6({ checked: value });
3026
2720
  return /* @__PURE__ */ React__namespace.createElement(
3027
2721
  core.UnstyledButton,
3028
2722
  __spreadProps$4(__spreadValues$5({}, others), {
@@ -3083,7 +2777,7 @@ var __spreadValues$4 = (a, b) => {
3083
2777
  return a;
3084
2778
  };
3085
2779
  var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
3086
- const useStyles$6 = core.createStyles((theme) => ({
2780
+ const useStyles$5 = core.createStyles((theme) => ({
3087
2781
  wrapper: {
3088
2782
  minHeight: "100%",
3089
2783
  boxSizing: "border-box",
@@ -3146,7 +2840,7 @@ const OPTIONS = [
3146
2840
  { description: "project-based learning", title: "Project-Based Learning", icon: icons.IconTools }
3147
2841
  ];
3148
2842
  const TrialRegistration = (props) => {
3149
- const { classes } = useStyles$6();
2843
+ const { classes } = useStyles$5();
3150
2844
  const [firstName, setFirstName] = React__namespace.useState("");
3151
2845
  const [lastName, setLastName] = React__namespace.useState("");
3152
2846
  const [organization, setOrganization] = React__namespace.useState({ organizationId: "", displayName: "" });
@@ -3261,7 +2955,7 @@ var __spreadValues$3 = (a, b) => {
3261
2955
  return a;
3262
2956
  };
3263
2957
  var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
3264
- const useStyles$5 = core.createStyles((theme, props) => ({
2958
+ const useStyles$4 = core.createStyles((theme, props) => ({
3265
2959
  footer: {
3266
2960
  paddingTop: theme.spacing.md,
3267
2961
  paddingBottom: theme.spacing.md,
@@ -3348,7 +3042,7 @@ const useStyles$5 = core.createStyles((theme, props) => ({
3348
3042
  }
3349
3043
  }));
3350
3044
  const App = (props) => {
3351
- const { classes } = useStyles$5(props);
3045
+ const { classes } = useStyles$4(props);
3352
3046
  const account = useAccount(props.account, props.accounts, props.onAccountChange);
3353
3047
  return /* @__PURE__ */ React__namespace.createElement(
3354
3048
  core.AppShell,
@@ -3444,58 +3138,26 @@ const useAccount = (account, accounts, onAccountChange) => {
3444
3138
  };
3445
3139
 
3446
3140
  function Table$3(props) {
3141
+ if (props.loading) {
3142
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "text-sm text-slate-400" }, "Loading\u2026");
3143
+ }
3447
3144
  if (props.items.length === 0) {
3448
- return /* @__PURE__ */ React__namespace.createElement(
3449
- PlaceholderBanner,
3450
- {
3451
- title: "No pathway items to display",
3452
- description: "We don't have any pathway items to show you just yet.",
3453
- loading: props.loading,
3454
- icon: "badges"
3455
- }
3456
- );
3145
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "rounded-xl border border-slate-200 bg-white p-8 text-center text-sm text-slate-400 shadow-sm" }, "No pathways to display.");
3457
3146
  }
3458
- const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.badgeId }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(
3459
- core.UnstyledButton,
3147
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "flex flex-col gap-3" }, props.items.map((row) => /* @__PURE__ */ React__namespace.createElement(
3148
+ reactRouterDom.Link,
3460
3149
  {
3461
- component: reactRouterDom.Link,
3150
+ key: row.badgeId,
3462
3151
  to: row.href,
3463
- sx: (theme) => ({
3464
- display: "block",
3465
- width: "100%",
3466
- padding: theme.spacing.md,
3467
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
3468
- "&:hover": {
3469
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.colors.gray[1]
3470
- }
3471
- })
3152
+ className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
3472
3153
  },
3473
- /* @__PURE__ */ React__namespace.createElement(core.Group, null, /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xs", color: "dimmed" }, row.description)))
3474
- ))));
3475
- 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)));
3154
+ /* @__PURE__ */ React__namespace.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, row.name), row.description && /* @__PURE__ */ React__namespace.createElement("div", { className: "mt-1 text-xs leading-relaxed text-slate-500" }, row.description)),
3155
+ /* @__PURE__ */ React__namespace.createElement(icons.IconChevronRight, { size: 16, stroke: 2, className: "shrink-0 text-slate-300" })
3156
+ )));
3476
3157
  }
3477
3158
 
3478
- const useStyles$4 = core.createStyles((theme) => ({
3479
- title: {
3480
- fontSize: 34,
3481
- fontWeight: 900,
3482
- [theme.fn.smallerThan("sm")]: {
3483
- fontSize: 24
3484
- }
3485
- },
3486
- description: {
3487
- maxWidth: 600
3488
- }
3489
- }));
3490
3159
  const Pathways = (props) => {
3491
- const { classes } = useStyles$4();
3492
- 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" }, "Pathways"), /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, "Pathways"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Explore all your unique pathway requirements in one clear space"))), /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(
3493
- Table$3,
3494
- {
3495
- loading: props.loading,
3496
- items: props.pathways
3497
- }
3498
- ))));
3160
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: "mx-auto flex max-w-4xl flex-col gap-5 px-4 py-8" }, /* @__PURE__ */ React__namespace.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React__namespace.createElement("h1", { className: "text-2xl font-extrabold tracking-tight text-dark-blue-400" }, "Pathways"), /* @__PURE__ */ React__namespace.createElement("p", { className: "text-sm text-slate-500" }, "Explore all your unique pathway requirements in one clear space")), /* @__PURE__ */ React__namespace.createElement(Table$3, { loading: props.loading, items: props.pathways }));
3499
3161
  };
3500
3162
 
3501
3163
  const useStyles$3 = core.createStyles((theme) => ({
@@ -4125,12 +3787,12 @@ const FileLocker = (props) => {
4125
3787
  };
4126
3788
 
4127
3789
  Object.defineProperty(exports, 'showNotification', {
4128
- enumerable: true,
4129
- get: function () { return notifications.showNotification; }
3790
+ enumerable: true,
3791
+ get: function () { return notifications.showNotification; }
4130
3792
  });
4131
3793
  Object.defineProperty(exports, 'updateNotification', {
4132
- enumerable: true,
4133
- get: function () { return notifications.updateNotification; }
3794
+ enumerable: true,
3795
+ get: function () { return notifications.updateNotification; }
4134
3796
  });
4135
3797
  exports.AdminProvider = AdminProvider;
4136
3798
  exports.App = App;