@local-civics/mgmt-ui 0.1.212 → 0.1.214

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { useState, useMemo } from 'react';
3
- import { createStyles, Group, Avatar, Text, Box, Badge as Badge$1, ThemeIcon, Collapse, Navbar as Navbar$1, Center, Image, Code, Burger, ScrollArea, Modal, Loader, Container, Button, Title, UnstyledButton, Card, SimpleGrid, Tabs as Tabs$1, Stack as Stack$5, Grid, ActionIcon, LoadingOverlay, Select, Table as Table$l, Autocomplete, Drawer, Divider, TextInput, Tooltip, Paper, Overlay, Anchor, Menu, Checkbox, createEmotionCache, MantineProvider, AppShell, Accordion } from '@mantine/core';
4
- import { IconChevronRight, IconChevronLeft, IconVideo, IconSwitchHorizontal, IconLogout, IconHome2, IconGauge, IconCategory2, IconRoute, IconAlbum, IconLambda, IconClipboard, IconBuilding, IconBatteryEco, IconBooks, IconBackpack, IconClipboardCopy, IconTableExport, IconArrowLeft, IconPlaylistAdd, IconCheck, IconTrash, IconDownload, IconX, IconCloudUpload, IconInfoCircle, IconColorSwatch, IconPointer, IconChevronDown, IconScribble, IconSchool, IconPodium, IconBriefcase, IconPresentation, IconNews, IconTools, IconBrandInstagram, IconBrandLinkedin, IconBrandFacebook } from '@tabler/icons';
3
+ import { IconChevronRight, IconVideo, IconSwitchHorizontal, IconLogout, IconHome2, IconGauge, IconCategory2, IconRoute, IconAlbum, IconLambda, IconClipboard, IconBuilding, IconBatteryEco, IconBooks, IconBackpack, IconClipboardCopy, IconTableExport, IconArrowLeft, IconSearch, IconCheck, IconTrash, IconPlus, IconLink, IconDownload, IconCloudUpload, IconInfoCircle, IconPlaylistAdd, IconPointer, IconChevronDown, IconX, IconScribble, IconSchool, IconPodium, IconBriefcase, IconPresentation, IconNews, IconTools, IconBrandInstagram, IconBrandLinkedin, IconBrandFacebook, IconExternalLink, IconChevronLeft } from '@tabler/icons';
4
+ import { Avatar, createStyles, Modal, Center, Loader, Container, Group, Button, Title, Text, UnstyledButton, Card, ScrollArea, SimpleGrid, Tabs as Tabs$1, Stack as Stack$5, Image, Grid, Badge as Badge$1, ActionIcon, LoadingOverlay, Select, Table as Table$l, Drawer, Divider, TextInput, Tooltip, Autocomplete, Paper, Anchor, Box, Menu, Overlay, ThemeIcon, Checkbox, createEmotionCache, MantineProvider, AppShell } from '@mantine/core';
5
5
  import { Link } from 'react-router-dom';
6
6
  import { showNotification, NotificationsProvider } from '@mantine/notifications';
7
7
  export { showNotification, updateNotification } from '@mantine/notifications';
@@ -14,47 +14,46 @@ import AvatarInit from 'avatar-initials';
14
14
  import { Chart } from 'react-charts';
15
15
  import { useUncontrolled } from '@mantine/hooks';
16
16
 
17
- var __defProp$f = Object.defineProperty;
18
- var __getOwnPropSymbols$f = Object.getOwnPropertySymbols;
19
- var __hasOwnProp$f = Object.prototype.hasOwnProperty;
20
- var __propIsEnum$f = Object.prototype.propertyIsEnumerable;
21
- var __defNormalProp$f = (obj, key, value) => key in obj ? __defProp$f(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
22
- var __spreadValues$f = (a, b) => {
23
- for (var prop in b || (b = {}))
24
- if (__hasOwnProp$f.call(b, prop))
25
- __defNormalProp$f(a, prop, b[prop]);
26
- if (__getOwnPropSymbols$f)
27
- for (var prop of __getOwnPropSymbols$f(b)) {
28
- if (__propIsEnum$f.call(b, prop))
29
- __defNormalProp$f(a, prop, b[prop]);
30
- }
31
- return a;
32
- };
33
- var __objRest$2 = (source, exclude) => {
34
- var target = {};
35
- for (var prop in source)
36
- if (__hasOwnProp$f.call(source, prop) && exclude.indexOf(prop) < 0)
37
- target[prop] = source[prop];
38
- if (source != null && __getOwnPropSymbols$f)
39
- for (var prop of __getOwnPropSymbols$f(source)) {
40
- if (exclude.indexOf(prop) < 0 && __propIsEnum$f.call(source, prop))
41
- target[prop] = source[prop];
17
+ function styleInject(css, ref) {
18
+ if ( ref === void 0 ) ref = {};
19
+ var insertAt = ref.insertAt;
20
+
21
+ if (!css || typeof document === 'undefined') { return; }
22
+
23
+ var head = document.head || document.getElementsByTagName('head')[0];
24
+ var style = document.createElement('style');
25
+ style.type = 'text/css';
26
+
27
+ if (insertAt === 'top') {
28
+ if (head.firstChild) {
29
+ head.insertBefore(style, head.firstChild);
30
+ } else {
31
+ head.appendChild(style);
42
32
  }
43
- return target;
44
- };
45
- const useStyles$v = createStyles((theme) => ({
46
- user: {
47
- display: "block",
48
- width: "100%",
49
- padding: theme.spacing.md,
50
- cursor: "default",
51
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black
33
+ } else {
34
+ head.appendChild(style);
52
35
  }
53
- }));
54
- function UserButton(_a) {
55
- var _b = _a, { image, name, email, icon } = _b, others = __objRest$2(_b, ["image", "name", "email", "icon"]);
56
- const { classes } = useStyles$v();
57
- return /* @__PURE__ */ React.createElement(Group, __spreadValues$f({ className: classes.user }, others), /* @__PURE__ */ React.createElement(Avatar, { src: image, radius: "xl" }), /* @__PURE__ */ React.createElement("div", { style: { flex: 1 } }, /* @__PURE__ */ React.createElement(Text, { size: "sm", weight: 500 }, name), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", size: "xs" }, email)));
36
+
37
+ if (style.styleSheet) {
38
+ style.styleSheet.cssText = css;
39
+ } else {
40
+ style.appendChild(document.createTextNode(css));
41
+ }
42
+ }
43
+
44
+ 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: }.pointer-events-none{pointer-events:none}.visible{visibility:visible}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.\\!relative{position:relative!important}.left-3\\.5{left:.875rem}.top-1\\/2{top:50%}.left-3{left:.75rem}.m-3{margin:.75rem}.mx-auto{margin-left:auto;margin-right:auto}.mt-0\\.5{margin-top:.125rem}.mt-0{margin-top:0}.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}.block{display:block}.inline{display:inline}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-full{height:100%}.h-8{height:2rem}.h-7{height:1.75rem}.h-12{height:3rem}.h-9{height:2.25rem}.h-screen{height:100vh}.h-\\[30px\\]{height:30px}.w-10{width:2.5rem}.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-64{width:16rem}.w-12{width:3rem}.w-16{width:4rem}.w-36{width:9rem}.w-4{width:1rem}.w-9{width:2.25rem}.w-\\[440px\\]{width:440px}.w-40{width:10rem}.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}.max-w-\\[1100px\\]{max-width:1100px}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-y-1\\/2{--tw-translate-y:-50%}.-translate-y-1\\/2,.rotate-180{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))}.rotate-180{--tw-rotate:180deg}.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}.items-stretch{align-items:stretch}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-\\[18px\\]{gap:18px}.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-3\\.5{gap:.875rem}.gap-0\\.5{gap:.125rem}.gap-0{gap:0}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.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-2xl{border-radius:1rem}.rounded-\\[10px\\]{border-radius:10px}.rounded-xl{border-radius:.75rem}.rounded-lg{border-radius:.5rem}.rounded-full{border-radius:9999px}.rounded-md{border-radius:.375rem}.rounded-\\[8px\\]{border-radius:8px}.border{border-width:1px}.border-l-4{border-left-width:4px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-r{border-right-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}.border-l-sky-blue-400{--tw-border-opacity:1;border-left-color:rgb(59 208 242/var(--tw-border-opacity))}.border-l-mint-400{--tw-border-opacity:1;border-left-color:rgb(30 226 175/var(--tw-border-opacity))}.border-l-gold-400{--tw-border-opacity:1;border-left-color:rgb(255 212 77/var(--tw-border-opacity))}.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-mint-100{--tw-bg-opacity:1;background-color:rgb(208 251 240/var(--tw-bg-opacity))}.bg-sky-blue-400\\/20{background-color:rgba(59,208,242,.2)}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-white\\/90{background-color:hsla(0,0%,100%,.9)}.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-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-sky-blue-400{--tw-gradient-from:#3bd0f2;--tw-gradient-to:rgba(59,208,242,0);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-mint-400{--tw-gradient-from:#1ee2af;--tw-gradient-to:rgba(30,226,175,0);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.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-dark-blue-400{--tw-gradient-to:#232a3a}.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-1{padding:.25rem}.p-5{padding:1.25rem}.p-2\\.5{padding:.625rem}.p-2{padding:.5rem}.px-\\[22px\\]{padding-left:22px;padding-right:22px}.py-\\[18px\\]{padding-bottom:18px;padding-top:18px}.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}.pb-2{padding-bottom:.5rem}.pl-10{padding-left:2.5rem}.pr-4{padding-right:1rem}.pl-2\\.5{padding-left:.625rem}.pl-2{padding-left:.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-proxima{font-family:ProximaNova}.text-\\[15\\.5px\\]{font-size:15.5px}.text-xs{font-size:.75rem;line-height:1rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-\\[10px\\]{font-size:10px}.text-\\[10\\.5px\\]{font-size:10.5px}.text-\\[11px\\]{font-size:11px}.text-\\[28px\\]{font-size:28px}.text-\\[12\\.5px\\]{font-size:12.5px}.text-base{font-size:1rem;line-height:1.5rem}.text-\\[11\\.5px\\]{font-size:11.5px}.text-3xl{font-size:1.875rem;line-height:2.25rem}.font-extrabold{font-weight:800}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.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-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.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-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-transform{transition-duration:.15s;transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1)}.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)}*,:after,:before{border-style:solid;border-width:0}button{background-color:transparent;background-image:none;color:inherit;cursor:pointer;font:inherit;margin:0;padding:0;text-transform:none}.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\\:scale-\\[1\\.02\\]:hover{--tw-scale-x:1.02;--tw-scale-y:1.02;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))}.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\\:bg-white:hover{--tw-bg-opacity:1;background-color:rgb(255 255 255/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-600:hover{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.hover\\:text-slate-500:hover{--tw-text-opacity:1;color:rgb(100 116 139/var(--tw-text-opacity))}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:shadow-md:hover{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.focus\\:border-sky-blue-400:focus{--tw-border-opacity:1;border-color:rgb(59 208 242/var(--tw-border-opacity))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.disabled\\:opacity-50:disabled{opacity:.5}";
45
+ styleInject(css_248z);
46
+
47
+ function UserButton({ image, name, email }) {
48
+ return /* @__PURE__ */ React.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.createElement(
49
+ Avatar,
50
+ {
51
+ src: image,
52
+ radius: "xl",
53
+ size: 32,
54
+ styles: { placeholder: { color: "#232A3A", backgroundColor: "rgba(30,226,175,0.2)" } }
55
+ }
56
+ ), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs font-bold text-dark-blue-400" }, name), /* @__PURE__ */ React.createElement("div", { className: "truncate text-[10px] text-slate-500" }, email)));
58
57
  }
59
58
 
60
59
  const compact = (num) => {
@@ -64,102 +63,66 @@ const compact = (num) => {
64
63
  }).format(num || 0);
65
64
  };
66
65
 
67
- const useStyles$u = createStyles((theme, _params, getRef) => {
68
- const icon = getRef("icon");
69
- return {
70
- control: {
71
- fontWeight: 500,
72
- width: "100%",
73
- padding: `${theme.spacing.xs}px ${theme.spacing.md}px`,
74
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
75
- fontSize: theme.fontSizes.sm,
76
- "&:hover": {
77
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.colors.gray[0],
78
- color: theme.colorScheme === "dark" ? theme.white : theme.black
79
- }
80
- },
81
- controlButton: {
82
- cursor: "pointer"
83
- },
84
- badge: {
85
- pointerEvents: "none"
86
- },
87
- link: {
88
- fontWeight: 500,
89
- display: "block",
90
- textDecoration: "none",
91
- padding: `${theme.spacing.xs}px ${theme.spacing.md}px`,
92
- paddingLeft: 31,
93
- marginLeft: 30,
94
- fontSize: theme.fontSizes.sm,
95
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.colors.gray[7],
96
- borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[3]}`,
97
- "&:hover": {
98
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.colors.gray[0],
99
- color: theme.colorScheme === "dark" ? theme.white : theme.black
100
- }
101
- },
102
- linkActive: {
103
- "&, &:hover": {
104
- backgroundColor: theme.fn.variant({ variant: "light", color: theme.primaryColor }).background,
105
- color: theme.fn.variant({ variant: "light", color: theme.primaryColor }).color,
106
- [`& .${icon}`]: {
107
- color: theme.fn.variant({ variant: "light", color: theme.primaryColor }).color
108
- }
109
- }
110
- },
111
- chevron: {
112
- transition: "transform 200ms ease"
113
- },
114
- linkIcon: {
115
- ref: icon
116
- }
117
- };
118
- });
119
- function LinksGroup({ icon: Icon, href, label, initiallyOpened, links, active, notifications }) {
120
- const { classes, theme, cx } = useStyles$u();
66
+ const ACCENT_CLASSNAMES = {
67
+ cyan: {
68
+ row: "bg-sky-blue-400/15 border-sky-blue-400/30",
69
+ chip: "bg-sky-blue-400/25",
70
+ icon: "text-sky-blue-400",
71
+ pill: "bg-sky-blue-400/15 text-dark-blue-400"
72
+ },
73
+ mint: {
74
+ row: "bg-mint-400/15 border-mint-400/30",
75
+ chip: "bg-mint-400/25",
76
+ icon: "text-mint-400",
77
+ pill: "bg-mint-400/15 text-dark-blue-400"
78
+ },
79
+ gold: {
80
+ row: "bg-gold-400/15 border-gold-400/30",
81
+ chip: "bg-gold-400/25",
82
+ icon: "text-gold-400",
83
+ pill: "bg-gold-400/15 text-dark-blue-400"
84
+ }
85
+ };
86
+ function LinksGroup({ icon: Icon, href, label, accent = "cyan", initiallyOpened, links, active, notifications }) {
121
87
  const hasLinks = Array.isArray(links) && links.length > 0;
122
88
  const hasActiveLinks = Array.isArray(links) && links.map((l) => !!active && active === `${label}/${l.label}`).reduce((a, b) => a || b, false);
123
89
  const [opened, setOpened] = useState(initiallyOpened || hasActiveLinks || false);
124
90
  React.useEffect(() => {
125
91
  setOpened(hasActiveLinks);
126
92
  }, [hasActiveLinks]);
127
- const ChevronIcon = theme.dir === "ltr" ? IconChevronRight : IconChevronLeft;
93
+ const isActive = !!active && !hasLinks && label === active;
94
+ const accentClasses = ACCENT_CLASSNAMES[accent];
128
95
  const items = (hasLinks ? links : []).map((link) => {
96
+ const linkActive = !!active && active === `${label}/${link.label}`;
129
97
  return /* @__PURE__ */ React.createElement(
130
- Box,
98
+ Link,
131
99
  {
132
- className: cx(classes.link, { [classes.linkActive]: !!active && active === `${label}/${link.label}` }),
133
- key: link.label
100
+ key: link.label,
101
+ to: link.href,
102
+ 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"}`
134
103
  },
135
- /* @__PURE__ */ React.createElement(Group, { position: "apart", spacing: 0 }, /* @__PURE__ */ React.createElement(Text, { component: Link, to: link.href }, link.label), !!link.notifications && /* @__PURE__ */ React.createElement(Badge$1, { size: "sm", variant: "filled", className: classes.badge }, compact(link.notifications)))
104
+ link.label,
105
+ !!link.notifications && /* @__PURE__ */ React.createElement("span", { className: `rounded-full px-2 py-0.5 text-[10px] font-bold ${accentClasses.pill}` }, compact(link.notifications))
136
106
  );
137
107
  });
138
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
139
- Group,
108
+ const rowInner = /* @__PURE__ */ React.createElement("div", { className: "flex flex-1 items-center gap-2.5" }, /* @__PURE__ */ React.createElement("div", { className: `flex h-[30px] w-[30px] shrink-0 items-center justify-center rounded-lg ${isActive ? accentClasses.chip : "bg-slate-50"}` }, /* @__PURE__ */ React.createElement(Icon, { size: 14, stroke: isActive ? 2.2 : 1.75, className: isActive ? accentClasses.icon : "text-slate-400" })), /* @__PURE__ */ React.createElement("span", { className: `flex-1 text-xs ${isActive ? "font-bold text-dark-blue-400" : "font-medium text-slate-500"}` }, label));
109
+ return /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
110
+ "div",
140
111
  {
141
- className: cx(classes.control, {
142
- [classes.linkActive]: !!active && !hasLinks && label === active,
143
- [classes.controlButton]: hasLinks
144
- }),
145
- onClick: () => setOpened((o) => !o),
146
- position: "apart",
147
- spacing: 0
112
+ onClick: () => hasLinks && setOpened((o) => !o),
113
+ 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" : ""}`
148
114
  },
149
- /* @__PURE__ */ React.createElement(Box, { sx: { display: "flex", alignItems: "center" } }, /* @__PURE__ */ React.createElement(ThemeIcon, { variant: "light", size: 30 }, /* @__PURE__ */ React.createElement(Icon, { className: classes.linkIcon, size: 18 })), /* @__PURE__ */ React.createElement(Box, { ml: "md" }, /* @__PURE__ */ React.createElement(Text, { component: Link, to: href }, label))),
150
- !!notifications && /* @__PURE__ */ React.createElement(Badge$1, { size: "sm", variant: "filled", className: classes.badge }, compact(notifications)),
115
+ hasLinks ? rowInner : /* @__PURE__ */ React.createElement(Link, { to: href, className: "flex flex-1 items-center gap-2.5 no-underline" }, rowInner),
116
+ !!notifications && /* @__PURE__ */ React.createElement("span", { className: `rounded-full px-2 py-0.5 text-[10px] font-bold ${accentClasses.pill}` }, compact(notifications)),
151
117
  hasLinks && /* @__PURE__ */ React.createElement(
152
- ChevronIcon,
118
+ IconChevronRight,
153
119
  {
154
- className: classes.chevron,
155
- size: 14,
156
- stroke: 1.5,
157
- style: {
158
- transform: opened ? `rotate(${theme.dir === "rtl" ? -90 : 90}deg)` : "none"
159
- }
120
+ size: 13,
121
+ stroke: 2.2,
122
+ className: `shrink-0 text-slate-300 transition-transform ${opened ? "rotate-90" : ""}`
160
123
  }
161
124
  )
162
- ), hasLinks ? /* @__PURE__ */ React.createElement(Collapse, { in: opened }, items) : null);
125
+ ), hasLinks && opened && /* @__PURE__ */ React.createElement("div", { className: "ml-[29px] mt-0.5 flex flex-col gap-0.5 border-l border-slate-100 pl-2.5" }, items));
163
126
  }
164
127
 
165
128
  var __defProp$e = Object.defineProperty;
@@ -181,100 +144,15 @@ var __spreadValues$e = (a, b) => {
181
144
  return a;
182
145
  };
183
146
  var __spreadProps$a = (a, b) => __defProps$a(a, __getOwnPropDescs$a(b));
184
- const useStyles$t = createStyles((theme, _params, getRef) => {
185
- const icon = getRef("icon");
186
- return {
187
- navbar: {
188
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.white
189
- },
190
- navHeader: {
191
- [`@media (max-width: ${theme.breakpoints.sm}px)`]: {
192
- height: 71,
193
- position: "absolute",
194
- top: 0
195
- }
196
- },
197
- navBody: {
198
- [`@media (max-width: ${theme.breakpoints.sm}px)`]: {
199
- display: "none"
200
- }
201
- },
202
- burger: {
203
- [theme.fn.largerThan("sm")]: {
204
- display: "none"
205
- }
206
- },
207
- header: {
208
- padding: theme.spacing.md,
209
- paddingTop: 0,
210
- marginLeft: -theme.spacing.md,
211
- marginRight: -theme.spacing.md,
212
- color: theme.colorScheme === "dark" ? theme.white : theme.black,
213
- borderBottom: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[3]}`
214
- },
215
- link: __spreadProps$a(__spreadValues$e({}, theme.fn.focusStyles()), {
216
- display: "flex",
217
- alignItems: "center",
218
- textDecoration: "none",
219
- fontSize: theme.fontSizes.sm,
220
- color: theme.colorScheme === "dark" ? theme.colors.dark[1] : theme.colors.gray[7],
221
- padding: `${theme.spacing.xs}px ${theme.spacing.sm}px`,
222
- borderRadius: theme.radius.sm,
223
- fontWeight: 500,
224
- "&:hover": {
225
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[0],
226
- color: theme.colorScheme === "dark" ? theme.white : theme.black,
227
- [`& .${icon}`]: {
228
- color: theme.colorScheme === "dark" ? theme.white : theme.black
229
- }
230
- }
231
- }),
232
- linkIcon: {
233
- ref: icon,
234
- color: theme.colorScheme === "dark" ? theme.colors.dark[2] : theme.colors.gray[6],
235
- marginRight: theme.spacing.sm
236
- },
237
- links: {
238
- marginLeft: -theme.spacing.md,
239
- marginRight: -theme.spacing.md
240
- },
241
- user: {
242
- margin: theme.spacing.md,
243
- marginLeft: 0,
244
- marginRight: 0
245
- },
246
- linksInner: {
247
- paddingBottom: theme.spacing.xl
248
- },
249
- footer: {
250
- paddingTop: theme.spacing.md,
251
- paddingBottom: theme.spacing.md,
252
- borderTop: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[2]}`
253
- },
254
- active: {
255
- "&, &:hover": {
256
- backgroundColor: theme.fn.variant({ variant: "light", color: theme.primaryColor }).background,
257
- color: theme.fn.variant({ variant: "light", color: theme.primaryColor }).color
258
- }
259
- }
260
- };
261
- });
262
147
  const data = [
263
- { label: "Home", icon: IconHome2 },
264
- { label: "Dashboard", icon: IconGauge },
265
- { label: "Classes", icon: IconCategory2 },
266
- { label: "Pathways", icon: IconRoute },
267
- { label: "Badges", icon: IconAlbum },
268
- { label: "Lessons", icon: IconLambda },
269
- { label: "File Locker", icon: IconClipboard },
270
- {
271
- label: "Organization",
272
- icon: IconBuilding,
273
- links: [
274
- { label: "Overview" },
275
- { label: "People" }
276
- ]
277
- }
148
+ { label: "Home", icon: IconHome2, accent: "cyan" },
149
+ { label: "Dashboard", icon: IconGauge, accent: "mint" },
150
+ { label: "Classes", icon: IconCategory2, accent: "gold" },
151
+ { label: "Pathways", icon: IconRoute, accent: "cyan" },
152
+ { label: "Badges", icon: IconAlbum, accent: "mint" },
153
+ { label: "Lessons", icon: IconLambda, accent: "gold" },
154
+ { label: "File Locker", icon: IconClipboard, accent: "cyan" },
155
+ { label: "Organization", icon: IconBuilding, accent: "gold", links: [{ label: "Overview" }, { label: "People" }] }
278
156
  ];
279
157
  const TRIAL_PAGES = [
280
158
  "Home",
@@ -282,9 +160,6 @@ const TRIAL_PAGES = [
282
160
  "Badges"
283
161
  ];
284
162
  function Navbar(props) {
285
- const { classes, cx } = useStyles$t();
286
- const [burgerOpen, setBurgerOpen] = React.useState(false);
287
- const toggle = () => setBurgerOpen(!burgerOpen);
288
163
  const links = data.map((item) => {
289
164
  const context = props.links[item.label] || { notifications: 0, href: "" };
290
165
  if (context.hidden || props.trial && TRIAL_PAGES.indexOf(item.label) === -1) {
@@ -305,27 +180,22 @@ function Navbar(props) {
305
180
  })
306
181
  );
307
182
  });
308
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Navbar$1, { width: { sm: 300 }, p: "md", className: cx(classes.navbar, { [classes.navHeader]: !burgerOpen }) }, /* @__PURE__ */ React.createElement(Navbar$1.Section, { className: classes.header }, /* @__PURE__ */ React.createElement(Group, { position: "apart" }, /* @__PURE__ */ React.createElement(Center, null, /* @__PURE__ */ React.createElement(Avatar, { color: "blue", radius: "sm" }, /* @__PURE__ */ React.createElement("div", { style: { width: 15, marginLeft: "auto", marginRight: "auto" } }, /* @__PURE__ */ React.createElement(Image, { fit: "contain", src: "https://cdn.localcivics.io/brand/l.png" })))), /* @__PURE__ */ React.createElement(Group, { position: "apart" }, /* @__PURE__ */ React.createElement(Code, { sx: { fontWeight: 700 } }, props.version), !!props.trial && /* @__PURE__ */ React.createElement(Badge$1, { color: "violet", radius: "xs" }, "Trial"), /* @__PURE__ */ React.createElement(Burger, { opened: burgerOpen, onClick: toggle, className: classes.burger, size: "sm" })))), /* @__PURE__ */ React.createElement("div", { className: cx({ [classes.navBody]: !burgerOpen }) }, !props.loading && /* @__PURE__ */ React.createElement(
309
- UserButton,
310
- {
311
- className: classes.user,
312
- image: props.image,
313
- name: props.name,
314
- email: props.email
315
- }
316
- ), /* @__PURE__ */ React.createElement(Navbar$1.Section, { grow: true, className: classes.links, component: ScrollArea }, /* @__PURE__ */ React.createElement("div", { className: classes.linksInner }, links)), !props.loading && /* @__PURE__ */ React.createElement(Navbar$1.Section, { className: classes.footer }, props.trial && /* @__PURE__ */ React.createElement("a", { href: "#", className: classes.link, onClick: (event) => {
317
- event.preventDefault();
318
- props.onGettingStarted();
319
- } }, /* @__PURE__ */ React.createElement(IconVideo, { className: classes.linkIcon, stroke: 1.5 }), /* @__PURE__ */ React.createElement("span", null, "Getting started")), !!props.onSwitchAccounts && /* @__PURE__ */ React.createElement("a", { href: "#", className: classes.link, onClick: (event) => {
320
- event.preventDefault();
321
- props.onSwitchAccounts && props.onSwitchAccounts();
322
- } }, /* @__PURE__ */ React.createElement(IconSwitchHorizontal, { className: classes.linkIcon, stroke: 1.5 }), /* @__PURE__ */ React.createElement("span", null, "Change account")), /* @__PURE__ */ React.createElement("a", { href: "#", className: classes.link, onClick: (event) => {
323
- event.preventDefault();
324
- props.onLogout();
325
- } }, /* @__PURE__ */ React.createElement(IconLogout, { className: classes.linkIcon, stroke: 1.5 }), /* @__PURE__ */ React.createElement("span", null, "Logout"))))));
183
+ return /* @__PURE__ */ React.createElement("nav", { className: "flex h-full w-[230px] shrink-0 flex-col border-r border-slate-200 bg-white" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between border-b border-slate-100 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "w-24" }, /* @__PURE__ */ React.createElement("img", { className: "w-full object-contain", src: "https://cdn.localcivics.io/brand/localcivics.png", alt: "Logo" })), !!props.trial && /* @__PURE__ */ React.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.createElement(UserButton, { image: props.image, name: props.name, email: props.email }), /* @__PURE__ */ React.createElement("div", { className: "flex flex-1 flex-col gap-0.5 overflow-y-auto p-2.5" }, links), !props.loading && /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-0.5 border-t border-slate-200 p-2.5" }, props.trial && /* @__PURE__ */ React.createElement(UtilLink, { label: "Getting started", icon: IconVideo, onClick: props.onGettingStarted }), !!props.onSwitchAccounts && /* @__PURE__ */ React.createElement(UtilLink, { label: "Change account", icon: IconSwitchHorizontal, onClick: props.onSwitchAccounts }), /* @__PURE__ */ React.createElement(UtilLink, { label: "Logout", icon: IconLogout, onClick: props.onLogout })));
326
184
  }
185
+ const UtilLink = (props) => {
186
+ const Icon = props.icon;
187
+ return /* @__PURE__ */ React.createElement(
188
+ "div",
189
+ {
190
+ onClick: props.onClick,
191
+ 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"
192
+ },
193
+ /* @__PURE__ */ React.createElement(Icon, { size: 13, stroke: 1.75 }),
194
+ /* @__PURE__ */ React.createElement("span", { className: "text-[11.5px]" }, props.label)
195
+ );
196
+ };
327
197
 
328
- const useStyles$s = createStyles((theme) => ({
198
+ const useStyles$k = createStyles((theme) => ({
329
199
  inner: {
330
200
  paddingTop: theme.spacing.xl,
331
201
  paddingBottom: theme.spacing.xl * 4
@@ -361,7 +231,7 @@ const useStyles$s = createStyles((theme) => ({
361
231
  }
362
232
  }));
363
233
  const GettingStarted = (props) => {
364
- const { classes } = useStyles$s();
234
+ const { classes } = useStyles$k();
365
235
  return /* @__PURE__ */ React.createElement(
366
236
  Modal,
367
237
  {
@@ -375,7 +245,7 @@ const GettingStarted = (props) => {
375
245
  );
376
246
  };
377
247
 
378
- const useStyles$r = createStyles((theme) => ({
248
+ const useStyles$j = createStyles((theme) => ({
379
249
  title: {
380
250
  fontSize: 34,
381
251
  fontWeight: 900,
@@ -416,7 +286,7 @@ const useStyles$r = createStyles((theme) => ({
416
286
  }
417
287
  }));
418
288
  const SwitchAccount = (props) => {
419
- const { classes, theme } = useStyles$r();
289
+ const { classes, theme } = useStyles$j();
420
290
  const options = props.accounts.map((a) => {
421
291
  return /* @__PURE__ */ React.createElement(UnstyledButton, { onClick: () => props.onClick && props.onClick(a.accountId), key: a.accountId, p: theme.spacing.md }, /* @__PURE__ */ React.createElement(Card, { withBorder: true, shadow: "md", radius: "md", className: classes.card, p: "xl" }, a.isAdmin && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(IconBatteryEco, { size: 50, stroke: 2, color: theme.fn.primaryColor() })), a.isGroupAdmin && !a.isAdmin && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(IconBooks, { size: 50, stroke: 2, color: theme.fn.primaryColor() })), !a.isAdmin && !a.isGroupAdmin && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(IconBackpack, { size: 50, stroke: 2, color: theme.fn.primaryColor() })), /* @__PURE__ */ React.createElement(Text, { size: "lg", weight: 500, className: classes.cardTitle, mt: "md" }, a.name), /* @__PURE__ */ React.createElement(Text, { size: "sm", color: "dimmed", mt: "sm" }, a.isAdmin ? "Admin" : a.isGroupAdmin ? "Educator" : "Student")));
422
292
  });
@@ -433,51 +303,7 @@ const SwitchAccount = (props) => {
433
303
  );
434
304
  };
435
305
 
436
- const useStyles$q = createStyles((theme) => ({
437
- root: {
438
- display: "flex",
439
- backgroundImage: `linear-gradient(-60deg, ${theme.colors[theme.primaryColor][4]} 0%, ${theme.colors[theme.primaryColor][7]} 100%)`,
440
- padding: theme.spacing.xl * 1.5,
441
- borderRadius: theme.radius.md
442
- },
443
- title: {
444
- color: theme.white,
445
- textTransform: "uppercase",
446
- fontWeight: 700,
447
- fontSize: theme.fontSizes.sm
448
- },
449
- count: {
450
- color: theme.white,
451
- fontSize: 32,
452
- lineHeight: 1,
453
- fontWeight: 700,
454
- marginBottom: theme.spacing.md,
455
- fontFamily: `Greycliff CF, ${theme.fontFamily}`
456
- },
457
- description: {
458
- color: theme.colors[theme.primaryColor][0],
459
- fontSize: theme.fontSizes.sm,
460
- marginTop: 5
461
- },
462
- stat: {
463
- flex: 1,
464
- "& + &": {
465
- paddingLeft: theme.spacing.xl,
466
- marginLeft: theme.spacing.xl,
467
- borderLeft: `1px solid ${theme.colors[theme.primaryColor][3]}`,
468
- [theme.fn.smallerThan("sm")]: {
469
- paddingLeft: 0,
470
- marginLeft: 0,
471
- borderLeft: 0,
472
- paddingTop: theme.spacing.xl,
473
- marginTop: theme.spacing.xl,
474
- borderTop: `1px solid ${theme.colors[theme.primaryColor][3]}`
475
- }
476
- }
477
- }
478
- }));
479
306
  const StatsGroup = ({ data, footer }) => {
480
- const { classes } = useStyles$q();
481
307
  const stats = data.map((stat) => {
482
308
  const value = (() => {
483
309
  if (stat.unit === "%") {
@@ -486,9 +312,9 @@ const StatsGroup = ({ data, footer }) => {
486
312
  return stat.value;
487
313
  })();
488
314
  const safeValue = Number.isFinite(value) ? value : 0;
489
- return /* @__PURE__ */ React.createElement("div", { key: stat.title, className: classes.stat }, /* @__PURE__ */ React.createElement(Text, { className: classes.count }, safeValue.toLocaleString(), stat.unit), /* @__PURE__ */ React.createElement(Text, { className: classes.title }, stat.title));
315
+ return /* @__PURE__ */ React.createElement("div", { key: stat.title }, /* @__PURE__ */ React.createElement("div", { className: "text-3xl font-black text-white" }, safeValue.toLocaleString(), stat.unit), /* @__PURE__ */ React.createElement("div", { className: "mt-1.5 text-[11px] font-bold uppercase tracking-wide text-white/70" }, stat.title));
490
316
  });
491
- return /* @__PURE__ */ React.createElement("div", { className: classes.root }, stats, footer);
317
+ return /* @__PURE__ */ React.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);
492
318
  };
493
319
 
494
320
  const Tabs = (props) => {
@@ -497,7 +323,7 @@ const Tabs = (props) => {
497
323
  return /* @__PURE__ */ React.createElement(Tabs$1, { value: props.value, onTabChange: props.onChange }, /* @__PURE__ */ React.createElement(Tabs$1.List, null, tabs));
498
324
  };
499
325
 
500
- const useStyles$p = createStyles((theme) => ({
326
+ const useStyles$i = createStyles((theme) => ({
501
327
  button: {
502
328
  borderTopRightRadius: 0,
503
329
  borderBottomRightRadius: 0,
@@ -511,8 +337,8 @@ const useStyles$p = createStyles((theme) => ({
511
337
  borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
512
338
  }
513
339
  }));
514
- const SplitButton$5 = (props) => {
515
- const { classes, theme } = useStyles$p();
340
+ const SplitButton$4 = (props) => {
341
+ const { classes, theme } = useStyles$i();
516
342
  theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
517
343
  return /* @__PURE__ */ React.createElement(Stack$5, { spacing: "sm" }, /* @__PURE__ */ React.createElement(
518
344
  Button,
@@ -540,7 +366,7 @@ const SplitButton$5 = (props) => {
540
366
  ));
541
367
  };
542
368
 
543
- const useStyles$o = createStyles((theme) => ({
369
+ const useStyles$h = createStyles((theme) => ({
544
370
  wrapper: {
545
371
  display: "flex",
546
372
  alignItems: "center",
@@ -591,7 +417,7 @@ const useStyles$o = createStyles((theme) => ({
591
417
  }
592
418
  }));
593
419
  const PlaceholderBanner = (props) => {
594
- const { classes } = useStyles$o();
420
+ const { classes } = useStyles$h();
595
421
  const title = props.title || "Nothing to display";
596
422
  const description = props.description || "We don't have anything to show you here just yet. Add data, check back later, or adjust your search.";
597
423
  return /* @__PURE__ */ React.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React.createElement("div", { className: classes.body }, /* @__PURE__ */ React.createElement(Title, { className: classes.title }, props.loading ? "Loading..." : title), /* @__PURE__ */ React.createElement(Text, { size: "sm", color: "dimmed" }, props.loading ? "Hold on, we're loading your data." : description)), /* @__PURE__ */ React.createElement(Image, { src: `https://cdn.localcivics.io/illustrations/${props.icon}.svg`, className: classes.image }));
@@ -761,7 +587,7 @@ function Table$j(props) {
761
587
  ));
762
588
  }
763
589
 
764
- const useStyles$n = createStyles((theme) => ({
590
+ const useStyles$g = createStyles((theme) => ({
765
591
  title: {
766
592
  fontSize: 34,
767
593
  fontWeight: 900,
@@ -774,7 +600,7 @@ const useStyles$n = createStyles((theme) => ({
774
600
  }
775
601
  }));
776
602
  const Badge = (props) => {
777
- const { classes } = useStyles$n();
603
+ const { classes } = useStyles$g();
778
604
  const [tab, setTab] = useState("lessons");
779
605
  const numberOfStudents = props.students.length;
780
606
  const numberOfBadges = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length : 0;
@@ -788,7 +614,7 @@ const Badge = (props) => {
788
614
  },
789
615
  "Back"
790
616
  )), /* @__PURE__ */ React.createElement(Group, null, /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0 }, /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "Badge"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), !props.trial && /* @__PURE__ */ React.createElement(Stack$5, { ml: "auto" }, /* @__PURE__ */ React.createElement(
791
- SplitButton$5,
617
+ SplitButton$4,
792
618
  {
793
619
  href: props.href,
794
620
  onCopyLinkClick: props.onCopyLinkClick,
@@ -841,65 +667,34 @@ const Badge = (props) => {
841
667
  };
842
668
 
843
669
  function Table$i(props) {
670
+ if (props.loading) {
671
+ return /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Loading\u2026");
672
+ }
844
673
  if (props.items.length === 0) {
845
- return /* @__PURE__ */ React.createElement(
846
- PlaceholderBanner,
847
- {
848
- title: "No badges to display",
849
- description: "We don't have any badges to show you just yet.",
850
- loading: props.loading,
851
- icon: "badges"
852
- }
853
- );
674
+ return /* @__PURE__ */ React.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.");
854
675
  }
855
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement("tr", { key: row.badgeId }, /* @__PURE__ */ React.createElement("td", null, /* @__PURE__ */ React.createElement(
856
- UnstyledButton,
676
+ return /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm" }, props.items.map((row, i) => /* @__PURE__ */ React.createElement(
677
+ Link,
857
678
  {
858
- component: Link,
679
+ key: row.badgeId,
859
680
  to: row.href,
860
- sx: (theme) => ({
861
- display: "block",
862
- width: "100%",
863
- padding: theme.spacing.md,
864
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
865
- "&:hover": {
866
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.colors.gray[1]
867
- }
868
- })
681
+ className: `block px-5 py-4 no-underline hover:bg-slate-50 ${i < props.items.length - 1 ? "border-b border-slate-100" : ""}`
869
682
  },
870
- /* @__PURE__ */ React.createElement(Group, null, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React.createElement(Text, { size: "xs", color: "dimmed" }, row.description)))
871
- ))));
872
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(Table$l, { horizontalSpacing: 0, verticalSpacing: 0, sx: { minWidth: 700 } }, /* @__PURE__ */ React.createElement("tbody", null, rows)));
683
+ /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, row.name),
684
+ row.description && /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs leading-relaxed text-slate-500" }, row.description)
685
+ )));
873
686
  }
874
687
 
875
- const useStyles$m = createStyles((theme) => ({
876
- title: {
877
- fontSize: 34,
878
- fontWeight: 900,
879
- [theme.fn.smallerThan("sm")]: {
880
- fontSize: 24
881
- }
882
- },
883
- description: {
884
- maxWidth: 600
885
- }
886
- }));
887
688
  const Badges = (props) => {
888
- const { classes } = useStyles$m();
889
- return /* @__PURE__ */ React.createElement(Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: "md" }, /* @__PURE__ */ React.createElement(Grid, null, /* @__PURE__ */ React.createElement(Grid.Col, { sm: "auto" }, /* @__PURE__ */ React.createElement(Badge$1, { variant: "filled", size: "lg" }, "Badges"), /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, "Badges and micro-credentials"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Key milestones that reflect skill development, micro-credentials, or academic progress"))), /* @__PURE__ */ React.createElement(
890
- Autocomplete,
689
+ return /* @__PURE__ */ React.createElement("div", { className: "mx-auto flex max-w-4xl flex-col gap-5 px-4 py-8" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React.createElement("h1", { className: "text-2xl font-extrabold tracking-tight text-dark-blue-400" }, "Badges and micro-credentials"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-500" }, "Project-sized skills acquisition and standards alignment.")), /* @__PURE__ */ React.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.createElement(IconSearch, { size: 15, stroke: 1.75, className: "text-slate-400" }), /* @__PURE__ */ React.createElement(
690
+ "input",
891
691
  {
692
+ type: "text",
892
693
  placeholder: "Search for a badge that fits your needs",
893
- data: props.badges.map((item) => item.name),
894
- onChange: props.onAutocompleteChange
895
- }
896
- ), /* @__PURE__ */ React.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React.createElement(LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React.createElement(
897
- Table$i,
898
- {
899
- loading: props.loading,
900
- items: props.badges
694
+ onChange: (e) => props.onAutocompleteChange(e.target.value),
695
+ className: "flex-1 border-none bg-transparent text-sm text-dark-blue-400 outline-none placeholder:text-slate-400"
901
696
  }
902
- ))));
697
+ )), /* @__PURE__ */ React.createElement(Table$i, { loading: props.loading, items: props.badges }));
903
698
  };
904
699
 
905
700
  function Table$h(props) {
@@ -1090,30 +885,58 @@ const Dashboard = (props) => {
1090
885
  )))))));
1091
886
  };
1092
887
 
1093
- const SplitButton$4 = (props) => {
1094
- return /* @__PURE__ */ React.createElement(Stack$5, { spacing: "sm" }, /* @__PURE__ */ React.createElement(
1095
- Button,
1096
- {
1097
- leftIcon: /* @__PURE__ */ React.createElement(IconPlaylistAdd, { size: 14 }),
1098
- onClick: props.onAddMembersClick
1099
- },
1100
- "Add students"
1101
- ), /* @__PURE__ */ React.createElement(
1102
- Button,
1103
- {
1104
- leftIcon: /* @__PURE__ */ React.createElement(IconClipboardCopy, { size: 14 }),
1105
- onClick: props.onCopyClassLinkClick
1106
- },
1107
- "Copy link"
1108
- ), /* @__PURE__ */ React.createElement(
1109
- Button,
1110
- {
1111
- leftIcon: /* @__PURE__ */ React.createElement(IconTableExport, { size: 14 }),
1112
- onClick: props.onExportDataClick
1113
- },
1114
- "Export data (.csv)"
1115
- ));
1116
- };
888
+ const openDeleteModal = (student, onDelete) => openConfirmModal({
889
+ title: `Remove "${student.givenName && student.familyName ? `${student.givenName} ${student.familyName}` : student.email}" from this class?`,
890
+ centered: true,
891
+ children: /* @__PURE__ */ React.createElement(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."),
892
+ labels: { confirm: "Remove Student", cancel: "Cancel" },
893
+ confirmProps: { color: "red" },
894
+ onConfirm: () => onDelete(student)
895
+ });
896
+ function Table$c(props) {
897
+ if (props.loading) {
898
+ return /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Loading\u2026");
899
+ }
900
+ if (props.items.length === 0) {
901
+ return /* @__PURE__ */ React.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.");
902
+ }
903
+ return /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.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.createElement("div", null, "Name"), /* @__PURE__ */ React.createElement("div", null, "Role"), /* @__PURE__ */ React.createElement("div", null, "Badges Earned"), /* @__PURE__ */ React.createElement("div", null, "Lessons Completed"), /* @__PURE__ */ React.createElement("div", null, "Account Created?"), /* @__PURE__ */ React.createElement("div", null)), props.items.map((row, i) => {
904
+ var _a, _b;
905
+ const name = row.givenName && row.familyName ? `${row.givenName} ${row.familyName}` : row.email;
906
+ const initials = (((_a = row.givenName) == null ? void 0 : _a[0]) || row.email[0] || "?") + (((_b = row.familyName) == null ? void 0 : _b[0]) || "");
907
+ return /* @__PURE__ */ React.createElement(
908
+ "div",
909
+ {
910
+ key: row.email,
911
+ 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" : ""}`
912
+ },
913
+ /* @__PURE__ */ React.createElement(Link, { to: row.href, className: "flex min-w-0 items-center gap-2.5 no-underline" }, row.avatar ? /* @__PURE__ */ React.createElement("img", { className: "h-8 w-8 shrink-0 rounded-full object-cover", src: row.avatar, alt: name }) : /* @__PURE__ */ React.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.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs font-bold text-dark-blue-400" }, name), /* @__PURE__ */ React.createElement("div", { className: "truncate text-[10.5px] text-slate-400" }, row.email))),
914
+ /* @__PURE__ */ React.createElement(
915
+ "select",
916
+ {
917
+ disabled: row.readonly,
918
+ value: row.isAdmin ? "educator" : "student",
919
+ onChange: (e) => props.onRoleChange && props.onRoleChange(row, e.target.value),
920
+ 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"
921
+ },
922
+ /* @__PURE__ */ React.createElement("option", { value: "student" }, "Student"),
923
+ /* @__PURE__ */ React.createElement("option", { value: "educator" }, "Educator")
924
+ ),
925
+ /* @__PURE__ */ React.createElement("div", { className: "text-xs font-bold text-dark-blue-400" }, row.badgesEarned),
926
+ /* @__PURE__ */ React.createElement("div", { className: "text-xs font-bold text-dark-blue-400" }, row.lessonsCompleted),
927
+ /* @__PURE__ */ React.createElement("div", null, row.hasAccount && /* @__PURE__ */ React.createElement(IconCheck, { size: 16, stroke: 3, className: "text-mint-400" })),
928
+ /* @__PURE__ */ React.createElement("div", null, !row.readonly && !!props.onDelete && /* @__PURE__ */ React.createElement(
929
+ "button",
930
+ {
931
+ type: "button",
932
+ onClick: () => openDeleteModal(row, props.onDelete),
933
+ className: "flex h-7 w-7 items-center justify-center rounded-md text-slate-300 hover:bg-red-50 hover:text-red-500"
934
+ },
935
+ /* @__PURE__ */ React.createElement(IconTrash, { size: 14, stroke: 1.75 })
936
+ ))
937
+ );
938
+ }));
939
+ }
1117
940
 
1118
941
  var __defProp$c = Object.defineProperty;
1119
942
  var __defProps$8 = Object.defineProperties;
@@ -1134,225 +957,46 @@ var __spreadValues$c = (a, b) => {
1134
957
  return a;
1135
958
  };
1136
959
  var __spreadProps$8 = (a, b) => __defProps$8(a, __getOwnPropDescs$8(b));
1137
- function Table$c(props) {
1138
- const preparedItems = React.useMemo(() => {
1139
- return props.items.map((item) => __spreadProps$8(__spreadValues$c({}, item), {
1140
- fullName: item.givenName && item.familyName ? `${item.givenName} ${item.familyName}`.toLowerCase() : item.email.toLowerCase()
1141
- }));
1142
- }, [props.items]);
1143
- console.groupEnd();
1144
- const { items: sortedItems, requestSort, sortConfig } = useSortableData(preparedItems);
1145
- if (props.items.length === 0) {
1146
- return /* @__PURE__ */ React.createElement(
1147
- PlaceholderBanner,
1148
- {
1149
- title: "No members to display",
1150
- description: "You have not rostered any students yet.",
1151
- loading: props.loading,
1152
- icon: "groups"
1153
- }
1154
- );
1155
- }
1156
- const sortStatus = {
1157
- columnAccessor: sortConfig.key,
1158
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
1159
- };
1160
- const openDeleteModal = (student) => openConfirmModal({
1161
- title: `Remove "${student.givenName && student.familyName ? `${student.givenName} ${student.familyName}` : student.email}" from this class?`,
1162
- centered: true,
1163
- children: /* @__PURE__ */ React.createElement(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."),
1164
- labels: { confirm: "Remove Student", cancel: "Cancel" },
1165
- confirmProps: { color: "red" },
1166
- onConfirm: () => props.onDelete && props.onDelete(student)
1167
- });
1168
- return /* @__PURE__ */ React.createElement(ScrollArea, null, /* @__PURE__ */ React.createElement(
1169
- DataTable,
1170
- {
1171
- verticalSpacing: 20,
1172
- sx: { minWidth: 700 },
1173
- highlightOnHover: true,
1174
- striped: true,
1175
- records: sortedItems,
1176
- idAccessor: "email",
1177
- sortStatus,
1178
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
1179
- columns: [
1180
- {
1181
- accessor: "fullName",
1182
- title: "Name",
1183
- sortable: true,
1184
- render: (row) => /* @__PURE__ */ React.createElement(UnstyledButton, { component: Link, to: row.href }, /* @__PURE__ */ React.createElement(Group, { spacing: "sm" }, /* @__PURE__ */ React.createElement(Avatar, { size: 40, src: row.avatar, radius: 40 }), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Text, { size: "sm", weight: 500 }, row.givenName && row.familyName ? `${row.givenName} ${row.familyName}` : row.email), /* @__PURE__ */ React.createElement(Text, { size: "xs", color: "dimmed" }, row.email))))
1185
- },
1186
- {
1187
- accessor: "isAdmin",
1188
- title: "Role",
1189
- sortable: true,
1190
- render: (row) => /* @__PURE__ */ React.createElement(Box, { maw: 150 }, /* @__PURE__ */ React.createElement(
1191
- Select,
1192
- {
1193
- size: "sm",
1194
- disabled: row.readonly,
1195
- value: row.isAdmin ? "educator" : "student",
1196
- onChange: (value) => props.onRoleChange && props.onRoleChange(row, value),
1197
- data: [
1198
- { label: "Student", value: "student" },
1199
- { label: "Educator", value: "educator" }
1200
- ]
1201
- }
1202
- ))
1203
- },
1204
- {
1205
- accessor: "badgesEarned",
1206
- title: "Badges Earned",
1207
- sortable: true
1208
- },
1209
- {
1210
- accessor: "lessonsCompleted",
1211
- title: "Lessons Completed",
1212
- sortable: true
1213
- },
1214
- {
1215
- accessor: "hasAccount",
1216
- title: "Account Created?",
1217
- sortable: true,
1218
- render: (row) => row.hasAccount ? /* @__PURE__ */ React.createElement(IconCheck, { color: "green" }) : null
1219
- },
1220
- {
1221
- accessor: "actions",
1222
- title: "",
1223
- textAlignment: "right",
1224
- render: (row) => /* @__PURE__ */ React.createElement(Group, { noWrap: true, spacing: 0, position: "right" }, !row.readonly && !!props.onDelete && /* @__PURE__ */ React.createElement(ActionIcon, { color: "red", onClick: () => openDeleteModal(row) }, /* @__PURE__ */ React.createElement(IconTrash, { size: 16, stroke: 1.5 })))
1225
- }
1226
- ]
1227
- }
1228
- ));
1229
- }
1230
-
1231
- var __defProp$b = Object.defineProperty;
1232
- var __defProps$7 = Object.defineProperties;
1233
- var __getOwnPropDescs$7 = Object.getOwnPropertyDescriptors;
1234
- var __getOwnPropSymbols$b = Object.getOwnPropertySymbols;
1235
- var __hasOwnProp$b = Object.prototype.hasOwnProperty;
1236
- var __propIsEnum$b = Object.prototype.propertyIsEnumerable;
1237
- var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1238
- var __spreadValues$b = (a, b) => {
1239
- for (var prop in b || (b = {}))
1240
- if (__hasOwnProp$b.call(b, prop))
1241
- __defNormalProp$b(a, prop, b[prop]);
1242
- if (__getOwnPropSymbols$b)
1243
- for (var prop of __getOwnPropSymbols$b(b)) {
1244
- if (__propIsEnum$b.call(b, prop))
1245
- __defNormalProp$b(a, prop, b[prop]);
1246
- }
1247
- return a;
1248
- };
1249
- var __spreadProps$7 = (a, b) => __defProps$7(a, __getOwnPropDescs$7(b));
1250
- const useStyles$l = createStyles((theme) => ({
1251
- title: {
1252
- fontSize: 34,
1253
- fontWeight: 900,
1254
- [theme.fn.smallerThan("sm")]: {
1255
- fontSize: 24
1256
- }
1257
- },
1258
- description: {
1259
- maxWidth: 600
1260
- },
1261
- autocomplete: {
1262
- maxWidth: 400
1263
- },
1264
- wrapper: {
1265
- position: "relative",
1266
- marginBottom: 30
1267
- },
1268
- dropzone: {
1269
- borderWidth: 1,
1270
- paddingBottom: 50
1271
- },
1272
- icon: {
1273
- color: theme.colorScheme === "dark" ? theme.colors.dark[3] : theme.colors.gray[4]
1274
- },
1275
- control: {
1276
- position: "absolute",
1277
- width: 250,
1278
- left: "calc(50% - 125px)",
1279
- bottom: -20
1280
- }
1281
- }));
1282
- const Class = (props) => {
1283
- const { classes } = useStyles$l();
1284
- const form = useForm({
1285
- initialValues: {
1286
- classId: "",
1287
- userId: "",
1288
- email: "",
1289
- givenName: "",
1290
- familyName: "",
1291
- avatar: "",
1292
- role: "",
1293
- readonly: false,
1294
- lastActivity: null,
1295
- hasAccount: false,
1296
- lessonsCompleted: 0,
1297
- badgesEarned: 0,
1298
- href: "",
1299
- isAdmin: false
1300
- },
1301
- validate: {
1302
- email: (value) => /^\S+@\S+$/.test(value) && props.members.filter((u) => u.email === value).length === 0 ? null : "Invalid email"
1303
- }
1304
- });
1305
- const [opened, setOpened] = useState(false);
1306
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
1307
- Drawer,
960
+ const Class = (props) => {
961
+ const [opened, setOpened] = useState(false);
962
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
963
+ Drawer,
1308
964
  {
1309
965
  opened,
1310
966
  onClose: () => setOpened(false),
1311
- title: /* @__PURE__ */ React.createElement(Title, { size: "h5" }, "Add students"),
967
+ title: "Add students",
1312
968
  padding: "xl",
1313
969
  size: "xl"
1314
970
  },
1315
- /* @__PURE__ */ React.createElement(Stack$5, { spacing: "md" }, /* @__PURE__ */ React.createElement(DropzoneButton$1, __spreadProps$7(__spreadValues$b({}, props), { close: () => setOpened(false) })), /* @__PURE__ */ React.createElement(Divider, { label: "or", labelPosition: "center", my: "md", variant: "dashed" }), /* @__PURE__ */ React.createElement("form", { onSubmit: form.onSubmit(() => {
1316
- const values = form.values;
1317
- form.reset();
1318
- setOpened(false);
1319
- props.onCreateMembers && props.onCreateMembers([values]);
1320
- }) }, /* @__PURE__ */ React.createElement(Stack$5, null, /* @__PURE__ */ React.createElement(
1321
- TextInput,
1322
- __spreadValues$b({
1323
- withAsterisk: true,
1324
- label: "Email",
1325
- placeholder: "Email"
1326
- }, form.getInputProps("email"))
1327
- ), /* @__PURE__ */ React.createElement(Group, { grow: true }, /* @__PURE__ */ React.createElement(
1328
- TextInput,
1329
- __spreadValues$b({
1330
- label: "Given name",
1331
- placeholder: "Given name"
1332
- }, form.getInputProps("givenName"))
1333
- ), /* @__PURE__ */ React.createElement(
1334
- TextInput,
1335
- __spreadValues$b({
1336
- label: "Family name",
1337
- placeholder: "Family name"
1338
- }, form.getInputProps("familyName"))
1339
- )), /* @__PURE__ */ React.createElement(Button, { type: "submit", fullWidth: true, mt: "md" }, "Submit"))))
1340
- ), /* @__PURE__ */ React.createElement(Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: "md" }, /* @__PURE__ */ React.createElement(Grid, null, /* @__PURE__ */ React.createElement(Grid.Col, { sm: "auto" }, /* @__PURE__ */ React.createElement(UnstyledButton, { onClick: props.onBackClick }, /* @__PURE__ */ React.createElement(
1341
- Badge$1,
971
+ /* @__PURE__ */ React.createElement(DropzoneButton$1, __spreadProps$8(__spreadValues$c({}, props), { close: () => setOpened(false) }))
972
+ ), /* @__PURE__ */ React.createElement("div", { className: "mx-auto flex max-w-5xl flex-col gap-5 px-4 py-8" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-start justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React.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.createElement(IconArrowLeft, { size: 13, stroke: 2.5 }), "Back"), /* @__PURE__ */ React.createElement("h1", { className: "text-2xl font-extrabold tracking-tight text-dark-blue-400" }, props.displayName || "Class"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-500" }, props.description || "No description")), !props.loading && /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement(
973
+ "button",
1342
974
  {
1343
- variant: "filled",
1344
- leftSection: /* @__PURE__ */ React.createElement(ActionIcon, { color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React.createElement(IconArrowLeft, { size: 14 })),
1345
- size: "lg"
975
+ type: "button",
976
+ onClick: () => setOpened(true),
977
+ 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"
1346
978
  },
1347
- "Back"
1348
- )), /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "Class"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), /* @__PURE__ */ React.createElement(Grid.Col, { sm: "content" }, !props.loading && /* @__PURE__ */ React.createElement(
1349
- SplitButton$4,
979
+ /* @__PURE__ */ React.createElement(IconPlus, { size: 13, stroke: 2 }),
980
+ "Add students"
981
+ ), /* @__PURE__ */ React.createElement(
982
+ "button",
1350
983
  {
1351
- onAddMembersClick: () => setOpened(true),
1352
- onCopyClassLinkClick: props.onCopyLinkClick,
1353
- onExportDataClick: props.onExportDataClick
1354
- }
1355
- ))), /* @__PURE__ */ React.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React.createElement(LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React.createElement(Stack$5, { spacing: "sm" }, /* @__PURE__ */ React.createElement(StatsGroup, { data: [
984
+ type: "button",
985
+ onClick: props.onCopyLinkClick,
986
+ 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"
987
+ },
988
+ /* @__PURE__ */ React.createElement(IconLink, { size: 13, stroke: 2 }),
989
+ "Copy class link"
990
+ ), /* @__PURE__ */ React.createElement(
991
+ "button",
992
+ {
993
+ type: "button",
994
+ onClick: props.onExportDataClick,
995
+ 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)]"
996
+ },
997
+ /* @__PURE__ */ React.createElement(IconDownload, { size: 13, stroke: 2 }),
998
+ "Export data (.csv)"
999
+ ))), /* @__PURE__ */ React.createElement(StatsGroup, { data: [
1356
1000
  {
1357
1001
  title: "# OF STUDENTS",
1358
1002
  value: props.members.filter((a) => !a.isAdmin).length
@@ -1378,10 +1022,30 @@ const Class = (props) => {
1378
1022
  onDelete: props.onDeleteMember,
1379
1023
  onRoleChange: props.onChangeUserRole
1380
1024
  }
1381
- ))))));
1025
+ )));
1382
1026
  };
1383
1027
  const DropzoneButton$1 = (props) => {
1384
- const { classes, theme } = useStyles$l();
1028
+ const form = useForm({
1029
+ initialValues: {
1030
+ classId: "",
1031
+ userId: "",
1032
+ email: "",
1033
+ givenName: "",
1034
+ familyName: "",
1035
+ avatar: "",
1036
+ role: "",
1037
+ readonly: false,
1038
+ lastActivity: null,
1039
+ hasAccount: false,
1040
+ lessonsCompleted: 0,
1041
+ badgesEarned: 0,
1042
+ href: "",
1043
+ isAdmin: false
1044
+ },
1045
+ validate: {
1046
+ email: (value) => /^\S+@\S+$/.test(value) && props.members.filter((u) => u.email === value).length === 0 ? null : "Invalid email"
1047
+ }
1048
+ });
1385
1049
  const openRef = React.useRef(null);
1386
1050
  const [loading, setLoading] = React.useState(false);
1387
1051
  const onDrop = React.useCallback((acceptedFiles) => {
@@ -1402,29 +1066,59 @@ const DropzoneButton$1 = (props) => {
1402
1066
  });
1403
1067
  });
1404
1068
  }, []);
1405
- return /* @__PURE__ */ React.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React.createElement(
1069
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4" }, /* @__PURE__ */ React.createElement(
1406
1070
  Dropzone,
1407
1071
  {
1408
1072
  loading,
1409
1073
  openRef,
1410
1074
  onDrop,
1411
- className: classes.dropzone,
1412
- radius: "md",
1413
1075
  accept: [MIME_TYPES.csv],
1414
1076
  maxSize: 5 * 1024 ** 2
1415
1077
  },
1416
- /* @__PURE__ */ React.createElement("div", { style: { pointerEvents: "none" } }, /* @__PURE__ */ React.createElement(Group, { position: "center" }, /* @__PURE__ */ React.createElement(Dropzone.Accept, null, /* @__PURE__ */ React.createElement(IconDownload, { size: 50, color: theme.colors[theme.primaryColor][6], stroke: 1.5 })), /* @__PURE__ */ React.createElement(Dropzone.Reject, null, /* @__PURE__ */ React.createElement(IconX, { size: 50, color: theme.colors.red[6], stroke: 1.5 })), /* @__PURE__ */ React.createElement(Dropzone.Idle, null, /* @__PURE__ */ React.createElement(
1417
- IconCloudUpload,
1418
- {
1419
- size: 50,
1420
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
1421
- stroke: 1.5
1422
- }
1423
- ))), /* @__PURE__ */ React.createElement(Text, { align: "center", weight: 700, size: "lg", mt: "xl" }, /* @__PURE__ */ React.createElement(Dropzone.Accept, null, "Drop files here"), /* @__PURE__ */ React.createElement(Dropzone.Reject, null, "Csv file less than 5mb"), /* @__PURE__ */ React.createElement(Dropzone.Idle, null, "Upload multiple")), /* @__PURE__ */ React.createElement(Text, { align: "center", size: "sm", mt: "xs", color: "dimmed" }, "Drag'n'drop files here to upload. We can accept only ", /* @__PURE__ */ React.createElement("i", null, ".csv"), " files that are less than 5mb in size."))
1424
- ), /* @__PURE__ */ React.createElement(Button, { className: classes.control, size: "md", radius: "xl", onClick: () => {
1425
- var _a;
1426
- return (_a = openRef.current) == null ? void 0 : _a.call(openRef);
1427
- } }, "Select file"));
1078
+ /* @__PURE__ */ React.createElement("div", { style: { pointerEvents: "none" } }, /* @__PURE__ */ React.createElement(Group, { position: "center" }, /* @__PURE__ */ React.createElement(IconCloudUpload, { size: 50, stroke: 1.5 })), /* @__PURE__ */ React.createElement("p", { className: "mt-6 text-center text-lg font-bold text-dark-blue-400" }, "Upload multiple"), /* @__PURE__ */ React.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.createElement("i", null, ".csv"), " files that are less than 5mb in size."))
1079
+ ), /* @__PURE__ */ React.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React.createElement(
1080
+ "button",
1081
+ {
1082
+ type: "button",
1083
+ onClick: () => {
1084
+ var _a;
1085
+ return (_a = openRef.current) == null ? void 0 : _a.call(openRef);
1086
+ },
1087
+ className: "rounded-full bg-dark-blue-400 px-6 py-2.5 text-xs font-bold text-white"
1088
+ },
1089
+ "Select file"
1090
+ )), /* @__PURE__ */ React.createElement(Divider, { label: "or", labelPosition: "center", my: "md", variant: "dashed" }), /* @__PURE__ */ React.createElement("form", { onSubmit: form.onSubmit(() => {
1091
+ const values = form.values;
1092
+ form.reset();
1093
+ props.close();
1094
+ props.onCreateMembers && props.onCreateMembers([values]);
1095
+ }) }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement(
1096
+ TextInput,
1097
+ __spreadValues$c({
1098
+ withAsterisk: true,
1099
+ label: "Email",
1100
+ placeholder: "Email"
1101
+ }, form.getInputProps("email"))
1102
+ ), /* @__PURE__ */ React.createElement(Group, { grow: true }, /* @__PURE__ */ React.createElement(
1103
+ TextInput,
1104
+ __spreadValues$c({
1105
+ label: "Given name",
1106
+ placeholder: "Given name"
1107
+ }, form.getInputProps("givenName"))
1108
+ ), /* @__PURE__ */ React.createElement(
1109
+ TextInput,
1110
+ __spreadValues$c({
1111
+ label: "Family name",
1112
+ placeholder: "Family name"
1113
+ }, form.getInputProps("familyName"))
1114
+ )), /* @__PURE__ */ React.createElement(
1115
+ "button",
1116
+ {
1117
+ type: "submit",
1118
+ className: "mt-2 rounded-lg bg-dark-blue-400 px-4 py-2.5 text-xs font-bold text-white"
1119
+ },
1120
+ "Submit"
1121
+ ))));
1428
1122
  };
1429
1123
 
1430
1124
  function Table$b(props) {
@@ -1493,23 +1187,23 @@ function Table$b(props) {
1493
1187
  ));
1494
1188
  }
1495
1189
 
1496
- var __defProp$a = Object.defineProperty;
1497
- var __getOwnPropSymbols$a = Object.getOwnPropertySymbols;
1498
- var __hasOwnProp$a = Object.prototype.hasOwnProperty;
1499
- var __propIsEnum$a = Object.prototype.propertyIsEnumerable;
1500
- var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1501
- var __spreadValues$a = (a, b) => {
1190
+ var __defProp$b = Object.defineProperty;
1191
+ var __getOwnPropSymbols$b = Object.getOwnPropertySymbols;
1192
+ var __hasOwnProp$b = Object.prototype.hasOwnProperty;
1193
+ var __propIsEnum$b = Object.prototype.propertyIsEnumerable;
1194
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1195
+ var __spreadValues$b = (a, b) => {
1502
1196
  for (var prop in b || (b = {}))
1503
- if (__hasOwnProp$a.call(b, prop))
1504
- __defNormalProp$a(a, prop, b[prop]);
1505
- if (__getOwnPropSymbols$a)
1506
- for (var prop of __getOwnPropSymbols$a(b)) {
1507
- if (__propIsEnum$a.call(b, prop))
1508
- __defNormalProp$a(a, prop, b[prop]);
1197
+ if (__hasOwnProp$b.call(b, prop))
1198
+ __defNormalProp$b(a, prop, b[prop]);
1199
+ if (__getOwnPropSymbols$b)
1200
+ for (var prop of __getOwnPropSymbols$b(b)) {
1201
+ if (__propIsEnum$b.call(b, prop))
1202
+ __defNormalProp$b(a, prop, b[prop]);
1509
1203
  }
1510
1204
  return a;
1511
1205
  };
1512
- const useStyles$k = createStyles((theme) => ({
1206
+ const useStyles$f = createStyles((theme) => ({
1513
1207
  title: {
1514
1208
  fontSize: 34,
1515
1209
  fontWeight: 900,
@@ -1522,7 +1216,7 @@ const useStyles$k = createStyles((theme) => ({
1522
1216
  }
1523
1217
  }));
1524
1218
  const Classes = (props) => {
1525
- const { classes } = useStyles$k();
1219
+ const { classes } = useStyles$f();
1526
1220
  const form = useForm({
1527
1221
  initialValues: {
1528
1222
  classId: "",
@@ -1552,14 +1246,14 @@ const Classes = (props) => {
1552
1246
  props.onCreateClass && props.onCreateClass(values);
1553
1247
  }) }, /* @__PURE__ */ React.createElement(Stack$5, null, /* @__PURE__ */ React.createElement(
1554
1248
  TextInput,
1555
- __spreadValues$a({
1249
+ __spreadValues$b({
1556
1250
  withAsterisk: true,
1557
1251
  label: "Name",
1558
1252
  placeholder: "Class name"
1559
1253
  }, form.getInputProps("name"))
1560
1254
  ), /* @__PURE__ */ React.createElement(
1561
1255
  TextInput,
1562
- __spreadValues$a({
1256
+ __spreadValues$b({
1563
1257
  label: "Description",
1564
1258
  placeholder: "A class for my first period English students"
1565
1259
  }, form.getInputProps("description"))
@@ -1593,7 +1287,7 @@ const Classes = (props) => {
1593
1287
  ))))));
1594
1288
  };
1595
1289
 
1596
- const useStyles$j = createStyles((theme) => ({
1290
+ const useStyles$e = createStyles((theme) => ({
1597
1291
  title: {
1598
1292
  fontSize: 34,
1599
1293
  fontWeight: 900,
@@ -1607,7 +1301,7 @@ const useStyles$j = createStyles((theme) => ({
1607
1301
  }
1608
1302
  }));
1609
1303
  const UserInfo = (props) => {
1610
- const { classes } = useStyles$j();
1304
+ const { classes } = useStyles$e();
1611
1305
  return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Title, { className: classes.title }, props.name), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "xs" }, props.impactStatement));
1612
1306
  };
1613
1307
 
@@ -1745,229 +1439,98 @@ const Student = (props) => {
1745
1439
  ))))));
1746
1440
  };
1747
1441
 
1748
- const useStyles$i = createStyles((theme, props) => {
1749
- const from = props.from || "blue";
1750
- const to = props.to || "green";
1751
- return {
1752
- card: {
1753
- position: "relative",
1754
- cursor: "pointer",
1755
- overflow: "hidden",
1756
- transition: "transform 150ms ease, box-shadow 100ms ease",
1757
- padding: theme.spacing.xl,
1758
- paddingLeft: theme.spacing.xl * 2,
1759
- "&:hover": {
1760
- boxShadow: theme.shadows.md,
1761
- transform: "scale(1.02)"
1762
- },
1763
- "&::before": {
1764
- content: '""',
1765
- position: "absolute",
1766
- top: 0,
1767
- bottom: 0,
1768
- left: 0,
1769
- width: 6,
1770
- backgroundImage: theme.fn.linearGradient(0, theme.colors[from][6], theme.colors[to][6])
1771
- }
1772
- }
1773
- };
1774
- });
1442
+ const ACCENT_BORDER = {
1443
+ cyan: "border-l-sky-blue-400",
1444
+ mint: "border-l-mint-400",
1445
+ gold: "border-l-gold-400"
1446
+ };
1447
+ const ACCENT_GRADIENT = {
1448
+ cyan: "from-sky-blue-400",
1449
+ mint: "from-mint-400",
1450
+ gold: "from-gold-400"
1451
+ };
1775
1452
  function CardGradient(props) {
1776
- const { classes } = useStyles$i(props);
1777
- const from = props.from || "blue";
1778
- const to = props.to || "green";
1779
- const icon = props.icon || /* @__PURE__ */ React.createElement(IconColorSwatch, { size: 28, stroke: 1.5 });
1780
- return /* @__PURE__ */ React.createElement(Paper, { withBorder: true, radius: "md", className: classes.card, onClick: props.onClick }, /* @__PURE__ */ React.createElement(
1781
- ThemeIcon,
1782
- {
1783
- size: "xl",
1784
- radius: "md",
1785
- variant: "gradient",
1786
- gradient: { deg: 0, from, to }
1453
+ const accent = props.accent || "cyan";
1454
+ return /* @__PURE__ */ React.createElement(
1455
+ "div",
1456
+ {
1457
+ onClick: props.onClick,
1458
+ className: `flex cursor-pointer items-center gap-[18px] rounded-2xl border border-l-4 border-slate-200 bg-white px-[22px] py-[18px] transition-transform hover:scale-[1.02] hover:shadow-md ${ACCENT_BORDER[accent]}`
1787
1459
  },
1788
- icon
1789
- ), /* @__PURE__ */ React.createElement(Text, { size: "xl", weight: 500, mt: "md" }, props.title), /* @__PURE__ */ React.createElement(Text, { size: "sm", mt: "sm", color: "dimmed" }, props.description));
1460
+ /* @__PURE__ */ React.createElement("div", { className: `flex h-10 w-10 shrink-0 items-center justify-center rounded-[10px] bg-gradient-to-br ${ACCENT_GRADIENT[accent]} to-dark-blue-400 text-white` }, props.icon),
1461
+ /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-[15.5px] font-extrabold text-dark-blue-400" }, props.title), /* @__PURE__ */ React.createElement("div", { className: "mt-0.5 text-xs text-slate-500" }, props.description))
1462
+ );
1790
1463
  }
1791
1464
 
1792
- var __defProp$9 = Object.defineProperty;
1793
- var __getOwnPropSymbols$9 = Object.getOwnPropertySymbols;
1794
- var __hasOwnProp$9 = Object.prototype.hasOwnProperty;
1795
- var __propIsEnum$9 = Object.prototype.propertyIsEnumerable;
1796
- var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1797
- var __spreadValues$9 = (a, b) => {
1798
- for (var prop in b || (b = {}))
1799
- if (__hasOwnProp$9.call(b, prop))
1800
- __defNormalProp$9(a, prop, b[prop]);
1801
- if (__getOwnPropSymbols$9)
1802
- for (var prop of __getOwnPropSymbols$9(b)) {
1803
- if (__propIsEnum$9.call(b, prop))
1804
- __defNormalProp$9(a, prop, b[prop]);
1465
+ const Home = (props) => {
1466
+ const accessCode = props.organization.accessCode;
1467
+ const onCopyAccessCode = async () => {
1468
+ if (!accessCode)
1469
+ return;
1470
+ try {
1471
+ await navigator.clipboard.writeText(accessCode);
1472
+ showNotification({
1473
+ title: "Copied!",
1474
+ message: "Community code copied to clipboard.",
1475
+ autoClose: 3e3
1476
+ });
1477
+ } catch (err) {
1478
+ console.error("Failed to copy code", err);
1805
1479
  }
1806
- return a;
1807
- };
1808
- var __objRest$1 = (source, exclude) => {
1809
- var target = {};
1810
- for (var prop in source)
1811
- if (__hasOwnProp$9.call(source, prop) && exclude.indexOf(prop) < 0)
1812
- target[prop] = source[prop];
1813
- if (source != null && __getOwnPropSymbols$9)
1814
- for (var prop of __getOwnPropSymbols$9(source)) {
1815
- if (exclude.indexOf(prop) < 0 && __propIsEnum$9.call(source, prop))
1816
- target[prop] = source[prop];
1480
+ };
1481
+ return /* @__PURE__ */ React.createElement("div", { className: "mx-auto flex w-full max-w-[1100px] flex-col gap-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-stretch gap-5" }, /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "text-[28px] font-extrabold text-dark-blue-400" }, props.name), /* @__PURE__ */ React.createElement("div", { className: "mt-1.5 text-[12.5px] text-slate-400" }, props.impactStatement)), /* @__PURE__ */ React.createElement("div", { className: "flex w-[440px] shrink-0 flex-col justify-between gap-3 rounded-2xl bg-gradient-to-br from-dark-blue-600 via-dark-blue-400 to-sky-blue-400 p-5" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-base font-extrabold text-white" }, props.organization.name), /* @__PURE__ */ React.createElement("div", { className: "mt-1.5 text-[11.5px] leading-relaxed text-white/70" }, props.organization.description)), accessCode && /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement("span", { className: "text-[11px] text-white/70" }, "Community code: ", accessCode), /* @__PURE__ */ React.createElement(
1482
+ "button",
1483
+ {
1484
+ onClick: onCopyAccessCode,
1485
+ className: "rounded-md bg-white/90 px-2.5 py-1 text-[10.5px] font-bold text-dark-blue-400 hover:bg-white"
1486
+ },
1487
+ "Copy"
1488
+ )))), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement(
1489
+ CardGradient,
1490
+ {
1491
+ title: "Dashboard",
1492
+ description: "Track your students\u2019 pathway progress",
1493
+ accent: "mint",
1494
+ icon: /* @__PURE__ */ React.createElement(IconGauge, { size: 18, stroke: 1.75 }),
1495
+ onClick: props.onDashboardClick
1817
1496
  }
1818
- return target;
1819
- };
1820
- const useStyles$h = createStyles((theme) => ({
1821
- card: {
1822
- height: 240,
1823
- backgroundSize: "cover",
1824
- backgroundPosition: "center",
1825
- whiteSpace: "pre-line"
1826
- },
1827
- content: {
1828
- position: "absolute",
1829
- padding: theme.spacing.xl,
1830
- zIndex: 1,
1831
- top: 0,
1832
- bottom: 0,
1833
- right: 0,
1834
- left: 0
1835
- },
1836
- title: {
1837
- color: theme.white,
1838
- marginBottom: theme.spacing.xs / 2
1839
- },
1840
- description: {
1841
- color: theme.white,
1842
- maxWidth: 220
1843
- },
1844
- code: {
1845
- color: theme.white,
1846
- maxWidth: 220
1847
- }
1848
- }));
1849
- const TenantBanner = (_a) => {
1850
- var _b = _a, {
1851
- title,
1852
- description,
1853
- image,
1854
- style,
1855
- className,
1856
- code
1857
- } = _b, others = __objRest$1(_b, [
1858
- "title",
1859
- "description",
1860
- "image",
1861
- "style",
1862
- "className",
1863
- "code"
1864
- ]);
1865
- const { classes, cx, theme } = useStyles$h();
1866
- const handleCopy = async () => {
1867
- if (!code)
1868
- return;
1869
- try {
1870
- await navigator.clipboard.writeText(code);
1871
- showNotification({
1872
- title: "Copied!",
1873
- message: "Community code copied to clipboard.",
1874
- autoClose: 3e3
1875
- });
1876
- } catch (err) {
1877
- console.error("Failed to copy code", err);
1878
- }
1879
- };
1880
- return /* @__PURE__ */ React.createElement(
1881
- Card,
1882
- __spreadValues$9({
1883
- radius: "md",
1884
- style: __spreadValues$9({ backgroundImage: `url(${image})` }, style),
1885
- className: cx(classes.card, className)
1886
- }, others),
1887
- /* @__PURE__ */ React.createElement(
1888
- Overlay,
1889
- {
1890
- gradient: `linear-gradient(105deg, ${theme.black} 20%, #312f2f 50%, ${theme.colors.gray[6]} 100%)`,
1891
- opacity: 0.55,
1892
- zIndex: 0
1893
- }
1894
- ),
1895
- /* @__PURE__ */ React.createElement("div", { className: classes.content }, /* @__PURE__ */ React.createElement(Text, { size: "lg", weight: 700, className: classes.title }, title), /* @__PURE__ */ React.createElement(Text, { size: "sm", className: classes.description }, description), /* @__PURE__ */ React.createElement(Group, { mt: "sm", spacing: "xs" }, /* @__PURE__ */ React.createElement(Text, { size: "sm", className: classes.code }, "Community Code: ", code || "\u2014"), code && /* @__PURE__ */ React.createElement(
1896
- Button,
1897
- {
1898
- size: "xs",
1899
- variant: "white",
1900
- onClick: handleCopy,
1901
- styles: {
1902
- root: {
1903
- backgroundColor: "rgba(255,255,255,0.9)"
1904
- }
1905
- }
1906
- },
1907
- "Copy"
1908
- )))
1909
- );
1910
- };
1911
-
1912
- const Home = (props) => {
1913
- return /* @__PURE__ */ React.createElement(Container, { size: "lg" }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: "lg" }, /* @__PURE__ */ React.createElement(Grid, { gutter: "md" }, /* @__PURE__ */ React.createElement(Grid.Col, { md: 6 }, /* @__PURE__ */ React.createElement(
1914
- UserInfo,
1915
- {
1916
- variant: "compact",
1917
- name: props.name,
1918
- impactStatement: props.impactStatement
1919
- }
1920
- )), /* @__PURE__ */ React.createElement(Grid.Col, { md: 6 }, /* @__PURE__ */ React.createElement(
1921
- TenantBanner,
1922
- {
1923
- title: props.organization.name,
1924
- description: props.organization.description,
1925
- image: props.organization.image,
1926
- code: props.organization.accessCode
1927
- }
1928
- ))), /* @__PURE__ */ React.createElement(Grid, { gutter: "md" }, /* @__PURE__ */ React.createElement(Grid.Col, null, /* @__PURE__ */ React.createElement(
1929
- CardGradient,
1930
- {
1931
- title: "Dashboard",
1932
- description: "Track your students\u2019 pathway progress",
1933
- onClick: props.onDashboardClick
1934
- }
1935
- )), /* @__PURE__ */ React.createElement(Grid.Col, null, /* @__PURE__ */ React.createElement(
1936
- CardGradient,
1937
- {
1938
- title: "Classes",
1939
- description: "Create classes, cohorts, or custom subgroups",
1940
- onClick: props.onClassesClick
1941
- }
1942
- )), /* @__PURE__ */ React.createElement(Grid.Col, null, /* @__PURE__ */ React.createElement(
1943
- CardGradient,
1944
- {
1945
- title: "Pathways",
1946
- description: "Explore all your unique pathway requirements in one clear space",
1947
- onClick: props.onPathwaysClick
1948
- }
1949
- )), /* @__PURE__ */ React.createElement(Grid.Col, null, /* @__PURE__ */ React.createElement(
1950
- CardGradient,
1951
- {
1952
- title: "Badges",
1953
- description: "Key milestones that reflect skill development, micro-credentials, or academic progress",
1954
- onClick: props.onBadgesClick
1955
- }
1956
- )), /* @__PURE__ */ React.createElement(Grid.Col, null, /* @__PURE__ */ React.createElement(
1957
- CardGradient,
1958
- {
1959
- title: "Lessons",
1960
- description: "Bite-sized activities and learning experiences accelerating students achievement",
1961
- onClick: props.onLessonsClick
1962
- }
1963
- )), /* @__PURE__ */ React.createElement(Grid.Col, null, /* @__PURE__ */ React.createElement(
1964
- CardGradient,
1965
- {
1966
- title: "File Locker",
1967
- description: "A secure space to view student-submitted work and provide feedback",
1968
- onClick: props.onFileLockerClick
1969
- }
1970
- )))));
1497
+ ), /* @__PURE__ */ React.createElement(
1498
+ CardGradient,
1499
+ {
1500
+ title: "Classes",
1501
+ description: "Create classes, cohorts, or custom subgroups",
1502
+ accent: "gold",
1503
+ icon: /* @__PURE__ */ React.createElement(IconCategory2, { size: 18, stroke: 1.75 }),
1504
+ onClick: props.onClassesClick
1505
+ }
1506
+ ), /* @__PURE__ */ React.createElement(
1507
+ CardGradient,
1508
+ {
1509
+ title: "Pathways",
1510
+ description: "Explore all your unique pathway requirements in one clear space",
1511
+ accent: "cyan",
1512
+ icon: /* @__PURE__ */ React.createElement(IconRoute, { size: 18, stroke: 1.75 }),
1513
+ onClick: props.onPathwaysClick
1514
+ }
1515
+ ), /* @__PURE__ */ React.createElement(
1516
+ CardGradient,
1517
+ {
1518
+ title: "Badges",
1519
+ description: "Key milestones that reflect skill development, micro-credentials, or academic progress",
1520
+ accent: "mint",
1521
+ icon: /* @__PURE__ */ React.createElement(IconAlbum, { size: 18, stroke: 1.75 }),
1522
+ onClick: props.onBadgesClick
1523
+ }
1524
+ ), /* @__PURE__ */ React.createElement(
1525
+ CardGradient,
1526
+ {
1527
+ title: "File Locker",
1528
+ description: "A secure space to view student-submitted work and provide feedback",
1529
+ accent: "cyan",
1530
+ icon: /* @__PURE__ */ React.createElement(IconClipboard, { size: 18, stroke: 1.75 }),
1531
+ onClick: props.onFileLockerClick
1532
+ }
1533
+ )));
1971
1534
  };
1972
1535
 
1973
1536
  function Table$7(props) {
@@ -2002,7 +1565,7 @@ function Table$7(props) {
2002
1565
  ));
2003
1566
  }
2004
1567
 
2005
- const useStyles$g = createStyles((theme) => ({
1568
+ const useStyles$d = createStyles((theme) => ({
2006
1569
  button: {
2007
1570
  borderTopRightRadius: 0,
2008
1571
  borderBottomRightRadius: 0,
@@ -2017,7 +1580,7 @@ const useStyles$g = createStyles((theme) => ({
2017
1580
  }
2018
1581
  }));
2019
1582
  const SplitButton$3 = (props) => {
2020
- const { classes, theme } = useStyles$g();
1583
+ const { classes, theme } = useStyles$d();
2021
1584
  theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
2022
1585
  return /* @__PURE__ */ React.createElement(Stack$5, { spacing: "sm" }, /* @__PURE__ */ React.createElement(
2023
1586
  Button,
@@ -2054,28 +1617,28 @@ function Stack$3(props) {
2054
1617
  return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(UnstyledButton, { component: Link, to: props.href }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: 24, sx: { padding: 20, minWidth: 700 } }, rows)));
2055
1618
  }
2056
1619
 
2057
- var __defProp$8 = Object.defineProperty;
2058
- var __defProps$6 = Object.defineProperties;
2059
- var __getOwnPropDescs$6 = Object.getOwnPropertyDescriptors;
2060
- var __getOwnPropSymbols$8 = Object.getOwnPropertySymbols;
2061
- var __hasOwnProp$8 = Object.prototype.hasOwnProperty;
2062
- var __propIsEnum$8 = Object.prototype.propertyIsEnumerable;
2063
- var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2064
- var __spreadValues$8 = (a, b) => {
1620
+ var __defProp$a = Object.defineProperty;
1621
+ var __defProps$7 = Object.defineProperties;
1622
+ var __getOwnPropDescs$7 = Object.getOwnPropertyDescriptors;
1623
+ var __getOwnPropSymbols$a = Object.getOwnPropertySymbols;
1624
+ var __hasOwnProp$a = Object.prototype.hasOwnProperty;
1625
+ var __propIsEnum$a = Object.prototype.propertyIsEnumerable;
1626
+ var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1627
+ var __spreadValues$a = (a, b) => {
2065
1628
  for (var prop in b || (b = {}))
2066
- if (__hasOwnProp$8.call(b, prop))
2067
- __defNormalProp$8(a, prop, b[prop]);
2068
- if (__getOwnPropSymbols$8)
2069
- for (var prop of __getOwnPropSymbols$8(b)) {
2070
- if (__propIsEnum$8.call(b, prop))
2071
- __defNormalProp$8(a, prop, b[prop]);
1629
+ if (__hasOwnProp$a.call(b, prop))
1630
+ __defNormalProp$a(a, prop, b[prop]);
1631
+ if (__getOwnPropSymbols$a)
1632
+ for (var prop of __getOwnPropSymbols$a(b)) {
1633
+ if (__propIsEnum$a.call(b, prop))
1634
+ __defNormalProp$a(a, prop, b[prop]);
2072
1635
  }
2073
1636
  return a;
2074
1637
  };
2075
- var __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b));
1638
+ var __spreadProps$7 = (a, b) => __defProps$7(a, __getOwnPropDescs$7(b));
2076
1639
  function Table$6(props) {
2077
1640
  const preparedItems = React.useMemo(() => {
2078
- return props.items.map((item) => __spreadProps$6(__spreadValues$8({}, item), {
1641
+ return props.items.map((item) => __spreadProps$7(__spreadValues$a({}, item), {
2079
1642
  status: item.isComplete ? 2 : item.isStarted ? 1 : 0
2080
1643
  }));
2081
1644
  }, [props.items]);
@@ -2195,7 +1758,7 @@ function Stack$2(props) {
2195
1758
  }
2196
1759
  const truncateWithEllipses = (text, max) => text.substr(0, max - 1) + (text.length > max ? "&hellip;" : "");
2197
1760
 
2198
- const useStyles$f = createStyles((theme) => ({
1761
+ const useStyles$c = createStyles((theme) => ({
2199
1762
  title: {
2200
1763
  fontSize: 34,
2201
1764
  fontWeight: 900,
@@ -2208,7 +1771,7 @@ const useStyles$f = createStyles((theme) => ({
2208
1771
  }
2209
1772
  }));
2210
1773
  const Lesson = (props) => {
2211
- const { classes } = useStyles$f();
1774
+ const { classes } = useStyles$c();
2212
1775
  const [tab, setTab] = useState("question");
2213
1776
  const numberOfStudents = props.students.length;
2214
1777
  const numberOfLessons = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length : 0;
@@ -2321,68 +1884,38 @@ const Lesson = (props) => {
2321
1884
  };
2322
1885
 
2323
1886
  function Table$5(props) {
1887
+ if (props.loading) {
1888
+ return /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Loading\u2026");
1889
+ }
2324
1890
  if (props.items.length === 0) {
2325
- return /* @__PURE__ */ React.createElement(
2326
- PlaceholderBanner,
2327
- {
2328
- title: "No lessons to display",
2329
- description: "We don't have any lessons to show you just yet.",
2330
- loading: props.loading,
2331
- icon: "lessons"
2332
- }
2333
- );
1891
+ return /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-slate-200 bg-white p-8 text-center text-sm text-slate-400 shadow-sm" }, "No lessons to display.");
2334
1892
  }
2335
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement("tr", { key: row.lessonId }, /* @__PURE__ */ React.createElement("td", null, /* @__PURE__ */ React.createElement(
2336
- UnstyledButton,
1893
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex gap-4 px-4 text-[10.5px] font-extrabold uppercase tracking-wide text-slate-400" }, /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, "Lesson"), /* @__PURE__ */ React.createElement("div", { className: "w-40 shrink-0" }, "Pathway"), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), props.items.map((row) => /* @__PURE__ */ React.createElement(
1894
+ Link,
2337
1895
  {
2338
- component: Link,
1896
+ key: row.lessonId,
2339
1897
  to: row.href,
2340
- sx: (theme) => ({
2341
- display: "block",
2342
- width: "100%",
2343
- padding: theme.spacing.md,
2344
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
2345
- "&:hover": {
2346
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.colors.gray[1]
2347
- }
2348
- })
1898
+ className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
2349
1899
  },
2350
- /* @__PURE__ */ React.createElement(Group, null, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React.createElement(Text, { size: "xs", color: "dimmed" }, row.description)))
2351
- ))));
2352
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(Table$l, { horizontalSpacing: 0, verticalSpacing: 0, sx: { minWidth: 700 } }, /* @__PURE__ */ React.createElement("tbody", null, rows)));
1900
+ /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, row.name), row.description && /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs leading-relaxed text-slate-500" }, row.description)),
1901
+ /* @__PURE__ */ React.createElement("div", { className: "w-40 shrink-0 text-xs text-slate-500" }, row.pathway || "\u2014"),
1902
+ /* @__PURE__ */ React.createElement(IconChevronRight, { size: 16, stroke: 2, className: "w-4 shrink-0 text-slate-300" })
1903
+ )));
2353
1904
  }
2354
1905
 
2355
- const useStyles$e = createStyles((theme) => ({
2356
- title: {
2357
- fontSize: 34,
2358
- fontWeight: 900,
2359
- [theme.fn.smallerThan("sm")]: {
2360
- fontSize: 24
2361
- }
2362
- },
2363
- description: {
2364
- maxWidth: 600
2365
- }
2366
- }));
2367
1906
  const Lessons = (props) => {
2368
- const { classes } = useStyles$e();
2369
- return /* @__PURE__ */ React.createElement(Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: "md" }, /* @__PURE__ */ React.createElement(Grid, null, /* @__PURE__ */ React.createElement(Grid.Col, { sm: "auto" }, /* @__PURE__ */ React.createElement(Badge$1, { variant: "filled", size: "lg" }, "Lessons"), /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, "Lessons"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Bite-sized activities and learning experiences accelerating students achievement"))), /* @__PURE__ */ React.createElement(
2370
- Autocomplete,
1907
+ return /* @__PURE__ */ React.createElement("div", { className: "mx-auto flex max-w-4xl flex-col gap-5 px-4 py-8" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React.createElement("h1", { className: "text-2xl font-extrabold tracking-tight text-dark-blue-400" }, "Lessons"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-500" }, "Bite-sized activities and learning experiences accelerating students achievement")), /* @__PURE__ */ React.createElement("div", { className: "relative" }, /* @__PURE__ */ React.createElement(IconSearch, { size: 16, stroke: 2, className: "pointer-events-none absolute left-3.5 top-1/2 -translate-y-1/2 text-slate-400" }), /* @__PURE__ */ React.createElement(
1908
+ "input",
2371
1909
  {
1910
+ type: "text",
2372
1911
  placeholder: "Search for a lesson that fits your needs",
2373
- data: props.lessons.map((item) => item.name),
2374
- onChange: props.onAutocompleteChange
1912
+ onChange: (e) => props.onAutocompleteChange(e.target.value),
1913
+ className: "w-full rounded-xl border border-slate-200 bg-white py-2.5 pl-10 pr-4 text-sm text-dark-blue-400 placeholder:text-slate-400 focus:border-sky-blue-400 focus:outline-none"
2375
1914
  }
2376
- ), /* @__PURE__ */ React.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React.createElement(LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React.createElement(
2377
- Table$5,
2378
- {
2379
- loading: props.loading,
2380
- items: props.lessons
2381
- }
2382
- ))));
1915
+ )), /* @__PURE__ */ React.createElement(Table$5, { loading: props.loading, items: props.lessons }));
2383
1916
  };
2384
1917
 
2385
- const useStyles$d = createStyles((theme) => ({
1918
+ const useStyles$b = createStyles((theme) => ({
2386
1919
  title: {
2387
1920
  fontSize: 22,
2388
1921
  fontWeight: 900,
@@ -2401,7 +1934,7 @@ const useStyles$d = createStyles((theme) => ({
2401
1934
  }
2402
1935
  }));
2403
1936
  function AccessCode(props) {
2404
- const { classes } = useStyles$d();
1937
+ const { classes } = useStyles$b();
2405
1938
  return /* @__PURE__ */ React.createElement(Container, { mx: "0", px: "0", size: 460, my: 30 }, /* @__PURE__ */ React.createElement(Title, { className: classes.title }, "Access code"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", size: "sm" }, "Grant access to join your organization"), /* @__PURE__ */ React.createElement(Paper, { withBorder: true, shadow: "md", p: 30, radius: "md", mt: "xl" }, /* @__PURE__ */ React.createElement(TextInput, { value: props.value, readOnly: true }), /* @__PURE__ */ React.createElement(Group, { position: "apart", mt: "lg", className: classes.controls }, /* @__PURE__ */ React.createElement(
2406
1939
  Anchor,
2407
1940
  {
@@ -2429,7 +1962,7 @@ const monthNames = [
2429
1962
  "November",
2430
1963
  "December"
2431
1964
  ];
2432
- const useStyles$c = createStyles((theme) => ({
1965
+ const useStyles$a = createStyles((theme) => ({
2433
1966
  title: {
2434
1967
  fontSize: 34,
2435
1968
  fontWeight: 900,
@@ -2459,7 +1992,7 @@ const useStyles$c = createStyles((theme) => ({
2459
1992
  }
2460
1993
  }));
2461
1994
  const Organization = (props) => {
2462
- const { classes } = useStyles$c();
1995
+ const { classes } = useStyles$a();
2463
1996
  return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: "md" }, /* @__PURE__ */ React.createElement(Grid, null, /* @__PURE__ */ React.createElement(Grid.Col, { sm: "auto" }, /* @__PURE__ */ React.createElement(UnstyledButton, { onClick: props.onBackClick }, /* @__PURE__ */ React.createElement(
2464
1997
  Badge$1,
2465
1998
  {
@@ -2485,7 +2018,7 @@ const Organization = (props) => {
2485
2018
  ] }))))));
2486
2019
  };
2487
2020
 
2488
- const useStyles$b = createStyles((theme) => ({
2021
+ const useStyles$9 = createStyles((theme) => ({
2489
2022
  button: {
2490
2023
  borderTopRightRadius: 0,
2491
2024
  borderBottomRightRadius: 0,
@@ -2500,7 +2033,7 @@ const useStyles$b = createStyles((theme) => ({
2500
2033
  }
2501
2034
  }));
2502
2035
  const SplitButton$2 = (props) => {
2503
- const { classes, theme } = useStyles$b();
2036
+ const { classes, theme } = useStyles$9();
2504
2037
  const menuIconColor = theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
2505
2038
  const hasMenu = !!props.withOrganizationLink;
2506
2039
  return /* @__PURE__ */ React.createElement(Group, { noWrap: true, spacing: 0 }, /* @__PURE__ */ React.createElement(
@@ -2562,26 +2095,26 @@ function Table$4(props) {
2562
2095
  return /* @__PURE__ */ React.createElement(ScrollArea, null, /* @__PURE__ */ React.createElement(Table$l, { verticalSpacing: 20, sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Name"), /* @__PURE__ */ React.createElement("th", null, "Role"), /* @__PURE__ */ React.createElement("th", null, "Account Created?"), /* @__PURE__ */ React.createElement("th", null, "# of Classes"), /* @__PURE__ */ React.createElement("th", null))), /* @__PURE__ */ React.createElement("tbody", null, rows)));
2563
2096
  }
2564
2097
 
2565
- var __defProp$7 = Object.defineProperty;
2566
- var __defProps$5 = Object.defineProperties;
2567
- var __getOwnPropDescs$5 = Object.getOwnPropertyDescriptors;
2568
- var __getOwnPropSymbols$7 = Object.getOwnPropertySymbols;
2569
- var __hasOwnProp$7 = Object.prototype.hasOwnProperty;
2570
- var __propIsEnum$7 = Object.prototype.propertyIsEnumerable;
2571
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2572
- var __spreadValues$7 = (a, b) => {
2098
+ var __defProp$9 = Object.defineProperty;
2099
+ var __defProps$6 = Object.defineProperties;
2100
+ var __getOwnPropDescs$6 = Object.getOwnPropertyDescriptors;
2101
+ var __getOwnPropSymbols$9 = Object.getOwnPropertySymbols;
2102
+ var __hasOwnProp$9 = Object.prototype.hasOwnProperty;
2103
+ var __propIsEnum$9 = Object.prototype.propertyIsEnumerable;
2104
+ var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2105
+ var __spreadValues$9 = (a, b) => {
2573
2106
  for (var prop in b || (b = {}))
2574
- if (__hasOwnProp$7.call(b, prop))
2575
- __defNormalProp$7(a, prop, b[prop]);
2576
- if (__getOwnPropSymbols$7)
2577
- for (var prop of __getOwnPropSymbols$7(b)) {
2578
- if (__propIsEnum$7.call(b, prop))
2579
- __defNormalProp$7(a, prop, b[prop]);
2107
+ if (__hasOwnProp$9.call(b, prop))
2108
+ __defNormalProp$9(a, prop, b[prop]);
2109
+ if (__getOwnPropSymbols$9)
2110
+ for (var prop of __getOwnPropSymbols$9(b)) {
2111
+ if (__propIsEnum$9.call(b, prop))
2112
+ __defNormalProp$9(a, prop, b[prop]);
2580
2113
  }
2581
2114
  return a;
2582
2115
  };
2583
- var __spreadProps$5 = (a, b) => __defProps$5(a, __getOwnPropDescs$5(b));
2584
- const useStyles$a = createStyles((theme) => ({
2116
+ var __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b));
2117
+ const useStyles$8 = createStyles((theme) => ({
2585
2118
  title: {
2586
2119
  fontSize: 34,
2587
2120
  fontWeight: 900,
@@ -2611,7 +2144,7 @@ const useStyles$a = createStyles((theme) => ({
2611
2144
  }
2612
2145
  }));
2613
2146
  const People = (props) => {
2614
- const { classes } = useStyles$a();
2147
+ const { classes } = useStyles$8();
2615
2148
  const form = useForm({
2616
2149
  initialValues: {
2617
2150
  userId: "",
@@ -2642,27 +2175,27 @@ const People = (props) => {
2642
2175
  padding: "xl",
2643
2176
  size: "xl"
2644
2177
  },
2645
- /* @__PURE__ */ React.createElement(Stack$5, { spacing: "md" }, /* @__PURE__ */ React.createElement(DropzoneButton, __spreadProps$5(__spreadValues$7({}, props), { close: () => setOpened(false) })), /* @__PURE__ */ React.createElement(Divider, { label: "or", labelPosition: "center", my: "md", variant: "dashed" }), /* @__PURE__ */ React.createElement("form", { onSubmit: form.onSubmit(() => {
2178
+ /* @__PURE__ */ React.createElement(Stack$5, { spacing: "md" }, /* @__PURE__ */ React.createElement(DropzoneButton, __spreadProps$6(__spreadValues$9({}, props), { close: () => setOpened(false) })), /* @__PURE__ */ React.createElement(Divider, { label: "or", labelPosition: "center", my: "md", variant: "dashed" }), /* @__PURE__ */ React.createElement("form", { onSubmit: form.onSubmit(() => {
2646
2179
  const values = form.values;
2647
2180
  form.reset();
2648
2181
  setOpened(false);
2649
2182
  props.onCreateUsers && props.onCreateUsers([values]);
2650
2183
  }) }, /* @__PURE__ */ React.createElement(Stack$5, null, /* @__PURE__ */ React.createElement(
2651
2184
  TextInput,
2652
- __spreadValues$7({
2185
+ __spreadValues$9({
2653
2186
  withAsterisk: true,
2654
2187
  label: "Email",
2655
2188
  placeholder: "Email"
2656
2189
  }, form.getInputProps("email"))
2657
2190
  ), /* @__PURE__ */ React.createElement(Group, { grow: true }, /* @__PURE__ */ React.createElement(
2658
2191
  TextInput,
2659
- __spreadValues$7({
2192
+ __spreadValues$9({
2660
2193
  label: "Given name",
2661
2194
  placeholder: "Given name"
2662
2195
  }, form.getInputProps("givenName"))
2663
2196
  ), /* @__PURE__ */ React.createElement(
2664
2197
  TextInput,
2665
- __spreadValues$7({
2198
+ __spreadValues$9({
2666
2199
  label: "Family name",
2667
2200
  placeholder: "Family name"
2668
2201
  }, form.getInputProps("familyName"))
@@ -2715,7 +2248,7 @@ const People = (props) => {
2715
2248
  ))))));
2716
2249
  };
2717
2250
  const DropzoneButton = (props) => {
2718
- const { classes, theme } = useStyles$a();
2251
+ const { classes, theme } = useStyles$8();
2719
2252
  const openRef = React.useRef(null);
2720
2253
  const [loading, setLoading] = React.useState(false);
2721
2254
  const onDrop = React.useCallback((acceptedFiles) => {
@@ -2761,7 +2294,7 @@ const DropzoneButton = (props) => {
2761
2294
  } }, "Select file"));
2762
2295
  };
2763
2296
 
2764
- const useStyles$9 = createStyles((theme) => ({
2297
+ const useStyles$7 = createStyles((theme) => ({
2765
2298
  form: {
2766
2299
  backgroundColor: theme.white,
2767
2300
  padding: theme.spacing.xl,
@@ -2824,7 +2357,7 @@ const useStyles$9 = createStyles((theme) => ({
2824
2357
  }
2825
2358
  }));
2826
2359
  const StartAnonymousLesson = (props) => {
2827
- const { classes } = useStyles$9();
2360
+ const { classes } = useStyles$7();
2828
2361
  const [name, setName] = React.useState("");
2829
2362
  return /* @__PURE__ */ React.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React.createElement(Container, null, /* @__PURE__ */ React.createElement(SimpleGrid, { maw: 960, cols: 2, spacing: 15, breakpoints: [{ maxWidth: "sm", cols: 1 }] }, /* @__PURE__ */ React.createElement("div", { className: classes.content }, /* @__PURE__ */ React.createElement(Badge$1, { color: "violet" }, "Community"), /* @__PURE__ */ React.createElement(Title, { className: classes.title }, props.title), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", mt: "md" }, props.description), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", mt: "md" }, "You are now part of ", `${props.educatorName}'s`, " Class")), /* @__PURE__ */ React.createElement("div", { className: classes.form }, /* @__PURE__ */ React.createElement(
2830
2363
  TextInput,
@@ -2848,24 +2381,24 @@ const StartAnonymousLesson = (props) => {
2848
2381
  ))))));
2849
2382
  };
2850
2383
 
2851
- var __defProp$6 = Object.defineProperty;
2852
- var __getOwnPropSymbols$6 = Object.getOwnPropertySymbols;
2853
- var __hasOwnProp$6 = Object.prototype.hasOwnProperty;
2854
- var __propIsEnum$6 = Object.prototype.propertyIsEnumerable;
2855
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2856
- var __spreadValues$6 = (a, b) => {
2857
- for (var prop in b || (b = {}))
2858
- if (__hasOwnProp$6.call(b, prop))
2859
- __defNormalProp$6(a, prop, b[prop]);
2860
- if (__getOwnPropSymbols$6)
2861
- for (var prop of __getOwnPropSymbols$6(b)) {
2862
- if (__propIsEnum$6.call(b, prop))
2863
- __defNormalProp$6(a, prop, b[prop]);
2384
+ var __defProp$8 = Object.defineProperty;
2385
+ var __getOwnPropSymbols$8 = Object.getOwnPropertySymbols;
2386
+ var __hasOwnProp$8 = Object.prototype.hasOwnProperty;
2387
+ var __propIsEnum$8 = Object.prototype.propertyIsEnumerable;
2388
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2389
+ var __spreadValues$8 = (a, b) => {
2390
+ for (var prop in b || (b = {}))
2391
+ if (__hasOwnProp$8.call(b, prop))
2392
+ __defNormalProp$8(a, prop, b[prop]);
2393
+ if (__getOwnPropSymbols$8)
2394
+ for (var prop of __getOwnPropSymbols$8(b)) {
2395
+ if (__propIsEnum$8.call(b, prop))
2396
+ __defNormalProp$8(a, prop, b[prop]);
2864
2397
  }
2865
2398
  return a;
2866
2399
  };
2867
2400
  const BadgeGrid = (props) => {
2868
- const badges = props.badges.map((b) => /* @__PURE__ */ React.createElement(TaskCard, __spreadValues$6({ key: b.title }, b)));
2401
+ const badges = props.badges.map((b) => /* @__PURE__ */ React.createElement(TaskCard, __spreadValues$8({ key: b.title }, b)));
2869
2402
  return /* @__PURE__ */ React.createElement(SimpleGrid, { cols: 4, breakpoints: [{ maxWidth: "sm", cols: 1 }, { maxWidth: "md", cols: 3 }] }, badges);
2870
2403
  };
2871
2404
  function TaskCard(props) {
@@ -2881,7 +2414,127 @@ function TaskCard(props) {
2881
2414
  ));
2882
2415
  }
2883
2416
 
2884
- const useStyles$8 = createStyles((theme) => ({
2417
+ var __defProp$7 = Object.defineProperty;
2418
+ var __getOwnPropSymbols$7 = Object.getOwnPropertySymbols;
2419
+ var __hasOwnProp$7 = Object.prototype.hasOwnProperty;
2420
+ var __propIsEnum$7 = Object.prototype.propertyIsEnumerable;
2421
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2422
+ var __spreadValues$7 = (a, b) => {
2423
+ for (var prop in b || (b = {}))
2424
+ if (__hasOwnProp$7.call(b, prop))
2425
+ __defNormalProp$7(a, prop, b[prop]);
2426
+ if (__getOwnPropSymbols$7)
2427
+ for (var prop of __getOwnPropSymbols$7(b)) {
2428
+ if (__propIsEnum$7.call(b, prop))
2429
+ __defNormalProp$7(a, prop, b[prop]);
2430
+ }
2431
+ return a;
2432
+ };
2433
+ var __objRest$1 = (source, exclude) => {
2434
+ var target = {};
2435
+ for (var prop in source)
2436
+ if (__hasOwnProp$7.call(source, prop) && exclude.indexOf(prop) < 0)
2437
+ target[prop] = source[prop];
2438
+ if (source != null && __getOwnPropSymbols$7)
2439
+ for (var prop of __getOwnPropSymbols$7(source)) {
2440
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$7.call(source, prop))
2441
+ target[prop] = source[prop];
2442
+ }
2443
+ return target;
2444
+ };
2445
+ const useStyles$6 = createStyles((theme) => ({
2446
+ card: {
2447
+ height: 240,
2448
+ backgroundSize: "cover",
2449
+ backgroundPosition: "center",
2450
+ whiteSpace: "pre-line"
2451
+ },
2452
+ content: {
2453
+ position: "absolute",
2454
+ padding: theme.spacing.xl,
2455
+ zIndex: 1,
2456
+ top: 0,
2457
+ bottom: 0,
2458
+ right: 0,
2459
+ left: 0
2460
+ },
2461
+ title: {
2462
+ color: theme.white,
2463
+ marginBottom: theme.spacing.xs / 2
2464
+ },
2465
+ description: {
2466
+ color: theme.white,
2467
+ maxWidth: 220
2468
+ },
2469
+ code: {
2470
+ color: theme.white,
2471
+ maxWidth: 220
2472
+ }
2473
+ }));
2474
+ const TenantBanner = (_a) => {
2475
+ var _b = _a, {
2476
+ title,
2477
+ description,
2478
+ image,
2479
+ style,
2480
+ className,
2481
+ code
2482
+ } = _b, others = __objRest$1(_b, [
2483
+ "title",
2484
+ "description",
2485
+ "image",
2486
+ "style",
2487
+ "className",
2488
+ "code"
2489
+ ]);
2490
+ const { classes, cx, theme } = useStyles$6();
2491
+ const handleCopy = async () => {
2492
+ if (!code)
2493
+ return;
2494
+ try {
2495
+ await navigator.clipboard.writeText(code);
2496
+ showNotification({
2497
+ title: "Copied!",
2498
+ message: "Community code copied to clipboard.",
2499
+ autoClose: 3e3
2500
+ });
2501
+ } catch (err) {
2502
+ console.error("Failed to copy code", err);
2503
+ }
2504
+ };
2505
+ return /* @__PURE__ */ React.createElement(
2506
+ Card,
2507
+ __spreadValues$7({
2508
+ radius: "md",
2509
+ style: __spreadValues$7({ backgroundImage: `url(${image})` }, style),
2510
+ className: cx(classes.card, className)
2511
+ }, others),
2512
+ /* @__PURE__ */ React.createElement(
2513
+ Overlay,
2514
+ {
2515
+ gradient: `linear-gradient(105deg, ${theme.black} 20%, #312f2f 50%, ${theme.colors.gray[6]} 100%)`,
2516
+ opacity: 0.55,
2517
+ zIndex: 0
2518
+ }
2519
+ ),
2520
+ /* @__PURE__ */ React.createElement("div", { className: classes.content }, /* @__PURE__ */ React.createElement(Text, { size: "lg", weight: 700, className: classes.title }, title), /* @__PURE__ */ React.createElement(Text, { size: "sm", className: classes.description }, description), /* @__PURE__ */ React.createElement(Group, { mt: "sm", spacing: "xs" }, /* @__PURE__ */ React.createElement(Text, { size: "sm", className: classes.code }, "Community Code: ", code || "\u2014"), code && /* @__PURE__ */ React.createElement(
2521
+ Button,
2522
+ {
2523
+ size: "xs",
2524
+ variant: "white",
2525
+ onClick: handleCopy,
2526
+ styles: {
2527
+ root: {
2528
+ backgroundColor: "rgba(255,255,255,0.9)"
2529
+ }
2530
+ }
2531
+ },
2532
+ "Copy"
2533
+ )))
2534
+ );
2535
+ };
2536
+
2537
+ const useStyles$5 = createStyles((theme) => ({
2885
2538
  action: {
2886
2539
  backgroundColor: "inherit",
2887
2540
  ":hover": {
@@ -2900,7 +2553,7 @@ const useStyles$8 = createStyles((theme) => ({
2900
2553
  }
2901
2554
  }));
2902
2555
  const TrialHome = (props) => {
2903
- const { classes } = useStyles$8();
2556
+ const { classes } = useStyles$5();
2904
2557
  return /* @__PURE__ */ React.createElement(Container, { size: "lg" }, /* @__PURE__ */ React.createElement(Badge$1, null, props.daysRemaining, " day", props.daysRemaining !== 1 ? "s" : "", " left"), /* @__PURE__ */ React.createElement(
2905
2558
  Button,
2906
2559
  {
@@ -2929,38 +2582,38 @@ const TrialHome = (props) => {
2929
2582
  )), /* @__PURE__ */ React.createElement(Title, { maw: 500, mb: 20, mt: 20, className: classes.title }, "Based on the tags you selected, check out these lessons to get started with your students!"), /* @__PURE__ */ React.createElement(BadgeGrid, { onAssign: props.onAssign, badges: props.badges })));
2930
2583
  };
2931
2584
 
2932
- var __defProp$5 = Object.defineProperty;
2933
- var __defProps$4 = Object.defineProperties;
2934
- var __getOwnPropDescs$4 = Object.getOwnPropertyDescriptors;
2935
- var __getOwnPropSymbols$5 = Object.getOwnPropertySymbols;
2936
- var __hasOwnProp$5 = Object.prototype.hasOwnProperty;
2937
- var __propIsEnum$5 = Object.prototype.propertyIsEnumerable;
2938
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2939
- var __spreadValues$5 = (a, b) => {
2585
+ var __defProp$6 = Object.defineProperty;
2586
+ var __defProps$5 = Object.defineProperties;
2587
+ var __getOwnPropDescs$5 = Object.getOwnPropertyDescriptors;
2588
+ var __getOwnPropSymbols$6 = Object.getOwnPropertySymbols;
2589
+ var __hasOwnProp$6 = Object.prototype.hasOwnProperty;
2590
+ var __propIsEnum$6 = Object.prototype.propertyIsEnumerable;
2591
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2592
+ var __spreadValues$6 = (a, b) => {
2940
2593
  for (var prop in b || (b = {}))
2941
- if (__hasOwnProp$5.call(b, prop))
2942
- __defNormalProp$5(a, prop, b[prop]);
2943
- if (__getOwnPropSymbols$5)
2944
- for (var prop of __getOwnPropSymbols$5(b)) {
2945
- if (__propIsEnum$5.call(b, prop))
2946
- __defNormalProp$5(a, prop, b[prop]);
2594
+ if (__hasOwnProp$6.call(b, prop))
2595
+ __defNormalProp$6(a, prop, b[prop]);
2596
+ if (__getOwnPropSymbols$6)
2597
+ for (var prop of __getOwnPropSymbols$6(b)) {
2598
+ if (__propIsEnum$6.call(b, prop))
2599
+ __defNormalProp$6(a, prop, b[prop]);
2947
2600
  }
2948
2601
  return a;
2949
2602
  };
2950
- var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
2603
+ var __spreadProps$5 = (a, b) => __defProps$5(a, __getOwnPropDescs$5(b));
2951
2604
  var __objRest = (source, exclude) => {
2952
2605
  var target = {};
2953
2606
  for (var prop in source)
2954
- if (__hasOwnProp$5.call(source, prop) && exclude.indexOf(prop) < 0)
2607
+ if (__hasOwnProp$6.call(source, prop) && exclude.indexOf(prop) < 0)
2955
2608
  target[prop] = source[prop];
2956
- if (source != null && __getOwnPropSymbols$5)
2957
- for (var prop of __getOwnPropSymbols$5(source)) {
2958
- if (exclude.indexOf(prop) < 0 && __propIsEnum$5.call(source, prop))
2609
+ if (source != null && __getOwnPropSymbols$6)
2610
+ for (var prop of __getOwnPropSymbols$6(source)) {
2611
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$6.call(source, prop))
2959
2612
  target[prop] = source[prop];
2960
2613
  }
2961
2614
  return target;
2962
2615
  };
2963
- const useStyles$7 = createStyles((theme, { checked }) => ({
2616
+ const useStyles$4 = createStyles((theme, { checked }) => ({
2964
2617
  button: {
2965
2618
  display: "flex",
2966
2619
  alignItems: "center",
@@ -3002,10 +2655,10 @@ function ImageCheckbox(_a) {
3002
2655
  finalValue: false,
3003
2656
  onChange
3004
2657
  });
3005
- const { classes, cx } = useStyles$7({ checked: value });
2658
+ const { classes, cx } = useStyles$4({ checked: value });
3006
2659
  return /* @__PURE__ */ React.createElement(
3007
2660
  UnstyledButton,
3008
- __spreadProps$4(__spreadValues$5({}, others), {
2661
+ __spreadProps$5(__spreadValues$6({}, others), {
3009
2662
  onClick: () => handleChange(!value),
3010
2663
  className: cx(classes.button, className)
3011
2664
  }),
@@ -3026,7 +2679,7 @@ function ImageCheckbox(_a) {
3026
2679
  function SelectGrid(props) {
3027
2680
  const items = props.items.map((item) => /* @__PURE__ */ React.createElement(
3028
2681
  ImageCheckbox,
3029
- __spreadProps$4(__spreadValues$5({}, item), {
2682
+ __spreadProps$5(__spreadValues$6({}, item), {
3030
2683
  key: item.title,
3031
2684
  onChange: (checked) => props.onChange(item.title, checked)
3032
2685
  })
@@ -3044,26 +2697,26 @@ function SelectGrid(props) {
3044
2697
  );
3045
2698
  }
3046
2699
 
3047
- var __defProp$4 = Object.defineProperty;
3048
- var __defProps$3 = Object.defineProperties;
3049
- var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
3050
- var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
3051
- var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
3052
- var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
3053
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3054
- var __spreadValues$4 = (a, b) => {
2700
+ var __defProp$5 = Object.defineProperty;
2701
+ var __defProps$4 = Object.defineProperties;
2702
+ var __getOwnPropDescs$4 = Object.getOwnPropertyDescriptors;
2703
+ var __getOwnPropSymbols$5 = Object.getOwnPropertySymbols;
2704
+ var __hasOwnProp$5 = Object.prototype.hasOwnProperty;
2705
+ var __propIsEnum$5 = Object.prototype.propertyIsEnumerable;
2706
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2707
+ var __spreadValues$5 = (a, b) => {
3055
2708
  for (var prop in b || (b = {}))
3056
- if (__hasOwnProp$4.call(b, prop))
3057
- __defNormalProp$4(a, prop, b[prop]);
3058
- if (__getOwnPropSymbols$4)
3059
- for (var prop of __getOwnPropSymbols$4(b)) {
3060
- if (__propIsEnum$4.call(b, prop))
3061
- __defNormalProp$4(a, prop, b[prop]);
2709
+ if (__hasOwnProp$5.call(b, prop))
2710
+ __defNormalProp$5(a, prop, b[prop]);
2711
+ if (__getOwnPropSymbols$5)
2712
+ for (var prop of __getOwnPropSymbols$5(b)) {
2713
+ if (__propIsEnum$5.call(b, prop))
2714
+ __defNormalProp$5(a, prop, b[prop]);
3062
2715
  }
3063
2716
  return a;
3064
2717
  };
3065
- var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
3066
- const useStyles$6 = createStyles((theme) => ({
2718
+ var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
2719
+ const useStyles$3 = createStyles((theme) => ({
3067
2720
  wrapper: {
3068
2721
  minHeight: "100%",
3069
2722
  boxSizing: "border-box",
@@ -3126,7 +2779,7 @@ const OPTIONS = [
3126
2779
  { description: "project-based learning", title: "Project-Based Learning", icon: IconTools }
3127
2780
  ];
3128
2781
  const TrialRegistration = (props) => {
3129
- const { classes } = useStyles$6();
2782
+ const { classes } = useStyles$3();
3130
2783
  const [firstName, setFirstName] = React.useState("");
3131
2784
  const [lastName, setLastName] = React.useState("");
3132
2785
  const [organization, setOrganization] = React.useState({ organizationId: "", displayName: "" });
@@ -3172,7 +2825,7 @@ const TrialRegistration = (props) => {
3172
2825
  label: "School/Organization Name",
3173
2826
  placeholder: "What's the name of your school?",
3174
2827
  data: props.organizations.map((o) => {
3175
- return __spreadProps$3(__spreadValues$4({}, o), { value: o.displayName });
2828
+ return __spreadProps$4(__spreadValues$5({}, o), { value: o.displayName });
3176
2829
  }),
3177
2830
  onItemSubmit: (item) => setOrganization({ organizationId: item.organizationId, displayName: item.displayName }),
3178
2831
  onChange: (next) => {
@@ -3184,7 +2837,7 @@ const TrialRegistration = (props) => {
3184
2837
  SelectGrid,
3185
2838
  {
3186
2839
  items: OPTIONS,
3187
- onChange: (e, checked) => setInterests(__spreadProps$3(__spreadValues$4({}, interests), { [e]: checked }))
2840
+ onChange: (e, checked) => setInterests(__spreadProps$4(__spreadValues$5({}, interests), { [e]: checked }))
3188
2841
  }
3189
2842
  ), /* @__PURE__ */ React.createElement(Group, { position: "right", mt: "md" }, /* @__PURE__ */ React.createElement(
3190
2843
  Button,
@@ -3222,26 +2875,26 @@ const AdminProvider = (props) => {
3222
2875
  );
3223
2876
  };
3224
2877
 
3225
- var __defProp$3 = Object.defineProperty;
3226
- var __defProps$2 = Object.defineProperties;
3227
- var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
3228
- var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
3229
- var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
3230
- var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
3231
- var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3232
- var __spreadValues$3 = (a, b) => {
2878
+ var __defProp$4 = Object.defineProperty;
2879
+ var __defProps$3 = Object.defineProperties;
2880
+ var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
2881
+ var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
2882
+ var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
2883
+ var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
2884
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2885
+ var __spreadValues$4 = (a, b) => {
3233
2886
  for (var prop in b || (b = {}))
3234
- if (__hasOwnProp$3.call(b, prop))
3235
- __defNormalProp$3(a, prop, b[prop]);
3236
- if (__getOwnPropSymbols$3)
3237
- for (var prop of __getOwnPropSymbols$3(b)) {
3238
- if (__propIsEnum$3.call(b, prop))
3239
- __defNormalProp$3(a, prop, b[prop]);
2887
+ if (__hasOwnProp$4.call(b, prop))
2888
+ __defNormalProp$4(a, prop, b[prop]);
2889
+ if (__getOwnPropSymbols$4)
2890
+ for (var prop of __getOwnPropSymbols$4(b)) {
2891
+ if (__propIsEnum$4.call(b, prop))
2892
+ __defNormalProp$4(a, prop, b[prop]);
3240
2893
  }
3241
2894
  return a;
3242
2895
  };
3243
- var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
3244
- const useStyles$5 = createStyles((theme, props) => ({
2896
+ var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
2897
+ const useStyles$2 = createStyles((theme, props) => ({
3245
2898
  footer: {
3246
2899
  paddingTop: theme.spacing.md,
3247
2900
  paddingBottom: theme.spacing.md,
@@ -3328,7 +2981,7 @@ const useStyles$5 = createStyles((theme, props) => ({
3328
2981
  }
3329
2982
  }));
3330
2983
  const App = (props) => {
3331
- const { classes } = useStyles$5(props);
2984
+ const { classes } = useStyles$2(props);
3332
2985
  const account = useAccount(props.account, props.accounts, props.onAccountChange);
3333
2986
  return /* @__PURE__ */ React.createElement(
3334
2987
  AppShell,
@@ -3336,7 +2989,7 @@ const App = (props) => {
3336
2989
  padding: "xs",
3337
2990
  navbar: props.navbar && /* @__PURE__ */ React.createElement(
3338
2991
  Navbar,
3339
- __spreadProps$2(__spreadValues$3({}, props.navbar.props), {
2992
+ __spreadProps$3(__spreadValues$4({}, props.navbar.props), {
3340
2993
  onSwitchAccounts: account.accounts && account.accounts.length > 1 ? () => account.setChangeModalOpen(true) : void 0
3341
2994
  })
3342
2995
  ),
@@ -3424,61 +3077,29 @@ const useAccount = (account, accounts, onAccountChange) => {
3424
3077
  };
3425
3078
 
3426
3079
  function Table$3(props) {
3080
+ if (props.loading) {
3081
+ return /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Loading\u2026");
3082
+ }
3427
3083
  if (props.items.length === 0) {
3428
- return /* @__PURE__ */ React.createElement(
3429
- PlaceholderBanner,
3430
- {
3431
- title: "No pathway items to display",
3432
- description: "We don't have any pathway items to show you just yet.",
3433
- loading: props.loading,
3434
- icon: "badges"
3435
- }
3436
- );
3084
+ return /* @__PURE__ */ React.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.");
3437
3085
  }
3438
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement("tr", { key: row.badgeId }, /* @__PURE__ */ React.createElement("td", null, /* @__PURE__ */ React.createElement(
3439
- UnstyledButton,
3086
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, props.items.map((row) => /* @__PURE__ */ React.createElement(
3087
+ Link,
3440
3088
  {
3441
- component: Link,
3089
+ key: row.badgeId,
3442
3090
  to: row.href,
3443
- sx: (theme) => ({
3444
- display: "block",
3445
- width: "100%",
3446
- padding: theme.spacing.md,
3447
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
3448
- "&:hover": {
3449
- backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.colors.gray[1]
3450
- }
3451
- })
3091
+ className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
3452
3092
  },
3453
- /* @__PURE__ */ React.createElement(Group, null, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React.createElement(Text, { size: "xs", color: "dimmed" }, row.description)))
3454
- ))));
3455
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(Table$l, { horizontalSpacing: 0, verticalSpacing: 0, sx: { minWidth: 700 } }, /* @__PURE__ */ React.createElement("tbody", null, rows)));
3093
+ /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, row.name), row.description && /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs leading-relaxed text-slate-500" }, row.description)),
3094
+ /* @__PURE__ */ React.createElement(IconChevronRight, { size: 16, stroke: 2, className: "shrink-0 text-slate-300" })
3095
+ )));
3456
3096
  }
3457
3097
 
3458
- const useStyles$4 = createStyles((theme) => ({
3459
- title: {
3460
- fontSize: 34,
3461
- fontWeight: 900,
3462
- [theme.fn.smallerThan("sm")]: {
3463
- fontSize: 24
3464
- }
3465
- },
3466
- description: {
3467
- maxWidth: 600
3468
- }
3469
- }));
3470
3098
  const Pathways = (props) => {
3471
- const { classes } = useStyles$4();
3472
- return /* @__PURE__ */ React.createElement(Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: "md" }, /* @__PURE__ */ React.createElement(Grid, null, /* @__PURE__ */ React.createElement(Grid.Col, { sm: "auto" }, /* @__PURE__ */ React.createElement(Badge$1, { variant: "filled", size: "lg" }, "Pathways"), /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, "Pathways"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Explore all your unique pathway requirements in one clear space"))), /* @__PURE__ */ React.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React.createElement(LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React.createElement(
3473
- Table$3,
3474
- {
3475
- loading: props.loading,
3476
- items: props.pathways
3477
- }
3478
- ))));
3099
+ return /* @__PURE__ */ React.createElement("div", { className: "mx-auto flex max-w-4xl flex-col gap-5 px-4 py-8" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-1" }, /* @__PURE__ */ React.createElement("h1", { className: "text-2xl font-extrabold tracking-tight text-dark-blue-400" }, "Pathways"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-500" }, "Explore all your unique pathway requirements in one clear space")), /* @__PURE__ */ React.createElement(Table$3, { loading: props.loading, items: props.pathways }));
3479
3100
  };
3480
3101
 
3481
- const useStyles$3 = createStyles((theme) => ({
3102
+ const useStyles$1 = createStyles((theme) => ({
3482
3103
  button: {
3483
3104
  borderTopRightRadius: 0,
3484
3105
  borderBottomRightRadius: 0,
@@ -3493,7 +3114,7 @@ const useStyles$3 = createStyles((theme) => ({
3493
3114
  }
3494
3115
  }));
3495
3116
  const SplitButton$1 = (props) => {
3496
- const { classes, theme } = useStyles$3();
3117
+ const { classes, theme } = useStyles$1();
3497
3118
  theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
3498
3119
  return /* @__PURE__ */ React.createElement(Stack$5, { spacing: "sm" }, /* @__PURE__ */ React.createElement(
3499
3120
  Button,
@@ -3529,25 +3150,25 @@ function Stack$1(props) {
3529
3150
  return /* @__PURE__ */ React.createElement(Grid, { grow: true, gutter: "lg", sx: { padding: 20, minWidth: 700 } }, rows);
3530
3151
  }
3531
3152
 
3532
- var __defProp$2 = Object.defineProperty;
3533
- var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
3534
- var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
3535
- var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
3536
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3537
- var __spreadValues$2 = (a, b) => {
3153
+ var __defProp$3 = Object.defineProperty;
3154
+ var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
3155
+ var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
3156
+ var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
3157
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3158
+ var __spreadValues$3 = (a, b) => {
3538
3159
  for (var prop in b || (b = {}))
3539
- if (__hasOwnProp$2.call(b, prop))
3540
- __defNormalProp$2(a, prop, b[prop]);
3541
- if (__getOwnPropSymbols$2)
3542
- for (var prop of __getOwnPropSymbols$2(b)) {
3543
- if (__propIsEnum$2.call(b, prop))
3544
- __defNormalProp$2(a, prop, b[prop]);
3160
+ if (__hasOwnProp$3.call(b, prop))
3161
+ __defNormalProp$3(a, prop, b[prop]);
3162
+ if (__getOwnPropSymbols$3)
3163
+ for (var prop of __getOwnPropSymbols$3(b)) {
3164
+ if (__propIsEnum$3.call(b, prop))
3165
+ __defNormalProp$3(a, prop, b[prop]);
3545
3166
  }
3546
3167
  return a;
3547
3168
  };
3548
3169
  function Table$2(props) {
3549
3170
  const preparedItems = React.useMemo(() => {
3550
- return (props.items || []).map((item) => __spreadValues$2(__spreadValues$2({}, item), item.categoryPoints));
3171
+ return (props.items || []).map((item) => __spreadValues$3(__spreadValues$3({}, item), item.categoryPoints));
3551
3172
  }, [props.items]);
3552
3173
  const { items: sortedItems, requestSort, sortConfig } = useSortableData(preparedItems);
3553
3174
  if (props.loading && props.items.length === 0) {
@@ -3679,7 +3300,7 @@ function Table$1(props) {
3679
3300
  ));
3680
3301
  }
3681
3302
 
3682
- const useStyles$2 = createStyles((theme) => ({
3303
+ const useStyles = createStyles((theme) => ({
3683
3304
  title: {
3684
3305
  fontSize: 34,
3685
3306
  fontWeight: 900,
@@ -3692,7 +3313,7 @@ const useStyles$2 = createStyles((theme) => ({
3692
3313
  }
3693
3314
  }));
3694
3315
  const Pathway = (props) => {
3695
- const { classes } = useStyles$2();
3316
+ const { classes } = useStyles();
3696
3317
  const [tab, setTab] = useState("badges");
3697
3318
  const numberOfStudents = props.students.length;
3698
3319
  numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length / numberOfStudents : 0;
@@ -3759,82 +3380,84 @@ const Pathway = (props) => {
3759
3380
  )))))));
3760
3381
  };
3761
3382
 
3762
- const useStyles$1 = createStyles((theme) => ({
3763
- button: {
3764
- borderTopRightRadius: 0,
3765
- borderBottomRightRadius: 0,
3766
- marginLeft: 0,
3767
- marginRight: 0
3768
- },
3769
- menuControl: {
3770
- borderTopLeftRadius: 0,
3771
- borderBottomLeftRadius: 0,
3772
- border: 0,
3773
- borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
3774
- }
3775
- }));
3776
3383
  const SplitButton = (props) => {
3777
- const { classes, theme } = useStyles$1();
3778
- theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
3779
- return /* @__PURE__ */ React.createElement(Stack$5, { spacing: "sm" }, /* @__PURE__ */ React.createElement(
3780
- Button,
3384
+ return /* @__PURE__ */ React.createElement(
3385
+ "button",
3781
3386
  {
3782
- leftIcon: /* @__PURE__ */ React.createElement(IconTableExport, { size: 14 }),
3783
- onClick: props.onExportDataClick
3387
+ onClick: props.onExportDataClick,
3388
+ className: "flex items-center gap-2 rounded-xl bg-gradient-to-r from-gold-400 to-[#f5c300] px-4 py-2.5 text-xs font-extrabold text-dark-blue-400"
3784
3389
  },
3390
+ /* @__PURE__ */ React.createElement(IconTableExport, { size: 14, stroke: 2 }),
3785
3391
  "Export data (.csv)"
3786
- ));
3392
+ );
3787
3393
  };
3788
3394
 
3789
3395
  function Stack(props) {
3790
- const { items, hideBadge, hideLesson } = props;
3396
+ const { items, hideBadge, hideLesson, hidePathway } = props;
3791
3397
  if (!items.length)
3792
3398
  return null;
3793
- const visibleColumns = [
3794
- true,
3795
- !hideBadge,
3796
- !hideLesson,
3797
- true
3798
- ].filter(Boolean).length;
3799
- const span = 12 / visibleColumns;
3800
- return /* @__PURE__ */ React.createElement(Grid, { gutter: "md", sx: { padding: 20, minWidth: 700 } }, /* @__PURE__ */ React.createElement(Grid.Col, { span }, /* @__PURE__ */ React.createElement(Text, { weight: "bold" }, "Link")), !hideBadge && /* @__PURE__ */ React.createElement(Grid.Col, { span }, /* @__PURE__ */ React.createElement(Text, { weight: "bold" }, "Badge")), !hideLesson && /* @__PURE__ */ React.createElement(Grid.Col, { span }, /* @__PURE__ */ React.createElement(Text, { weight: "bold" }, "Lesson")), /* @__PURE__ */ React.createElement(Grid.Col, { span }, /* @__PURE__ */ React.createElement(Text, { weight: "bold" }, "Question")), items.map((row, i) => /* @__PURE__ */ React.createElement(React.Fragment, { key: i }, /* @__PURE__ */ React.createElement(Grid.Col, { span }, /* @__PURE__ */ React.createElement(
3801
- Button,
3802
- {
3803
- component: "a",
3804
- href: row.link,
3805
- target: "_blank",
3806
- rel: "noopener noreferrer",
3807
- size: "xs",
3808
- variant: "light"
3809
- },
3810
- "View File"
3811
- )), !hideBadge && /* @__PURE__ */ React.createElement(Grid.Col, { span }, /* @__PURE__ */ React.createElement(Text, null, row.badgeName)), !hideLesson && /* @__PURE__ */ React.createElement(Grid.Col, { span }, /* @__PURE__ */ React.createElement(Text, null, row.lessonName)), /* @__PURE__ */ React.createElement(Grid.Col, { span }, /* @__PURE__ */ React.createElement(Text, null, row.question)))));
3399
+ const columns = [
3400
+ "minmax(0,2fr)",
3401
+ !hidePathway && "minmax(0,1.3fr)",
3402
+ !hideLesson && "minmax(0,1.3fr)",
3403
+ !hideBadge && "minmax(0,1.3fr)",
3404
+ "auto"
3405
+ ].filter(Boolean).join(" ");
3406
+ const headerCell = "border-b border-slate-100 pb-2 text-[10.5px] font-extrabold uppercase tracking-wide text-slate-400";
3407
+ const dataCell = "py-3";
3408
+ return /* @__PURE__ */ React.createElement("div", { className: "grid items-center gap-x-3", style: { gridTemplateColumns: columns } }, /* @__PURE__ */ React.createElement("div", { className: headerCell }, "Question"), !hidePathway && /* @__PURE__ */ React.createElement("div", { className: headerCell }, "Pathway"), !hideLesson && /* @__PURE__ */ React.createElement("div", { className: headerCell }, "Lesson"), !hideBadge && /* @__PURE__ */ React.createElement("div", { className: headerCell }, "Badge"), /* @__PURE__ */ React.createElement("div", { className: headerCell }), items.map((row, i) => {
3409
+ const rowBorder = i > 0 ? "border-t border-slate-100" : "";
3410
+ return /* @__PURE__ */ React.createElement(React.Fragment, { key: i }, /* @__PURE__ */ React.createElement("div", { className: `${dataCell} ${rowBorder} text-xs font-semibold text-dark-blue-400` }, row.question), !hidePathway && /* @__PURE__ */ React.createElement("div", { className: `${dataCell} ${rowBorder} truncate text-[11px] text-slate-500` }, row.pathwayName || "\u2014"), !hideLesson && /* @__PURE__ */ React.createElement("div", { className: `${dataCell} ${rowBorder} truncate text-[11px] text-slate-500` }, row.lessonName), !hideBadge && /* @__PURE__ */ React.createElement("div", { className: `${dataCell} ${rowBorder} truncate text-[11px] text-slate-500` }, row.badgeName), /* @__PURE__ */ React.createElement("div", { className: `${dataCell} ${rowBorder} flex shrink-0 gap-2` }, /* @__PURE__ */ React.createElement(
3411
+ "a",
3412
+ {
3413
+ href: row.link,
3414
+ target: "_blank",
3415
+ rel: "noopener noreferrer",
3416
+ className: "flex items-center gap-1 rounded-md border border-slate-200 px-2.5 py-1.5 text-[11px] font-bold text-slate-600 no-underline hover:bg-slate-50"
3417
+ },
3418
+ /* @__PURE__ */ React.createElement(IconExternalLink, { size: 12, stroke: 2 }),
3419
+ "Preview"
3420
+ ), /* @__PURE__ */ React.createElement(
3421
+ "a",
3422
+ {
3423
+ href: row.link,
3424
+ download: true,
3425
+ target: "_blank",
3426
+ rel: "noopener noreferrer",
3427
+ className: "flex items-center gap-1 rounded-md border border-slate-200 px-2.5 py-1.5 text-[11px] font-bold text-slate-600 no-underline hover:bg-slate-50"
3428
+ },
3429
+ /* @__PURE__ */ React.createElement(IconDownload, { size: 12, stroke: 2 }),
3430
+ "Download"
3431
+ )));
3432
+ }));
3812
3433
  }
3813
3434
 
3814
- var __defProp$1 = Object.defineProperty;
3815
- var __defProps$1 = Object.defineProperties;
3816
- var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
3817
- var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
3818
- var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
3819
- var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
3820
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3821
- var __spreadValues$1 = (a, b) => {
3435
+ var __defProp$2 = Object.defineProperty;
3436
+ var __defProps$2 = Object.defineProperties;
3437
+ var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
3438
+ var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
3439
+ var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
3440
+ var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
3441
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3442
+ var __spreadValues$2 = (a, b) => {
3822
3443
  for (var prop in b || (b = {}))
3823
- if (__hasOwnProp$1.call(b, prop))
3824
- __defNormalProp$1(a, prop, b[prop]);
3825
- if (__getOwnPropSymbols$1)
3826
- for (var prop of __getOwnPropSymbols$1(b)) {
3827
- if (__propIsEnum$1.call(b, prop))
3828
- __defNormalProp$1(a, prop, b[prop]);
3444
+ if (__hasOwnProp$2.call(b, prop))
3445
+ __defNormalProp$2(a, prop, b[prop]);
3446
+ if (__getOwnPropSymbols$2)
3447
+ for (var prop of __getOwnPropSymbols$2(b)) {
3448
+ if (__propIsEnum$2.call(b, prop))
3449
+ __defNormalProp$2(a, prop, b[prop]);
3829
3450
  }
3830
3451
  return a;
3831
3452
  };
3832
- var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
3453
+ var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
3454
+ const initials$1 = (name) => name.split(" ").map((w) => w[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
3833
3455
  function Table(props) {
3456
+ const [expanded, setExpanded] = React.useState({});
3834
3457
  const preparedItems = React.useMemo(() => {
3835
3458
  return props.items.map((item) => {
3836
3459
  var _a;
3837
- return __spreadProps$1(__spreadValues$1({}, item), {
3460
+ return __spreadProps$2(__spreadValues$2({}, item), {
3838
3461
  submissionCount: ((_a = item.submissions) == null ? void 0 : _a.length) || 0
3839
3462
  });
3840
3463
  });
@@ -3851,76 +3474,82 @@ function Table(props) {
3851
3474
  }
3852
3475
  );
3853
3476
  }
3854
- const sortStatus = {
3855
- columnAccessor: sortConfig.key,
3856
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
3857
- };
3858
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(
3859
- DataTable,
3477
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
3478
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 px-4 text-[10.5px] font-extrabold uppercase tracking-wide text-slate-400" }, /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("name"), className: "flex-1 text-left hover:text-slate-600" }, "Student Name", indicator("name")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("submissionCount"), className: "w-16 shrink-0 text-left hover:text-slate-600" }, "Files", indicator("submissionCount")), props.onReview && /* @__PURE__ */ React.createElement("div", { className: "w-36 shrink-0" }), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), sortedItems.map((row) => {
3479
+ const isOpen = !!expanded[row.userId];
3480
+ return /* @__PURE__ */ React.createElement("div", { key: row.userId, className: "rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement(
3481
+ "div",
3482
+ {
3483
+ onClick: () => setExpanded(__spreadProps$2(__spreadValues$2({}, expanded), { [row.userId]: !isOpen })),
3484
+ className: "flex cursor-pointer items-center gap-4 p-4"
3485
+ },
3486
+ /* @__PURE__ */ React.createElement("div", { className: "flex min-w-0 flex-1 items-center gap-3" }, row.avatar ? /* @__PURE__ */ React.createElement("img", { src: row.avatar, className: "h-9 w-9 shrink-0 rounded-full object-cover", alt: "" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-mint-400 to-dark-blue-400 text-xs font-bold text-white" }, initials$1(row.name)), /* @__PURE__ */ React.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ React.createElement("div", { className: "truncate text-sm font-bold text-dark-blue-400" }, row.name), /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs text-slate-400" }, row.email))),
3487
+ /* @__PURE__ */ React.createElement("div", { className: "w-16 shrink-0 text-sm font-bold text-dark-blue-400" }, row.submissions.length),
3488
+ props.onReview && /* @__PURE__ */ React.createElement("div", { className: "w-36 shrink-0" }, /* @__PURE__ */ React.createElement(
3489
+ "button",
3490
+ {
3491
+ onClick: (e) => {
3492
+ e.stopPropagation();
3493
+ props.onReview(row);
3494
+ },
3495
+ className: "rounded-lg bg-gradient-to-r from-gold-400 to-[#f5c300] px-3 py-1.5 text-[11px] font-extrabold text-dark-blue-400"
3496
+ },
3497
+ "Review Submission"
3498
+ )),
3499
+ /* @__PURE__ */ React.createElement(IconChevronRight, { size: 16, stroke: 2, className: `w-4 shrink-0 text-slate-300 transition-transform ${isOpen ? "rotate-90" : ""}` })
3500
+ ), isOpen && /* @__PURE__ */ React.createElement("div", { className: "border-t border-slate-100 px-4 py-3" }, /* @__PURE__ */ React.createElement(Stack, { items: row.submissions, hideBadge: props.hideBadge, hideLesson: props.hideLesson, hidePathway: props.hidePathway })));
3501
+ }));
3502
+ }
3503
+
3504
+ const initials = (name) => name.split(" ").map((w) => w[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
3505
+ function SubmissionDetail(props) {
3506
+ const { student } = props;
3507
+ return /* @__PURE__ */ React.createElement("div", { className: "mx-auto flex w-full max-w-4xl flex-col gap-4 px-4 py-8" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 text-xs text-slate-400" }, /* @__PURE__ */ React.createElement("button", { onClick: props.onBack, className: "font-bold text-sky-blue-400 hover:underline" }, "File Locker"), /* @__PURE__ */ React.createElement("span", null, "/"), /* @__PURE__ */ React.createElement("span", { className: "font-bold text-dark-blue-400" }, student.name)), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 rounded-2xl border border-slate-200 bg-white p-5 shadow-sm" }, student.avatar ? /* @__PURE__ */ React.createElement("img", { src: student.avatar, className: "h-12 w-12 shrink-0 rounded-full object-cover", alt: "" }) : /* @__PURE__ */ React.createElement("div", { className: "flex h-12 w-12 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-mint-400 to-dark-blue-400 text-sm font-bold text-white" }, initials(student.name)), /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "text-lg font-extrabold text-dark-blue-400" }, student.name), /* @__PURE__ */ React.createElement("div", { className: "mt-0.5 text-xs text-slate-400" }, student.email, props.context ? ` \xB7 ${props.context}` : "")), /* @__PURE__ */ React.createElement("div", { className: "shrink-0 rounded-full bg-slate-100 px-3 py-1 text-xs font-bold text-slate-500" }, student.submissions.length, " file", student.submissions.length === 1 ? "" : "s")), /* @__PURE__ */ React.createElement("div", { className: "rounded-2xl border border-slate-200 bg-white p-5 shadow-sm" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-extrabold text-dark-blue-400" }, "Files"), /* @__PURE__ */ React.createElement("div", { className: "mt-2" }, /* @__PURE__ */ React.createElement(Stack, { items: student.submissions }))), /* @__PURE__ */ React.createElement("div", { className: "flex gap-3" }, /* @__PURE__ */ React.createElement(
3508
+ "button",
3860
3509
  {
3861
- verticalSpacing: "sm",
3862
- sx: { minWidth: 700 },
3863
- withBorder: false,
3864
- borderRadius: "sm",
3865
- withColumnBorders: true,
3866
- striped: true,
3867
- highlightOnHover: true,
3868
- records: sortedItems,
3869
- sortStatus,
3870
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
3871
- idAccessor: "userId",
3872
- columns: [{
3873
- accessor: "name",
3874
- title: "Student Name",
3875
- sortable: true,
3876
- render: (row) => /* @__PURE__ */ React.createElement(Group, { spacing: "sm" }, /* @__PURE__ */ React.createElement(Avatar, { size: 40, src: row.avatar, radius: 40 }), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React.createElement(Text, { size: "xs", color: "dimmed" }, row.email)))
3877
- }, {
3878
- accessor: "submissionCount",
3879
- title: "Files",
3880
- sortable: true,
3881
- render: (row) => row.submissions.length
3882
- }],
3883
- rowExpansion: {
3884
- content: ({ record }) => /* @__PURE__ */ React.createElement(
3885
- Stack,
3886
- {
3887
- items: record.submissions,
3888
- hideBadge: props.hideBadge,
3889
- hideLesson: props.hideLesson
3890
- }
3891
- )
3892
- }
3893
- }
3894
- ));
3510
+ onClick: () => props.onNav(-1),
3511
+ className: "flex flex-1 items-center justify-center gap-1.5 rounded-xl border border-slate-200 bg-white py-2.5 text-xs font-bold text-slate-600 hover:bg-slate-50"
3512
+ },
3513
+ /* @__PURE__ */ React.createElement(IconChevronLeft, { size: 14, stroke: 2 }),
3514
+ "Previous Submission"
3515
+ ), /* @__PURE__ */ React.createElement(
3516
+ "button",
3517
+ {
3518
+ onClick: () => props.onNav(1),
3519
+ className: "flex flex-1 items-center justify-center gap-1.5 rounded-xl border border-slate-200 bg-white py-2.5 text-xs font-bold text-slate-600 hover:bg-slate-50"
3520
+ },
3521
+ "Next Submission",
3522
+ /* @__PURE__ */ React.createElement(IconChevronRight, { size: 14, stroke: 2 })
3523
+ )));
3895
3524
  }
3896
3525
 
3897
- var __defProp = Object.defineProperty;
3898
- var __defProps = Object.defineProperties;
3899
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
3900
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3901
- var __hasOwnProp = Object.prototype.hasOwnProperty;
3902
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
3903
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3904
- var __spreadValues = (a, b) => {
3526
+ var __defProp$1 = Object.defineProperty;
3527
+ var __defProps$1 = Object.defineProperties;
3528
+ var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
3529
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
3530
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
3531
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
3532
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3533
+ var __spreadValues$1 = (a, b) => {
3905
3534
  for (var prop in b || (b = {}))
3906
- if (__hasOwnProp.call(b, prop))
3907
- __defNormalProp(a, prop, b[prop]);
3908
- if (__getOwnPropSymbols)
3909
- for (var prop of __getOwnPropSymbols(b)) {
3910
- if (__propIsEnum.call(b, prop))
3911
- __defNormalProp(a, prop, b[prop]);
3535
+ if (__hasOwnProp$1.call(b, prop))
3536
+ __defNormalProp$1(a, prop, b[prop]);
3537
+ if (__getOwnPropSymbols$1)
3538
+ for (var prop of __getOwnPropSymbols$1(b)) {
3539
+ if (__propIsEnum$1.call(b, prop))
3540
+ __defNormalProp$1(a, prop, b[prop]);
3912
3541
  }
3913
3542
  return a;
3914
3543
  };
3915
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
3544
+ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
3916
3545
  const useFilteredStudents = (students) => {
3917
3546
  return React.useMemo(() => {
3918
- const byBadge = (badgeId) => students.map((s) => __spreadProps(__spreadValues({}, s), {
3547
+ const byBadge = (badgeId) => students.map((s) => __spreadProps$1(__spreadValues$1({}, s), {
3919
3548
  submissions: (s.submissions || []).filter(
3920
3549
  (sub) => sub.badgeId === badgeId
3921
3550
  )
3922
3551
  })).filter((s) => s.submissions.length);
3923
- const byLesson = (lessonName) => students.map((s) => __spreadProps(__spreadValues({}, s), {
3552
+ const byLesson = (lessonName) => students.map((s) => __spreadProps$1(__spreadValues$1({}, s), {
3924
3553
  submissions: (s.submissions || []).filter(
3925
3554
  (sub) => sub.lessonName === lessonName
3926
3555
  )
@@ -3931,7 +3560,7 @@ const useFilteredStudents = (students) => {
3931
3560
  (c) => c.startsWith(pathwayId)
3932
3561
  )
3933
3562
  ).map((b) => b.badgeId);
3934
- return students.map((s) => __spreadProps(__spreadValues({}, s), {
3563
+ return students.map((s) => __spreadProps$1(__spreadValues$1({}, s), {
3935
3564
  submissions: (s.submissions || []).filter(
3936
3565
  (sub) => validBadgeIds.includes(sub.badgeId)
3937
3566
  )
@@ -3941,168 +3570,167 @@ const useFilteredStudents = (students) => {
3941
3570
  }, [students]);
3942
3571
  };
3943
3572
 
3944
- const useStyles = createStyles((theme) => ({
3945
- title: {
3946
- fontSize: 34,
3947
- fontWeight: 900,
3948
- [theme.fn.smallerThan("sm")]: {
3949
- fontSize: 24
3573
+ var __defProp = Object.defineProperty;
3574
+ var __defProps = Object.defineProperties;
3575
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
3576
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3577
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
3578
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
3579
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3580
+ var __spreadValues = (a, b) => {
3581
+ for (var prop in b || (b = {}))
3582
+ if (__hasOwnProp.call(b, prop))
3583
+ __defNormalProp(a, prop, b[prop]);
3584
+ if (__getOwnPropSymbols)
3585
+ for (var prop of __getOwnPropSymbols(b)) {
3586
+ if (__propIsEnum.call(b, prop))
3587
+ __defNormalProp(a, prop, b[prop]);
3950
3588
  }
3951
- },
3952
- description: {
3953
- maxWidth: 600
3954
- }
3955
- }));
3956
- const BadgeTable = ({ badges, students, loading }) => {
3957
- const { byBadge } = useFilteredStudents(students);
3958
- const countFiles = (students2) => students2.reduce((acc, s) => {
3959
- var _a;
3960
- return acc + (((_a = s.submissions) == null ? void 0 : _a.length) || 0);
3961
- }, 0);
3962
- return /* @__PURE__ */ React.createElement(Accordion, null, badges.map((b) => {
3963
- const studentsForBadge = byBadge(b.badgeId);
3964
- const fileCount = countFiles(studentsForBadge);
3965
- return /* @__PURE__ */ React.createElement(Accordion.Item, { key: b.badgeId, value: b.badgeId }, /* @__PURE__ */ React.createElement(Accordion.Control, null, /* @__PURE__ */ React.createElement(Group, { position: "apart", w: "100%" }, /* @__PURE__ */ React.createElement(Text, null, b.displayName), /* @__PURE__ */ React.createElement(Badge$1, { size: "sm" }, fileCount))), /* @__PURE__ */ React.createElement(Accordion.Panel, null, /* @__PURE__ */ React.createElement(
3966
- Table,
3967
- {
3968
- loading,
3969
- items: studentsForBadge,
3970
- hideBadge: true
3971
- }
3972
- )));
3589
+ return a;
3590
+ };
3591
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
3592
+ const TABS = [
3593
+ { value: "students", label: "By student" },
3594
+ { value: "pathways", label: "By pathway" },
3595
+ { value: "badges", label: "By badge" },
3596
+ { value: "lessons", label: "By lesson" }
3597
+ ];
3598
+ const countFiles = (students) => students.reduce((acc, s) => {
3599
+ var _a;
3600
+ return acc + (((_a = s.submissions) == null ? void 0 : _a.length) || 0);
3601
+ }, 0);
3602
+ const GroupCard = (props) => {
3603
+ const [open, setOpen] = React.useState(false);
3604
+ return /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement("div", { onClick: () => setOpen(!open), className: "flex cursor-pointer items-center gap-3.5 p-4" }, /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-extrabold text-dark-blue-400" }, props.title), props.description && /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs leading-relaxed text-slate-500" }, props.description)), /* @__PURE__ */ React.createElement("div", { className: "shrink-0 rounded-full bg-mint-100 px-2.5 py-1 text-xs font-bold text-dark-blue-400" }, props.count), /* @__PURE__ */ React.createElement(IconChevronDown, { size: 15, stroke: 2.3, className: `shrink-0 text-slate-400 transition-transform ${open ? "rotate-180" : ""}` })), open && /* @__PURE__ */ React.createElement("div", { className: "border-t border-slate-100 p-4" }, props.children));
3605
+ };
3606
+ const PathwayGroups = (props) => {
3607
+ const { byPathway } = useFilteredStudents(props.students);
3608
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, props.pathways.map((p) => {
3609
+ const filtered = byPathway(p.pathwayId, props.badges);
3610
+ return /* @__PURE__ */ React.createElement(GroupCard, { key: p.pathwayId, title: p.title, description: p.description, count: countFiles(filtered) }, /* @__PURE__ */ React.createElement(Table, { loading: props.loading, items: filtered, hidePathway: true, onReview: (item) => props.onReview(item, filtered, p.title) }));
3973
3611
  }));
3974
3612
  };
3975
- const LessonTableWrapper = ({ lessons, students, loading }) => {
3976
- const { byLesson } = useFilteredStudents(students);
3977
- const countFiles = (students2) => students2.reduce((acc, s) => {
3978
- var _a;
3979
- return acc + (((_a = s.submissions) == null ? void 0 : _a.length) || 0);
3980
- }, 0);
3981
- return /* @__PURE__ */ React.createElement(Accordion, null, lessons.map((l) => {
3982
- const studentsForLesson = byLesson(l.lessonName);
3983
- const fileCount = countFiles(studentsForLesson);
3984
- return /* @__PURE__ */ React.createElement(Accordion.Item, { key: l.lessonId, value: l.lessonId }, /* @__PURE__ */ React.createElement(Accordion.Control, null, /* @__PURE__ */ React.createElement(Group, { position: "apart", w: "100%" }, /* @__PURE__ */ React.createElement(Text, null, l.lessonName), /* @__PURE__ */ React.createElement(Badge$1, { size: "sm" }, fileCount))), /* @__PURE__ */ React.createElement(Accordion.Panel, null, /* @__PURE__ */ React.createElement(
3985
- Table,
3986
- {
3987
- loading,
3988
- items: studentsForLesson,
3989
- hideLesson: true
3990
- }
3991
- )));
3613
+ const BadgeGroups = (props) => {
3614
+ const { byBadge } = useFilteredStudents(props.students);
3615
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, props.badges.map((b) => {
3616
+ const filtered = byBadge(b.badgeId);
3617
+ const pathwayTitle = props.pathwayNameForBadge[b.badgeId];
3618
+ return /* @__PURE__ */ React.createElement(GroupCard, { key: b.badgeId, title: b.displayName, description: pathwayTitle ? `${pathwayTitle} pathway` : void 0, count: countFiles(filtered) }, /* @__PURE__ */ React.createElement(Table, { loading: props.loading, items: filtered, hideBadge: true, hidePathway: true, onReview: (item) => props.onReview(item, filtered, b.displayName) }));
3992
3619
  }));
3993
3620
  };
3994
- const PathwayTable = ({
3995
- pathways,
3996
- badges,
3997
- students,
3998
- loading
3999
- }) => {
4000
- const { byPathway } = useFilteredStudents(students);
4001
- const countFiles = (students2) => students2.reduce((acc, s) => {
4002
- var _a;
4003
- return acc + (((_a = s.submissions) == null ? void 0 : _a.length) || 0);
4004
- }, 0);
4005
- return /* @__PURE__ */ React.createElement(Accordion, null, pathways.map((p) => {
4006
- const studentsForPathway = byPathway(p.pathwayId, badges);
4007
- const fileCount = countFiles(studentsForPathway);
4008
- return /* @__PURE__ */ React.createElement(Accordion.Item, { key: p.pathwayId, value: p.pathwayId }, /* @__PURE__ */ React.createElement(Accordion.Control, null, /* @__PURE__ */ React.createElement(Group, { position: "apart", w: "100%" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("strong", null, p.title), /* @__PURE__ */ React.createElement("div", null, p.description)), /* @__PURE__ */ React.createElement(Badge$1, { size: "sm" }, fileCount))), /* @__PURE__ */ React.createElement(Accordion.Panel, null, /* @__PURE__ */ React.createElement(
4009
- Table,
4010
- {
4011
- loading,
4012
- items: studentsForPathway
4013
- }
4014
- )));
3621
+ const LessonGroups = (props) => {
3622
+ const { byLesson } = useFilteredStudents(props.students);
3623
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, props.lessons.map((l) => {
3624
+ const filtered = byLesson(l.lessonName);
3625
+ const badge = props.badgeForLesson[l.lessonId];
3626
+ const pathwayTitle = badge ? props.pathwayNameForBadge[badge.badgeId] : void 0;
3627
+ const description = badge ? pathwayTitle ? `${badge.displayName} \xB7 ${pathwayTitle} pathway` : badge.displayName : void 0;
3628
+ return /* @__PURE__ */ React.createElement(GroupCard, { key: l.lessonId, title: l.lessonName, description, count: countFiles(filtered) }, /* @__PURE__ */ React.createElement(Table, { loading: props.loading, items: filtered, hideBadge: true, hideLesson: true, hidePathway: true, onReview: (item) => props.onReview(item, filtered, l.lessonName) }));
4015
3629
  }));
4016
3630
  };
4017
3631
  const FileLocker = (props) => {
4018
- const { classes } = useStyles();
4019
- const [tab, setTab] = useState("students");
4020
- props.students.length;
4021
- const numberOfFiles = props.students.reduce(
4022
- (acc, s) => {
4023
- var _a;
4024
- return acc + (((_a = s.submissions) == null ? void 0 : _a.length) || 0);
4025
- },
4026
- 0
4027
- );
4028
- return /* @__PURE__ */ React.createElement(Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: "md" }, /* @__PURE__ */ React.createElement(Grid, null, /* @__PURE__ */ React.createElement(Grid.Col, { sm: "auto" }, /* @__PURE__ */ React.createElement(UnstyledButton, { onClick: props.onBackClick }, /* @__PURE__ */ React.createElement(
4029
- Badge$1,
4030
- {
4031
- variant: "filled",
4032
- leftSection: /* @__PURE__ */ React.createElement(ActionIcon, { color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React.createElement(IconArrowLeft, { size: 14 })),
4033
- size: "lg"
4034
- },
4035
- "Back"
4036
- )), /* @__PURE__ */ React.createElement(Group, null, /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0 }, /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "File"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), !props.trial && /* @__PURE__ */ React.createElement(Stack$5, { ml: "auto" }, /* @__PURE__ */ React.createElement(
4037
- SplitButton,
4038
- {
4039
- href: props.href,
4040
- onCopyLinkClick: props.onCopyLinkClick,
4041
- onExportDataClick: props.onExportDataClick
4042
- }
4043
- ))))), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React.createElement(LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React.createElement(Stack$5, null, /* @__PURE__ */ React.createElement(StatsGroup, { data: [
4044
- {
4045
- title: props.trial ? "LESSONS SUBMITTED" : "FILES",
4046
- value: props.trial ? props.lessonsCompleted || 0 : numberOfFiles,
4047
- unit: props.trial ? "" : ""
4048
- }
4049
- ] }), !props.trial && /* @__PURE__ */ React.createElement(
4050
- Select,
3632
+ const [tab, setTab] = React.useState("students");
3633
+ const [reviewing, setReviewing] = React.useState(null);
3634
+ const numberOfFiles = countFiles(props.students);
3635
+ const { thisWeek, thisMonth } = React.useMemo(() => {
3636
+ const now = new Date();
3637
+ const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1e3);
3638
+ const fom = new Date(now.getFullYear(), now.getMonth(), 1);
3639
+ let week = 0, month = 0;
3640
+ props.students.forEach((s) => {
3641
+ (s.submissions || []).forEach((sub) => {
3642
+ if (!sub.updatedAt)
3643
+ return;
3644
+ const d = new Date(sub.updatedAt);
3645
+ if (d >= weekAgo)
3646
+ week += 1;
3647
+ if (d >= fom)
3648
+ month += 1;
3649
+ });
3650
+ });
3651
+ return { thisWeek: week, thisMonth: month };
3652
+ }, [props.students]);
3653
+ const pathwayNameForBadge = React.useMemo(() => {
3654
+ const map = {};
3655
+ (props.badges || []).forEach((b) => {
3656
+ if (!Array.isArray(b.categories))
3657
+ return;
3658
+ const pathway = (props.pathways || []).find((p) => b.categories.some((c) => c.startsWith(p.pathwayId)));
3659
+ if (pathway)
3660
+ map[b.badgeId] = pathway.title;
3661
+ });
3662
+ return map;
3663
+ }, [props.badges, props.pathways]);
3664
+ const badgeForLesson = React.useMemo(() => {
3665
+ const map = {};
3666
+ (props.badges || []).forEach((b) => {
3667
+ if (!Array.isArray(b.lessonIds))
3668
+ return;
3669
+ b.lessonIds.forEach((lessonId) => {
3670
+ if (!(lessonId in map))
3671
+ map[lessonId] = { displayName: b.displayName, badgeId: b.badgeId };
3672
+ });
3673
+ });
3674
+ return map;
3675
+ }, [props.badges]);
3676
+ const enrichedStudents = React.useMemo(() => {
3677
+ return props.students.map((s) => __spreadProps(__spreadValues({}, s), {
3678
+ submissions: (s.submissions || []).map((sub) => __spreadProps(__spreadValues({}, sub), { pathwayName: pathwayNameForBadge[sub.badgeId] || "" }))
3679
+ }));
3680
+ }, [props.students, pathwayNameForBadge]);
3681
+ const { byPathway } = useFilteredStudents(enrichedStudents);
3682
+ const mostActivePathway = React.useMemo(() => {
3683
+ return (props.pathways || []).reduce((best, p) => {
3684
+ const count = countFiles(byPathway(p.pathwayId, props.badges || []));
3685
+ return count > 0 && (!best || count > best.count) ? { title: p.title, count } : best;
3686
+ }, null);
3687
+ }, [props.pathways, props.badges, byPathway]);
3688
+ const onReview = (item, list, context) => setReviewing({ student: item, list, context });
3689
+ const onNav = (dir) => {
3690
+ if (!reviewing)
3691
+ return;
3692
+ const idx = reviewing.list.findIndex((s) => s.userId === reviewing.student.userId);
3693
+ if (idx === -1)
3694
+ return;
3695
+ const next = reviewing.list[(idx + dir + reviewing.list.length) % reviewing.list.length];
3696
+ setReviewing(__spreadProps(__spreadValues({}, reviewing), { student: next }));
3697
+ };
3698
+ if (reviewing) {
3699
+ return /* @__PURE__ */ React.createElement(
3700
+ SubmissionDetail,
3701
+ {
3702
+ student: reviewing.student,
3703
+ context: reviewing.context,
3704
+ onBack: () => setReviewing(null),
3705
+ onNav
3706
+ }
3707
+ );
3708
+ }
3709
+ return /* @__PURE__ */ React.createElement("div", { className: "mx-auto flex w-full max-w-4xl flex-col gap-5 px-4 py-8" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("button", { onClick: props.onBackClick, className: "flex items-center gap-1 text-xs font-bold text-sky-blue-400 hover:underline" }, /* @__PURE__ */ React.createElement(IconChevronLeft, { size: 13, stroke: 2.5 }), "Back"), /* @__PURE__ */ React.createElement("h1", { className: "mt-1.5 text-2xl font-extrabold tracking-tight text-dark-blue-400" }, props.displayName || "File Locker"), /* @__PURE__ */ React.createElement("p", { className: "mt-1 text-sm text-slate-500" }, props.description || "No description")), !props.trial && /* @__PURE__ */ React.createElement(SplitButton, { href: props.href, onCopyLinkClick: props.onCopyLinkClick, onExportDataClick: props.onExportDataClick })), /* @__PURE__ */ React.createElement(StatsGroup, { data: props.trial ? [
3710
+ { title: "LESSONS SUBMITTED", value: props.lessonsCompleted || 0 }
3711
+ ] : [
3712
+ { title: "FILES", value: numberOfFiles },
3713
+ { title: "THIS WEEK", value: thisWeek },
3714
+ { title: "THIS MONTH", value: thisMonth }
3715
+ ] }), !props.trial && mostActivePathway && /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-500" }, "Most active pathway: ", /* @__PURE__ */ React.createElement("span", { className: "font-bold text-dark-blue-400" }, mostActivePathway.title), " (", mostActivePathway.count, " submission", mostActivePathway.count === 1 ? "" : "s", ")"), !props.trial && /* @__PURE__ */ React.createElement(
3716
+ "select",
4051
3717
  {
4052
- clearable: true,
4053
- clearButtonLabel: "Clear class selection",
4054
- size: "sm",
4055
- placeholder: "Select a class",
4056
- nothingFound: "No options",
4057
3718
  value: props.classId,
4058
- onChange: props.onClassChange,
4059
- icon: /* @__PURE__ */ React.createElement(IconCategory2, null),
4060
- data: props.classes.map((g) => {
4061
- return { value: g.classId, label: g.name };
4062
- })
4063
- }
4064
- ), /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0 }, !props.trial && /* @__PURE__ */ React.createElement(
4065
- Tabs,
4066
- {
4067
- value: tab,
4068
- data: [
4069
- { label: "By student", value: "students" },
4070
- { label: "By pathway", value: "pathways" },
4071
- { label: "By badge", value: "badges" },
4072
- { label: "By lesson", value: "lessons" }
4073
- ],
4074
- onChange: setTab
4075
- }
4076
- ), !props.trial && tab === "students" && /* @__PURE__ */ React.createElement(
4077
- Table,
4078
- {
4079
- loading: props.loading,
4080
- items: props.students
4081
- }
4082
- ), tab === "pathways" && /* @__PURE__ */ React.createElement(
4083
- PathwayTable,
4084
- {
4085
- pathways: props.pathways || [],
4086
- badges: props.badges || [],
4087
- students: props.students,
4088
- loading: props.loading
4089
- }
4090
- ), tab === "badges" && /* @__PURE__ */ React.createElement(
4091
- BadgeTable,
4092
- {
4093
- badges: props.badges || [],
4094
- students: props.students,
4095
- loading: props.loading
4096
- }
4097
- ), tab === "lessons" && /* @__PURE__ */ React.createElement(
4098
- LessonTableWrapper,
3719
+ onChange: (e) => props.onClassChange(e.target.value),
3720
+ className: "w-64 rounded-xl border border-slate-200 bg-white px-3.5 py-2.5 text-sm text-dark-blue-400 focus:border-sky-blue-400 focus:outline-none"
3721
+ },
3722
+ /* @__PURE__ */ React.createElement("option", { value: "" }, "Select a class"),
3723
+ props.classes.map((g) => /* @__PURE__ */ React.createElement("option", { key: g.classId, value: g.classId }, g.name))
3724
+ ), !props.trial && /* @__PURE__ */ React.createElement("div", { className: "flex w-fit gap-1 rounded-xl border border-slate-200 bg-white p-1" }, TABS.map((t) => /* @__PURE__ */ React.createElement(
3725
+ "button",
4099
3726
  {
4100
- lessons: props.lessons,
4101
- students: props.students,
4102
- loading: props.loading
4103
- }
4104
- )))))));
3727
+ key: t.value,
3728
+ onClick: () => setTab(t.value),
3729
+ className: `rounded-lg px-4 py-2 text-xs font-bold ${tab === t.value ? "bg-sky-blue-400/20 text-dark-blue-400" : "text-slate-400 hover:text-slate-600"}`
3730
+ },
3731
+ t.label
3732
+ ))), !props.trial && tab === "students" && /* @__PURE__ */ React.createElement(Table, { loading: props.loading, items: enrichedStudents, onReview: (item) => onReview(item, enrichedStudents) }), !props.trial && tab === "pathways" && /* @__PURE__ */ React.createElement(PathwayGroups, { students: enrichedStudents, loading: props.loading, pathways: props.pathways || [], badges: props.badges || [], onReview }), !props.trial && tab === "badges" && /* @__PURE__ */ React.createElement(BadgeGroups, { students: enrichedStudents, loading: props.loading, badges: props.badges || [], pathwayNameForBadge, onReview }), !props.trial && tab === "lessons" && /* @__PURE__ */ React.createElement(LessonGroups, { students: enrichedStudents, loading: props.loading, lessons: props.lessons, badgeForLesson, pathwayNameForBadge, onReview }));
4105
3733
  };
4106
3734
 
4107
- export { AdminProvider, App, Badge, Badges, Class, Classes, Dashboard, FileLocker, GettingStarted, Home, Lesson, Lessons, Navbar, Organization, Pathway, PathwayTable, Pathways, People, StartAnonymousLesson, Student, SwitchAccount, TrialHome, TrialRegistration };
3735
+ export { AdminProvider, App, Badge, Badges, Class, Classes, Dashboard, FileLocker, GettingStarted, Home, Lesson, Lessons, Navbar, Organization, Pathway, Pathways, People, StartAnonymousLesson, Student, SwitchAccount, TrialHome, TrialRegistration };
4108
3736
  //# sourceMappingURL=index.mjs.map