@local-civics/mgmt-ui 0.1.215 → 0.1.217

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,16 +1,14 @@
1
1
  import * as React from 'react';
2
2
  import { useState, useMemo } from 'react';
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';
3
+ import { IconChevronRight, IconVideo, IconSwitchHorizontal, IconLogout, IconHome2, IconGauge, IconCategory2, IconRoute, IconAlbum, IconLambda, IconClipboard, IconBuilding, IconBatteryEco, IconBooks, IconBackpack, IconClipboardCopy, IconTableExport, IconChevronDown, IconArrowLeft, IconSearch, IconCheck, IconTrash, IconPlus, IconLink, IconDownload, IconCloudUpload, IconInfoCircle, IconPlaylistAdd, IconPointer, 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, Image, Drawer, Divider, TextInput, Tooltip, ActionIcon, Badge as Badge$1, Overlay, Stack as Stack$5, ThemeIcon, Checkbox, Autocomplete, 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';
8
- import { DataTable } from 'mantine-datatable';
9
8
  import { Dropzone, MIME_TYPES } from '@mantine/dropzone';
10
9
  import { useForm } from '@mantine/form';
11
10
  import * as papa from 'papaparse';
12
11
  import { openConfirmModal, ModalsProvider } from '@mantine/modals';
13
- import AvatarInit from 'avatar-initials';
14
12
  import { Chart } from 'react-charts';
15
13
  import { useUncontrolled } from '@mantine/hooks';
16
14
 
@@ -41,7 +39,7 @@ function styleInject(css, ref) {
41
39
  }
42
40
  }
43
41
 
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}.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-xl{max-width:36rem}.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-100{--tw-bg-opacity:1;background-color:rgb(255 248 214/var(--tw-bg-opacity))}.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-slate-700:hover{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-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}";
42
+ 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{left:.75rem}.top-1\\/2{top:50%}.left-3\\.5{left:.875rem}.bottom-\\[-20px\\]{bottom:-20px}.left-1\\/2{left:50%}.m-3{margin:.75rem}.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-2{margin-left:-.5rem}.mt-4{margin-top:1rem}.mb-8{margin-bottom:2rem}.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-9{height:2.25rem}.h-8{height:2rem}.h-7{height:1.75rem}.h-12{height:3rem}.h-\\[300px\\]{height:300px}.h-screen{height:100vh}.h-11{height:2.75rem}.h-16{height:4rem}.h-\\[30px\\]{height:30px}.w-10{width:2.5rem}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.w-fit{width:-moz-fit-content;width:fit-content}.w-36{width:9rem}.w-28{width:7rem}.w-4{width:1rem}.w-9{width:2.25rem}.w-40{width:10rem}.w-8{width:2rem}.w-7{width:1.75rem}.w-64{width:16rem}.w-12{width:3rem}.w-16{width:4rem}.w-\\[440px\\]{width:440px}.w-20{width:5rem}.w-24{width:6rem}.w-\\[250px\\]{width:250px}.w-screen{width:100vw}.w-11{width:2.75rem}.w-\\[230px\\]{width:230px}.w-\\[30px\\]{width:30px}.min-w-0{min-width:0}.max-w-xl{max-width:36rem}.max-w-xs{max-width:20rem}.max-w-\\[460px\\]{max-width:460px}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.-translate-y-1\\/2{--tw-translate-y:-50%}.-translate-x-1\\/2,.-translate-y-1\\/2{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))}.-translate-x-1\\/2{--tw-translate-x:-50%}.rotate-180{--tw-rotate:180deg}.rotate-180,.rotate-90{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-90{--tw-rotate:90deg}.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}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-\\[2\\.2fr_1\\.2fr_1fr_1\\.2fr_1fr_0\\.6fr\\]{grid-template-columns:2.2fr 1.2fr 1fr 1.2fr 1fr .6fr}.grid-cols-\\[1\\.5fr_2fr_1fr_0\\.6fr\\]{grid-template-columns:1.5fr 2fr 1fr .6fr}.grid-cols-\\[1\\.5fr_2fr_0\\.8fr\\]{grid-template-columns:1.5fr 2fr .8fr}.grid-cols-\\[1fr_3fr\\]{grid-template-columns:1fr 3fr}.grid-cols-\\[1fr_1fr_2fr_0\\.8fr\\]{grid-template-columns:1fr 1fr 2fr .8fr}.grid-cols-\\[2fr_1fr\\]{grid-template-columns:2fr 1fr}.grid-cols-\\[2\\.2fr_1\\.2fr_1fr_1fr_0\\.6fr\\]{grid-template-columns:2.2fr 1.2fr 1fr 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-4{gap:1rem}.gap-1{gap:.25rem}.gap-3{gap:.75rem}.gap-2{gap:.5rem}.gap-1\\.5{gap:.375rem}.gap-2\\.5{gap:.625rem}.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\\.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)))}.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)))}.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-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-full{border-radius:9999px}.rounded-md{border-radius:.375rem}.rounded{border-radius:.25rem}.rounded-\\[8px\\]{border-radius:8px}.border{border-width:1px}.border-2{border-width:2px}.border-l-4{border-left-width:4px}.border-t{border-top-width:1px}.border-b{border-bottom-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-white{--tw-border-opacity:1;border-color:rgb(255 255 255/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-sky-blue-400\\/40{border-color:rgba(59,208,242,.4)}.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-sky-blue-400\\/20{background-color:rgba(59,208,242,.2)}.bg-mint-100{--tw-bg-opacity:1;background-color:rgb(208 251 240/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-gold-100{--tw-bg-opacity:1;background-color:rgb(255 248 214/var(--tw-bg-opacity))}.bg-mint-400\\/20{background-color:rgba(30,226,175,.2)}.bg-transparent{background-color:transparent}.bg-dark-blue-400{--tw-bg-opacity:1;background-color:rgb(35 42 58/var(--tw-bg-opacity))}.bg-white\\/90{background-color:hsla(0,0%,100%,.9)}.bg-slate-200{--tw-bg-opacity:1;background-color:rgb(226 232 240/var(--tw-bg-opacity))}.bg-slate-50{--tw-bg-opacity:1;background-color:rgb(248 250 252/var(--tw-bg-opacity))}.bg-sky-blue-400\\/15{background-color:rgba(59,208,242,.15)}.bg-mint-400\\/15{background-color:rgba(30,226,175,.15)}.bg-gold-400\\/15{background-color:rgba(255,212,77,.15)}.bg-sky-blue-400\\/25{background-color:rgba(59,208,242,.25)}.bg-mint-400\\/25{background-color:rgba(30,226,175,.25)}.bg-gold-400\\/25{background-color:rgba(255,212,77,.25)}.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-1{padding:.25rem}.p-4{padding:1rem}.p-8{padding:2rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-3{padding:.75rem}.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-2{padding-bottom:.5rem;padding-top:.5rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.px-2\\.5{padding-left:.625rem;padding-right:.625rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3\\.5{padding-left:.875rem;padding-right:.875rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-2\\.5{padding-bottom:.625rem;padding-top:.625rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-3\\.5{padding-bottom:.875rem;padding-top:.875rem}.py-0\\.5{padding-bottom:.125rem;padding-top:.125rem}.py-0{padding-bottom:0;padding-top:0}.py-4{padding-bottom:1rem;padding-top:1rem}.px-8{padding-left:2rem;padding-right:2rem}.py-6{padding-bottom:1.5rem;padding-top:1.5rem}.pl-9{padding-left:2.25rem}.pr-4{padding-right:1rem}.pl-10{padding-left:2.5rem}.pb-2{padding-bottom:.5rem}.pt-0\\.5{padding-top:.125rem}.pt-0{padding-top:0}.pb-12{padding-bottom:3rem}.pl-2\\.5{padding-left:.625rem}.pl-2{padding-left:.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.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-\\[10px\\]{font-size:10px}.text-\\[10\\.5px\\]{font-size:10.5px}.text-lg{font-size:1.125rem;line-height:1.75rem}.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-sky-blue-400{--tw-text-opacity:1;color:rgb(59 208 242/var(--tw-text-opacity))}.text-slate-400{--tw-text-opacity:1;color:rgb(148 163 184/var(--tw-text-opacity))}.text-slate-600{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.text-slate-300{--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}.text-mint-400{--tw-text-opacity:1;color:rgb(30 226 175/var(--tw-text-opacity))}.text-white\\/70{color:hsla(0,0%,100%,.7)}.text-slate-700{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.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))}.first\\:ml-0:first-child{margin-left:0}.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-slate-600:hover{--tw-text-opacity:1;color:rgb(71 85 105/var(--tw-text-opacity))}.hover\\:text-slate-700:hover{--tw-text-opacity:1;color:rgb(51 65 85/var(--tw-text-opacity))}.hover\\:text-red-500:hover{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.hover\\:text-sky-blue-400:hover{--tw-text-opacity:1;color:rgb(59 208 242/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
43
  styleInject(css_248z);
46
44
 
47
45
  function UserButton({ image, name, email }) {
@@ -125,25 +123,25 @@ function LinksGroup({ icon: Icon, href, label, accent = "cyan", initiallyOpened,
125
123
  ), 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));
126
124
  }
127
125
 
128
- var __defProp$f = Object.defineProperty;
129
- var __defProps$b = Object.defineProperties;
130
- var __getOwnPropDescs$b = Object.getOwnPropertyDescriptors;
131
- var __getOwnPropSymbols$f = Object.getOwnPropertySymbols;
132
- var __hasOwnProp$f = Object.prototype.hasOwnProperty;
133
- var __propIsEnum$f = Object.prototype.propertyIsEnumerable;
134
- var __defNormalProp$f = (obj, key, value) => key in obj ? __defProp$f(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
135
- var __spreadValues$f = (a, b) => {
126
+ var __defProp$g = Object.defineProperty;
127
+ var __defProps$d = Object.defineProperties;
128
+ var __getOwnPropDescs$d = Object.getOwnPropertyDescriptors;
129
+ var __getOwnPropSymbols$g = Object.getOwnPropertySymbols;
130
+ var __hasOwnProp$g = Object.prototype.hasOwnProperty;
131
+ var __propIsEnum$g = Object.prototype.propertyIsEnumerable;
132
+ var __defNormalProp$g = (obj, key, value) => key in obj ? __defProp$g(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
133
+ var __spreadValues$g = (a, b) => {
136
134
  for (var prop in b || (b = {}))
137
- if (__hasOwnProp$f.call(b, prop))
138
- __defNormalProp$f(a, prop, b[prop]);
139
- if (__getOwnPropSymbols$f)
140
- for (var prop of __getOwnPropSymbols$f(b)) {
141
- if (__propIsEnum$f.call(b, prop))
142
- __defNormalProp$f(a, prop, b[prop]);
135
+ if (__hasOwnProp$g.call(b, prop))
136
+ __defNormalProp$g(a, prop, b[prop]);
137
+ if (__getOwnPropSymbols$g)
138
+ for (var prop of __getOwnPropSymbols$g(b)) {
139
+ if (__propIsEnum$g.call(b, prop))
140
+ __defNormalProp$g(a, prop, b[prop]);
143
141
  }
144
142
  return a;
145
143
  };
146
- var __spreadProps$b = (a, b) => __defProps$b(a, __getOwnPropDescs$b(b));
144
+ var __spreadProps$d = (a, b) => __defProps$d(a, __getOwnPropDescs$d(b));
147
145
  const data = [
148
146
  { label: "Home", icon: IconHome2, accent: "cyan" },
149
147
  { label: "Dashboard", icon: IconGauge, accent: "mint" },
@@ -170,12 +168,12 @@ function Navbar(props) {
170
168
  }
171
169
  return /* @__PURE__ */ React.createElement(
172
170
  LinksGroup,
173
- __spreadProps$b(__spreadValues$f(__spreadValues$f({
171
+ __spreadProps$d(__spreadValues$g(__spreadValues$g({
174
172
  key: item.label,
175
173
  active: props.active
176
174
  }, item), context), {
177
175
  links: (item.links || []).map((link) => {
178
- return __spreadValues$f(__spreadValues$f({}, link), props.links[`${item.label}/${link.label}`] || { notifications: 0, href: "" });
176
+ return __spreadValues$g(__spreadValues$g({}, link), props.links[`${item.label}/${link.label}`] || { notifications: 0, href: "" });
179
177
  })
180
178
  })
181
179
  );
@@ -195,7 +193,7 @@ const UtilLink = (props) => {
195
193
  );
196
194
  };
197
195
 
198
- const useStyles$k = createStyles((theme) => ({
196
+ const useStyles$9 = createStyles((theme) => ({
199
197
  inner: {
200
198
  paddingTop: theme.spacing.xl,
201
199
  paddingBottom: theme.spacing.xl * 4
@@ -231,7 +229,7 @@ const useStyles$k = createStyles((theme) => ({
231
229
  }
232
230
  }));
233
231
  const GettingStarted = (props) => {
234
- const { classes } = useStyles$k();
232
+ const { classes } = useStyles$9();
235
233
  return /* @__PURE__ */ React.createElement(
236
234
  Modal,
237
235
  {
@@ -245,7 +243,7 @@ const GettingStarted = (props) => {
245
243
  );
246
244
  };
247
245
 
248
- const useStyles$j = createStyles((theme) => ({
246
+ const useStyles$8 = createStyles((theme) => ({
249
247
  title: {
250
248
  fontSize: 34,
251
249
  fontWeight: 900,
@@ -286,7 +284,7 @@ const useStyles$j = createStyles((theme) => ({
286
284
  }
287
285
  }));
288
286
  const SwitchAccount = (props) => {
289
- const { classes, theme } = useStyles$j();
287
+ const { classes, theme } = useStyles$8();
290
288
  const options = props.accounts.map((a) => {
291
289
  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")));
292
290
  });
@@ -317,56 +315,55 @@ const StatsGroup = ({ data, footer }) => {
317
315
  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);
318
316
  };
319
317
 
320
- const Tabs = (props) => {
321
- var _a;
322
- const tabs = (_a = props.data) == null ? void 0 : _a.map((item) => /* @__PURE__ */ React.createElement(Tabs$1.Tab, { key: item.value, value: item.value }, item.label || item.value));
323
- return /* @__PURE__ */ React.createElement(Tabs$1, { value: props.value, onTabChange: props.onChange }, /* @__PURE__ */ React.createElement(Tabs$1.List, null, tabs));
318
+ const SIZE = {
319
+ sm: { box: "h-11 w-11", rounded: "rounded-xl", icon: 20 },
320
+ lg: { box: "h-16 w-16", rounded: "rounded-2xl", icon: 28 }
324
321
  };
325
-
326
- const useStyles$i = createStyles((theme) => ({
327
- button: {
328
- borderTopRightRadius: 0,
329
- borderBottomRightRadius: 0,
330
- marginLeft: 0,
331
- marginRight: 0
332
- },
333
- menuControl: {
334
- borderTopLeftRadius: 0,
335
- borderBottomLeftRadius: 0,
336
- border: 0,
337
- borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
322
+ const ACCENT = {
323
+ cyan: { bg: "bg-sky-blue-400/15", text: "text-sky-blue-400" },
324
+ mint: { bg: "bg-mint-400/15", text: "text-mint-400" },
325
+ gold: { bg: "bg-gold-400/15", text: "text-gold-400" }
326
+ };
327
+ function Emblem(props) {
328
+ const s = SIZE[props.size || "sm"];
329
+ const a = ACCENT[props.accent];
330
+ const Icon = props.icon;
331
+ if (props.imageURL) {
332
+ return /* @__PURE__ */ React.createElement("img", { src: props.imageURL, alt: props.alt || "", className: `${s.box} shrink-0 ${s.rounded} object-cover` });
338
333
  }
339
- }));
334
+ return /* @__PURE__ */ React.createElement("div", { className: `flex ${s.box} shrink-0 items-center justify-center ${s.rounded} ${a.bg}` }, /* @__PURE__ */ React.createElement(Icon, { size: s.icon, stroke: 1.75, className: a.text }));
335
+ }
336
+
340
337
  const SplitButton$4 = (props) => {
341
- const { classes, theme } = useStyles$i();
342
- theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
343
- return /* @__PURE__ */ React.createElement(Stack$5, { spacing: "sm" }, /* @__PURE__ */ React.createElement(
344
- Button,
338
+ return /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement(
339
+ Link,
345
340
  {
346
- component: Link,
347
341
  to: props.href,
348
- className: classes.button,
349
- variant: "gradient"
342
+ 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 no-underline hover:bg-slate-50"
350
343
  },
351
344
  "Preview"
352
345
  ), /* @__PURE__ */ React.createElement(
353
- Button,
346
+ "button",
354
347
  {
355
- leftIcon: /* @__PURE__ */ React.createElement(IconClipboardCopy, { size: 14 }),
356
- onClick: props.onCopyLinkClick
348
+ type: "button",
349
+ onClick: props.onCopyLinkClick,
350
+ 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"
357
351
  },
352
+ /* @__PURE__ */ React.createElement(IconClipboardCopy, { size: 13, stroke: 2 }),
358
353
  "Copy link"
359
354
  ), /* @__PURE__ */ React.createElement(
360
- Button,
355
+ "button",
361
356
  {
362
- leftIcon: /* @__PURE__ */ React.createElement(IconTableExport, { size: 14 }),
363
- onClick: props.onExportDataClick
357
+ type: "button",
358
+ onClick: props.onExportDataClick,
359
+ 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)]"
364
360
  },
361
+ /* @__PURE__ */ React.createElement(IconTableExport, { size: 13, stroke: 2 }),
365
362
  "Export data (.csv)"
366
363
  ));
367
364
  };
368
365
 
369
- const useStyles$h = createStyles((theme) => ({
366
+ const useStyles$7 = createStyles((theme) => ({
370
367
  wrapper: {
371
368
  display: "flex",
372
369
  alignItems: "center",
@@ -417,7 +414,7 @@ const useStyles$h = createStyles((theme) => ({
417
414
  }
418
415
  }));
419
416
  const PlaceholderBanner = (props) => {
420
- const { classes } = useStyles$h();
417
+ const { classes } = useStyles$7();
421
418
  const title = props.title || "Nothing to display";
422
419
  const description = props.description || "We don't have anything to show you here just yet. Add data, check back later, or adjust your search.";
423
420
  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 }));
@@ -427,8 +424,7 @@ function Stack$4(props) {
427
424
  if (props.items.length === 0) {
428
425
  return null;
429
426
  }
430
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Grid.Col, { span: 6 }, /* @__PURE__ */ React.createElement(Text, { component: Link, to: row.href, color: "dark.4", weight: "bold", size: "md" }, row.lessonName)), /* @__PURE__ */ React.createElement(Grid.Col, { span: 6 }, row.completion >= 1 && /* @__PURE__ */ React.createElement(Badge$1, { variant: "filled" }, "Complete"), row.completion === 0 && !row.isStarted && /* @__PURE__ */ React.createElement(Badge$1, { color: "red", variant: "filled" }, "Not started"), row.completion > 0 && row.completion < 1 && /* @__PURE__ */ React.createElement(Badge$1, { color: "violet", variant: "filled" }, Math.round((row.completion + Number.EPSILON) * 100), "% Complete"))));
431
- return /* @__PURE__ */ React.createElement(Grid, { grow: true, gutter: "lg", sx: { padding: 20, minWidth: 700 } }, rows);
427
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2" }, props.items.map((row) => /* @__PURE__ */ React.createElement("div", { key: row.lessonName, className: "flex items-center justify-between gap-4 py-1.5" }, /* @__PURE__ */ React.createElement(Link, { to: row.href, className: "text-sm font-bold text-dark-blue-400 no-underline hover:underline" }, row.lessonName), row.completion >= 1 && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 rounded-full bg-mint-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, "Complete"), row.completion === 0 && !row.isStarted && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 rounded-full bg-slate-100 px-2.5 py-1 text-[10px] font-bold text-slate-500" }, "Not started"), row.completion > 0 && row.completion < 1 && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 rounded-full bg-gold-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, Math.round((row.completion + Number.EPSILON) * 100), "% Complete"))));
432
428
  }
433
429
 
434
430
  function useSortableData(items, config = { key: "", direction: null }) {
@@ -469,28 +465,29 @@ function useSortableData(items, config = { key: "", direction: null }) {
469
465
  return { items: sortedItems, requestSort, sortConfig };
470
466
  }
471
467
 
472
- var __defProp$e = Object.defineProperty;
473
- var __defProps$a = Object.defineProperties;
474
- var __getOwnPropDescs$a = Object.getOwnPropertyDescriptors;
475
- var __getOwnPropSymbols$e = Object.getOwnPropertySymbols;
476
- var __hasOwnProp$e = Object.prototype.hasOwnProperty;
477
- var __propIsEnum$e = Object.prototype.propertyIsEnumerable;
478
- var __defNormalProp$e = (obj, key, value) => key in obj ? __defProp$e(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
479
- var __spreadValues$e = (a, b) => {
468
+ var __defProp$f = Object.defineProperty;
469
+ var __defProps$c = Object.defineProperties;
470
+ var __getOwnPropDescs$c = Object.getOwnPropertyDescriptors;
471
+ var __getOwnPropSymbols$f = Object.getOwnPropertySymbols;
472
+ var __hasOwnProp$f = Object.prototype.hasOwnProperty;
473
+ var __propIsEnum$f = Object.prototype.propertyIsEnumerable;
474
+ var __defNormalProp$f = (obj, key, value) => key in obj ? __defProp$f(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
475
+ var __spreadValues$f = (a, b) => {
480
476
  for (var prop in b || (b = {}))
481
- if (__hasOwnProp$e.call(b, prop))
482
- __defNormalProp$e(a, prop, b[prop]);
483
- if (__getOwnPropSymbols$e)
484
- for (var prop of __getOwnPropSymbols$e(b)) {
485
- if (__propIsEnum$e.call(b, prop))
486
- __defNormalProp$e(a, prop, b[prop]);
477
+ if (__hasOwnProp$f.call(b, prop))
478
+ __defNormalProp$f(a, prop, b[prop]);
479
+ if (__getOwnPropSymbols$f)
480
+ for (var prop of __getOwnPropSymbols$f(b)) {
481
+ if (__propIsEnum$f.call(b, prop))
482
+ __defNormalProp$f(a, prop, b[prop]);
487
483
  }
488
484
  return a;
489
485
  };
490
- var __spreadProps$a = (a, b) => __defProps$a(a, __getOwnPropDescs$a(b));
486
+ var __spreadProps$c = (a, b) => __defProps$c(a, __getOwnPropDescs$c(b));
491
487
  function Table$k(props) {
488
+ const [expanded, setExpanded] = React.useState({});
492
489
  const preparedItems = React.useMemo(() => {
493
- return props.items.map((item) => __spreadProps$a(__spreadValues$e({}, item), {
490
+ return props.items.map((item) => __spreadProps$c(__spreadValues$f({}, item), {
494
491
  status: item.isComplete ? 1 : 0
495
492
  }));
496
493
  }, [props.items]);
@@ -506,40 +503,22 @@ function Table$k(props) {
506
503
  }
507
504
  );
508
505
  }
509
- const sortStatus = {
510
- columnAccessor: sortConfig.key,
511
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
512
- };
513
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(
514
- DataTable,
515
- {
516
- verticalSpacing: "sm",
517
- sx: { minWidth: 700 },
518
- withBorder: false,
519
- borderRadius: "sm",
520
- withColumnBorders: true,
521
- striped: true,
522
- highlightOnHover: true,
523
- records: sortedItems,
524
- sortStatus,
525
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
526
- idAccessor: "userId",
527
- columns: [{
528
- accessor: "name",
529
- title: "Student Name",
530
- sortable: true,
531
- 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)))
532
- }, {
533
- accessor: "status",
534
- title: "Status",
535
- sortable: true,
536
- render: (row) => /* @__PURE__ */ React.createElement(React.Fragment, null, !!row.isComplete && /* @__PURE__ */ React.createElement(Badge$1, { variant: "filled" }, "Complete"), !row.isComplete && /* @__PURE__ */ React.createElement(Badge$1, { color: "red", variant: "filled" }, "Incomplete"))
537
- }],
538
- rowExpansion: {
539
- content: ({ record }) => /* @__PURE__ */ React.createElement(Stack$4, { items: record.lessons })
540
- }
541
- }
542
- ));
506
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
507
+ 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("status"), className: "w-28 shrink-0 text-center hover:text-slate-600" }, "Status", indicator("status")), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), sortedItems.map((row) => {
508
+ var _a;
509
+ const isOpen = !!expanded[row.userId];
510
+ const initials = (((_a = row.name) == null ? void 0 : _a[0]) || row.email[0] || "?").toUpperCase();
511
+ return /* @__PURE__ */ React.createElement("div", { key: row.userId, className: "rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement(
512
+ "div",
513
+ {
514
+ onClick: () => setExpanded(__spreadProps$c(__spreadValues$f({}, expanded), { [row.userId]: !isOpen })),
515
+ className: "flex cursor-pointer items-center gap-4 p-4"
516
+ },
517
+ /* @__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-mint-400/20 text-xs font-bold text-dark-blue-400" }, initials), /* @__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))),
518
+ /* @__PURE__ */ React.createElement("div", { className: "w-28 shrink-0 text-center" }, row.isComplete ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-mint-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, "Complete") : /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[10px] font-bold text-slate-500" }, "Incomplete")),
519
+ /* @__PURE__ */ React.createElement(IconChevronDown, { size: 15, stroke: 2.3, className: `shrink-0 text-slate-400 transition-transform ${isOpen ? "rotate-180" : ""}` })
520
+ ), isOpen && /* @__PURE__ */ React.createElement("div", { className: "border-t border-slate-100 px-4 py-3" }, /* @__PURE__ */ React.createElement(Stack$4, { items: row.lessons })));
521
+ }));
543
522
  }
544
523
 
545
524
  function Table$j(props) {
@@ -549,121 +528,63 @@ function Table$j(props) {
549
528
  PlaceholderBanner,
550
529
  {
551
530
  title: "No lessons to display",
552
- description: "There are not lessons in badge.",
531
+ description: "There are no lessons in this badge.",
553
532
  loading: props.loading,
554
533
  icon: "badges"
555
534
  }
556
535
  );
557
536
  }
558
- const sortStatus = {
559
- columnAccessor: sortConfig.key,
560
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
561
- };
562
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(
563
- DataTable,
564
- {
565
- verticalSpacing: "sm",
566
- sx: { minWidth: 700 },
567
- highlightOnHover: true,
568
- striped: true,
569
- records: sortedItems,
570
- sortStatus,
571
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
572
- columns: [
573
- {
574
- accessor: "lessonName",
575
- title: "Lesson Name",
576
- sortable: true,
577
- render: (row) => /* @__PURE__ */ React.createElement(Text, { component: Link, to: row.href }, row.lessonName)
578
- },
579
- {
580
- accessor: "percentageCompletion",
581
- title: "Lesson Completion",
582
- sortable: true,
583
- render: (row) => `${Math.round((row.percentageCompletion + Number.EPSILON) * 100)}%`
584
- }
585
- ]
586
- }
587
- ));
537
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
538
+ 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("button", { onClick: () => requestSort("lessonName"), className: "flex-1 text-left hover:text-slate-600" }, "Lesson Name", indicator("lessonName")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("percentageCompletion"), className: "w-36 shrink-0 text-right hover:text-slate-600" }, "Lesson Completion", indicator("percentageCompletion"))), sortedItems.map((row) => /* @__PURE__ */ React.createElement(
539
+ Link,
540
+ {
541
+ key: row.lessonId,
542
+ to: row.href,
543
+ className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
544
+ },
545
+ /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1 text-sm font-bold text-dark-blue-400" }, row.lessonName),
546
+ /* @__PURE__ */ React.createElement("div", { className: "w-36 shrink-0 text-right text-xs text-slate-500" }, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")
547
+ )));
588
548
  }
589
549
 
590
- const useStyles$g = createStyles((theme) => ({
591
- title: {
592
- fontSize: 34,
593
- fontWeight: 900,
594
- [theme.fn.smallerThan("sm")]: {
595
- fontSize: 24
596
- }
597
- },
598
- description: {
599
- maxWidth: 600
600
- }
601
- }));
550
+ const TABS$4 = [
551
+ { label: "By lesson", value: "lessons" },
552
+ { label: "By student", value: "students" }
553
+ ];
602
554
  const Badge = (props) => {
603
- const { classes } = useStyles$g();
604
555
  const [tab, setTab] = useState("lessons");
605
556
  const numberOfStudents = props.students.length;
606
557
  const numberOfBadges = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length : 0;
607
- numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length / numberOfStudents : 0;
608
- return /* @__PURE__ */ React.createElement(Container, { fluid: true, 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(
609
- Badge$1,
610
- {
611
- variant: "filled",
612
- leftSection: /* @__PURE__ */ React.createElement(ActionIcon, { color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React.createElement(IconArrowLeft, { size: 14 })),
613
- size: "lg"
614
- },
615
- "Back"
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(
558
+ return /* @__PURE__ */ React.createElement("div", { className: "flex 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: "flex items-start gap-4" }, /* @__PURE__ */ React.createElement(Emblem, { imageURL: props.imageURL, alt: props.displayName, size: "lg", icon: IconAlbum, accent: "mint" }), /* @__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 || "Badge"), /* @__PURE__ */ React.createElement("p", { className: "max-w-xl text-sm text-slate-500" }, props.description || "No description"))), !props.trial && /* @__PURE__ */ React.createElement(
617
559
  SplitButton$4,
618
560
  {
619
561
  href: props.href,
620
562
  onCopyLinkClick: props.onCopyLinkClick,
621
563
  onExportDataClick: props.onExportDataClick
622
564
  }
623
- ))))), /* @__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: [
565
+ )), /* @__PURE__ */ React.createElement(StatsGroup, { data: [
624
566
  {
625
567
  title: props.trial ? "LESSONS SUBMITTED" : "BADGE COMPLETION",
626
- value: props.trial ? props.lessonsCompleted || 0 : numberOfBadges,
627
- unit: props.trial ? "" : ""
568
+ value: props.trial ? props.lessonsCompleted || 0 : numberOfBadges
628
569
  }
629
- ] }), !props.trial && /* @__PURE__ */ React.createElement(
630
- Select,
570
+ ] }), !props.trial && /* @__PURE__ */ React.createElement("div", { className: "relative w-full max-w-xs" }, /* @__PURE__ */ React.createElement(IconCategory2, { size: 16, stroke: 2, className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" }), /* @__PURE__ */ React.createElement(
571
+ "select",
631
572
  {
632
- clearable: true,
633
- clearButtonLabel: "Clear class selection",
634
- size: "sm",
635
- placeholder: "Select a class",
636
- nothingFound: "No options",
637
573
  value: props.classId,
638
- onChange: props.onClassChange,
639
- icon: /* @__PURE__ */ React.createElement(IconCategory2, null),
640
- data: props.classes.map((g) => {
641
- return { value: g.classId, label: g.name };
642
- })
643
- }
644
- ), /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0 }, !props.trial && /* @__PURE__ */ React.createElement(
645
- Tabs,
646
- {
647
- value: tab,
648
- data: [
649
- { label: "By lesson", value: "lessons" },
650
- { label: "By student", value: "students" }
651
- ],
652
- onChange: setTab
653
- }
654
- ), (!!props.trial || tab === "lessons") && /* @__PURE__ */ React.createElement(
655
- Table$j,
656
- {
657
- loading: props.loading,
658
- items: props.lessons
659
- }
660
- ), !props.trial && tab === "students" && /* @__PURE__ */ React.createElement(
661
- Table$k,
574
+ onChange: (e) => props.onClassChange(e.target.value),
575
+ className: "w-full appearance-none rounded-lg border border-slate-200 bg-white py-2 pl-9 pr-4 text-sm text-dark-blue-400 focus:border-sky-blue-400 focus:outline-none"
576
+ },
577
+ /* @__PURE__ */ React.createElement("option", { value: "" }, "All classes"),
578
+ props.classes.map((c) => /* @__PURE__ */ React.createElement("option", { key: c.classId, value: c.classId }, c.name))
579
+ )), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, !props.trial && /* @__PURE__ */ React.createElement("div", { className: "flex w-fit gap-1 rounded-xl border border-slate-200 bg-white p-1" }, TABS$4.map((t) => /* @__PURE__ */ React.createElement(
580
+ "button",
662
581
  {
663
- loading: props.loading,
664
- items: props.students
665
- }
666
- )))))));
582
+ key: t.value,
583
+ onClick: () => setTab(t.value),
584
+ 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"}`
585
+ },
586
+ t.label
587
+ ))), (!!props.trial || tab === "lessons") && /* @__PURE__ */ React.createElement(Table$j, { loading: props.loading, items: props.lessons }), !props.trial && tab === "students" && /* @__PURE__ */ React.createElement(Table$k, { loading: props.loading, items: props.students })));
667
588
  };
668
589
 
669
590
  function Table$i(props) {
@@ -673,20 +594,40 @@ function Table$i(props) {
673
594
  if (props.items.length === 0) {
674
595
  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.");
675
596
  }
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(
597
+ 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" }, "Badge"), /* @__PURE__ */ React.createElement("div", { className: "w-40 shrink-0" }, "Pathway"), /* @__PURE__ */ React.createElement("div", { className: "w-28 shrink-0" }, "Lessons"), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), props.items.map((row) => /* @__PURE__ */ React.createElement(
677
598
  Link,
678
599
  {
679
600
  key: row.badgeId,
680
601
  to: row.href,
681
- className: `block px-5 py-4 no-underline hover:bg-slate-50 ${i < props.items.length - 1 ? "border-b border-slate-100" : ""}`
602
+ className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
603
+ },
604
+ /* @__PURE__ */ React.createElement(Emblem, { imageURL: row.imageURL, alt: row.name, size: "sm", icon: IconAlbum, accent: "mint" }),
605
+ /* @__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)),
606
+ /* @__PURE__ */ React.createElement("div", { className: "w-40 shrink-0 text-xs text-slate-500" }, row.pathway || "\u2014"),
607
+ /* @__PURE__ */ React.createElement("div", { className: "w-28 shrink-0 text-xs text-slate-500" }, row.numberOfLessons ? `${row.numberOfLessons} lesson${row.numberOfLessons === 1 ? "" : "s"}` : "\u2014"),
608
+ /* @__PURE__ */ React.createElement(IconChevronRight, { size: 16, stroke: 2, className: "w-4 shrink-0 text-slate-300" })
609
+ )));
610
+ }
611
+
612
+ function PathwayFilterPills(props) {
613
+ if (props.pathways.length === 0) {
614
+ return null;
615
+ }
616
+ const pillClass = (active) => `rounded-full border px-3.5 py-1.5 text-xs font-bold ${active ? "border-sky-blue-400/40 bg-sky-blue-400/20 text-dark-blue-400" : "border-slate-200 bg-white text-slate-500 hover:bg-slate-50"}`;
617
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement("button", { type: "button", onClick: () => props.onChange(""), className: pillClass(!props.selected) }, "All"), props.pathways.map((p) => /* @__PURE__ */ React.createElement(
618
+ "button",
619
+ {
620
+ key: p.pathwayId,
621
+ type: "button",
622
+ onClick: () => props.onChange(p.pathwayId),
623
+ className: pillClass(props.selected === p.pathwayId)
682
624
  },
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)
625
+ p.title
685
626
  )));
686
627
  }
687
628
 
688
629
  const Badges = (props) => {
689
- return /* @__PURE__ */ React.createElement("div", { className: "flex 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(
630
+ return /* @__PURE__ */ React.createElement("div", { className: "flex 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(PathwayFilterPills, { pathways: props.pathways, selected: props.selectedPathway, onChange: props.onPathwayChange }), /* @__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
631
  "input",
691
632
  {
692
633
  type: "text",
@@ -698,6 +639,7 @@ const Badges = (props) => {
698
639
  };
699
640
 
700
641
  function Table$h(props) {
642
+ const { items: sortedItems, requestSort, sortConfig } = useSortableData(props.items);
701
643
  if (props.items.length === 0) {
702
644
  return /* @__PURE__ */ React.createElement(
703
645
  PlaceholderBanner,
@@ -709,8 +651,24 @@ function Table$h(props) {
709
651
  }
710
652
  );
711
653
  }
712
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement("tr", { key: row.studentName }, /* @__PURE__ */ React.createElement("td", null, /* @__PURE__ */ React.createElement(UnstyledButton, { onClick: () => props.onViewProfile(row) }, row.studentName)), /* @__PURE__ */ React.createElement("td", null, row.className)));
713
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(Table$l, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Student Name"), /* @__PURE__ */ React.createElement("th", null, "Class Name"))), /* @__PURE__ */ React.createElement("tbody", null, rows)));
654
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
655
+ 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-[2fr_1fr] gap-3 border-b border-slate-100 px-5 py-3 text-[10px] font-bold uppercase tracking-wide text-slate-500" }, /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("studentName"), className: "flex items-center text-left hover:text-slate-700" }, "Student Name", indicator("studentName")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("className"), className: "flex items-center text-left hover:text-slate-700" }, "Class Name", indicator("className"))), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
656
+ "div",
657
+ {
658
+ key: row.studentId,
659
+ className: `grid grid-cols-[2fr_1fr] items-center gap-3 px-5 py-3.5 ${i < sortedItems.length - 1 ? "border-b border-slate-100" : ""}`
660
+ },
661
+ /* @__PURE__ */ React.createElement(
662
+ "button",
663
+ {
664
+ type: "button",
665
+ onClick: () => props.onViewProfile(row),
666
+ className: "truncate text-left text-xs font-bold text-dark-blue-400 hover:text-sky-blue-400"
667
+ },
668
+ row.studentName
669
+ ),
670
+ /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs text-slate-500" }, row.className)
671
+ )));
714
672
  }
715
673
 
716
674
  const units = [
@@ -737,7 +695,32 @@ function relativeTimeFromElapsed(elapsed) {
737
695
  return "";
738
696
  }
739
697
 
698
+ var __defProp$e = Object.defineProperty;
699
+ var __defProps$b = Object.defineProperties;
700
+ var __getOwnPropDescs$b = Object.getOwnPropertyDescriptors;
701
+ var __getOwnPropSymbols$e = Object.getOwnPropertySymbols;
702
+ var __hasOwnProp$e = Object.prototype.hasOwnProperty;
703
+ var __propIsEnum$e = Object.prototype.propertyIsEnumerable;
704
+ var __defNormalProp$e = (obj, key, value) => key in obj ? __defProp$e(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
705
+ var __spreadValues$e = (a, b) => {
706
+ for (var prop in b || (b = {}))
707
+ if (__hasOwnProp$e.call(b, prop))
708
+ __defNormalProp$e(a, prop, b[prop]);
709
+ if (__getOwnPropSymbols$e)
710
+ for (var prop of __getOwnPropSymbols$e(b)) {
711
+ if (__propIsEnum$e.call(b, prop))
712
+ __defNormalProp$e(a, prop, b[prop]);
713
+ }
714
+ return a;
715
+ };
716
+ var __spreadProps$b = (a, b) => __defProps$b(a, __getOwnPropDescs$b(b));
740
717
  function Table$g(props) {
718
+ const preparedItems = React.useMemo(() => {
719
+ return props.items.map((item) => __spreadProps$b(__spreadValues$e({}, item), {
720
+ updatedAtDate: new Date(item.updatedAt)
721
+ }));
722
+ }, [props.items]);
723
+ const { items: sortedItems, requestSort, sortConfig } = useSortableData(preparedItems);
741
724
  if (props.items.length === 0) {
742
725
  return /* @__PURE__ */ React.createElement(
743
726
  PlaceholderBanner,
@@ -749,11 +732,22 @@ function Table$g(props) {
749
732
  }
750
733
  );
751
734
  }
752
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement("tr", { key: row.studentName + row.lessonName }, /* @__PURE__ */ React.createElement("td", null, row.studentName), /* @__PURE__ */ React.createElement("td", null, row.lessonName), /* @__PURE__ */ React.createElement("td", null, row.reflection), /* @__PURE__ */ React.createElement("td", null, relativeTimeFromDates(new Date(row.updatedAt)))));
753
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(Table$l, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Student Name"), /* @__PURE__ */ React.createElement("th", null, "Lesson Name"), /* @__PURE__ */ React.createElement("th", null, "Reflection"), /* @__PURE__ */ React.createElement("th", null, "Updated At"))), /* @__PURE__ */ React.createElement("tbody", null, rows)));
735
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
736
+ 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-[1fr_1fr_2fr_0.8fr] gap-3 border-b border-slate-100 px-5 py-3 text-[10px] font-bold uppercase tracking-wide text-slate-500" }, /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("studentName"), className: "flex items-center text-left hover:text-slate-700" }, "Student Name", indicator("studentName")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("lessonName"), className: "flex items-center text-left hover:text-slate-700" }, "Lesson Name", indicator("lessonName")), /* @__PURE__ */ React.createElement("div", null, "Reflection"), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("updatedAtDate"), className: "flex items-center text-left hover:text-slate-700" }, "Updated At", indicator("updatedAtDate"))), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
737
+ "div",
738
+ {
739
+ key: row.studentName + row.lessonName,
740
+ className: `grid grid-cols-[1fr_1fr_2fr_0.8fr] items-center gap-3 px-5 py-3.5 ${i < sortedItems.length - 1 ? "border-b border-slate-100" : ""}`
741
+ },
742
+ /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs font-bold text-dark-blue-400" }, row.studentName),
743
+ /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs text-slate-500" }, row.lessonName),
744
+ /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-500" }, row.reflection),
745
+ /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-500" }, relativeTimeFromDates(row.updatedAtDate))
746
+ )));
754
747
  }
755
748
 
756
749
  function Table$f(props) {
750
+ const { items: sortedItems, requestSort, sortConfig } = useSortableData(props.items);
757
751
  if (props.items.length === 0) {
758
752
  return /* @__PURE__ */ React.createElement(
759
753
  PlaceholderBanner,
@@ -765,11 +759,20 @@ function Table$f(props) {
765
759
  }
766
760
  );
767
761
  }
768
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement("tr", { key: row.studentName }, /* @__PURE__ */ React.createElement("td", null, row.studentName), /* @__PURE__ */ React.createElement("td", null, row.impactStatement)));
769
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(Table$l, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Student Name"), /* @__PURE__ */ React.createElement("th", null, "Impact Statement"))), /* @__PURE__ */ React.createElement("tbody", null, rows)));
762
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
763
+ 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-[1fr_3fr] gap-3 border-b border-slate-100 px-5 py-3 text-[10px] font-bold uppercase tracking-wide text-slate-500" }, /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("studentName"), className: "flex items-center text-left hover:text-slate-700" }, "Student Name", indicator("studentName")), /* @__PURE__ */ React.createElement("div", null, "Impact Statement")), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
764
+ "div",
765
+ {
766
+ key: row.studentName,
767
+ className: `grid grid-cols-[1fr_3fr] items-center gap-3 px-5 py-3.5 ${i < sortedItems.length - 1 ? "border-b border-slate-100" : ""}`
768
+ },
769
+ /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs font-bold text-dark-blue-400" }, row.studentName),
770
+ /* @__PURE__ */ React.createElement("div", { className: "text-xs text-slate-500" }, row.impactStatement)
771
+ )));
770
772
  }
771
773
 
772
774
  function Table$e(props) {
775
+ const { items: sortedItems, requestSort, sortConfig } = useSortableData(props.items);
773
776
  if (props.items.length === 0) {
774
777
  return /* @__PURE__ */ React.createElement(
775
778
  PlaceholderBanner,
@@ -781,11 +784,29 @@ function Table$e(props) {
781
784
  }
782
785
  );
783
786
  }
784
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement("tr", { key: row.badgeId }, /* @__PURE__ */ React.createElement("td", null, /* @__PURE__ */ React.createElement(UnstyledButton, { onClick: () => props.onClick && props.onClick(row) }, row.name)), /* @__PURE__ */ React.createElement("td", null, row.description), /* @__PURE__ */ React.createElement("td", null, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")));
785
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(Table$l, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Badge Name"), /* @__PURE__ */ React.createElement("th", null, "Description"), /* @__PURE__ */ React.createElement("th", null, "Completion"))), /* @__PURE__ */ React.createElement("tbody", null, rows)));
787
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
788
+ 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-[1.5fr_2fr_0.8fr] gap-3 border-b border-slate-100 px-5 py-3 text-[10px] font-bold uppercase tracking-wide text-slate-500" }, /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("name"), className: "flex items-center text-left hover:text-slate-700" }, "Badge Name", indicator("name")), /* @__PURE__ */ React.createElement("div", null, "Description"), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("percentageCompletion"), className: "flex items-center justify-center text-center hover:text-slate-700" }, "Completion", indicator("percentageCompletion"))), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
789
+ "div",
790
+ {
791
+ key: row.badgeId,
792
+ className: `grid grid-cols-[1.5fr_2fr_0.8fr] items-center gap-3 px-5 py-3.5 ${i < sortedItems.length - 1 ? "border-b border-slate-100" : ""}`
793
+ },
794
+ /* @__PURE__ */ React.createElement(
795
+ "button",
796
+ {
797
+ type: "button",
798
+ onClick: () => props.onClick && props.onClick(row),
799
+ className: "truncate text-left text-xs font-bold text-dark-blue-400 hover:text-sky-blue-400"
800
+ },
801
+ row.name
802
+ ),
803
+ /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs text-slate-500" }, row.description),
804
+ /* @__PURE__ */ React.createElement("div", { className: "text-center text-xs font-bold text-dark-blue-400" }, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")
805
+ )));
786
806
  }
787
807
 
788
808
  function Table$d(props) {
809
+ const { items: sortedItems, requestSort, sortConfig } = useSortableData(props.items);
789
810
  if (props.items.length === 0) {
790
811
  return /* @__PURE__ */ React.createElement(
791
812
  PlaceholderBanner,
@@ -797,13 +818,37 @@ function Table$d(props) {
797
818
  }
798
819
  );
799
820
  }
800
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement("tr", { key: row.lessonId }, /* @__PURE__ */ React.createElement("td", null, /* @__PURE__ */ React.createElement(UnstyledButton, { onClick: () => props.onClick && props.onClick(row) }, row.name)), /* @__PURE__ */ React.createElement("td", null, row.description), /* @__PURE__ */ React.createElement("td", null, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")));
801
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(Table$l, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React.createElement("thead", null, /* @__PURE__ */ React.createElement("tr", null, /* @__PURE__ */ React.createElement("th", null, "Lesson Name"), /* @__PURE__ */ React.createElement("th", null, "Description"), /* @__PURE__ */ React.createElement("th", null, "Completion"))), /* @__PURE__ */ React.createElement("tbody", null, rows)));
821
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
822
+ 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-[1.5fr_2fr_0.8fr] gap-3 border-b border-slate-100 px-5 py-3 text-[10px] font-bold uppercase tracking-wide text-slate-500" }, /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("name"), className: "flex items-center text-left hover:text-slate-700" }, "Lesson Name", indicator("name")), /* @__PURE__ */ React.createElement("div", null, "Description"), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("percentageCompletion"), className: "flex items-center justify-center text-center hover:text-slate-700" }, "Completion", indicator("percentageCompletion"))), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
823
+ "div",
824
+ {
825
+ key: row.lessonId,
826
+ className: `grid grid-cols-[1.5fr_2fr_0.8fr] items-center gap-3 px-5 py-3.5 ${i < sortedItems.length - 1 ? "border-b border-slate-100" : ""}`
827
+ },
828
+ /* @__PURE__ */ React.createElement(
829
+ "button",
830
+ {
831
+ type: "button",
832
+ onClick: () => props.onClick && props.onClick(row),
833
+ className: "truncate text-left text-xs font-bold text-dark-blue-400 hover:text-sky-blue-400"
834
+ },
835
+ row.name
836
+ ),
837
+ /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs text-slate-500" }, row.description),
838
+ /* @__PURE__ */ React.createElement("div", { className: "text-center text-xs font-bold text-dark-blue-400" }, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")
839
+ )));
802
840
  }
803
841
 
842
+ const TABS$3 = [
843
+ { label: "My students", value: "students" },
844
+ { label: "Impact statements", value: "impact" },
845
+ { label: "Reflections", value: "reflections" },
846
+ { label: "Badges", value: "badges" },
847
+ { label: "Lessons", value: "lessons" }
848
+ ];
804
849
  const Dashboard = (props) => {
805
850
  const [tab, setTab] = useState("students");
806
- return /* @__PURE__ */ React.createElement(Container, { fluid: true, py: "xl" }, /* @__PURE__ */ React.createElement(Stack$5, null, /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0 }, /* @__PURE__ */ React.createElement(Title, { size: "h3" }, "Dashboard"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", size: "sm", mt: "md" }, "Track your students\u2019 pathway progress")), /* @__PURE__ */ React.createElement(Stack$5, null, /* @__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: [
851
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-5 px-4 py-8" }, /* @__PURE__ */ React.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React.createElement("h1", { className: "text-2xl font-extrabold tracking-tight text-dark-blue-400" }, "Dashboard"), /* @__PURE__ */ React.createElement("p", { className: "max-w-xl text-sm text-slate-500" }, "Track your students' pathway progress")), /* @__PURE__ */ React.createElement(StatsGroup, { data: [
807
852
  {
808
853
  title: "# OF STUDENTS",
809
854
  value: props.students.length
@@ -821,35 +866,24 @@ const Dashboard = (props) => {
821
866
  title: "LESSONS COMPLETED",
822
867
  value: props.numberOfLessonsCompleted
823
868
  }
824
- ] }), /* @__PURE__ */ React.createElement(
825
- Select,
869
+ ] }), /* @__PURE__ */ React.createElement("div", { className: "relative w-full max-w-xs" }, /* @__PURE__ */ React.createElement(IconCategory2, { size: 16, stroke: 2, className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" }), /* @__PURE__ */ React.createElement(
870
+ "select",
826
871
  {
827
- clearable: true,
828
- clearButtonLabel: "Clear class selection",
829
- size: "sm",
830
- placeholder: "Select a class",
831
- nothingFound: "No options",
832
872
  value: props.classId,
833
- onChange: props.onClassChange,
834
- icon: /* @__PURE__ */ React.createElement(IconCategory2, null),
835
- data: props.classes.map((g) => {
836
- return { value: g.classId, label: g.name };
837
- })
838
- }
839
- ), /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0 }, /* @__PURE__ */ React.createElement(
840
- Tabs,
873
+ onChange: (e) => props.onClassChange(e.target.value),
874
+ className: "w-full appearance-none rounded-lg border border-slate-200 bg-white py-2 pl-9 pr-4 text-sm text-dark-blue-400 focus:border-sky-blue-400 focus:outline-none"
875
+ },
876
+ /* @__PURE__ */ React.createElement("option", { value: "" }, "All classes"),
877
+ props.classes.map((c) => /* @__PURE__ */ React.createElement("option", { key: c.classId, value: c.classId }, c.name))
878
+ )), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex w-fit flex-wrap gap-1 rounded-xl border border-slate-200 bg-white p-1" }, TABS$3.map((t) => /* @__PURE__ */ React.createElement(
879
+ "button",
841
880
  {
842
- value: tab,
843
- data: [
844
- { label: "My students", value: "students" },
845
- { label: "Impact statements", value: "impact" },
846
- { label: "Reflections", value: "reflections" },
847
- { label: "Badges", value: "badges" },
848
- { label: "Lessons", value: "lessons" }
849
- ],
850
- onChange: setTab
851
- }
852
- ), tab === "impact" && /* @__PURE__ */ React.createElement(
881
+ key: t.value,
882
+ onClick: () => setTab(t.value),
883
+ 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"}`
884
+ },
885
+ t.label
886
+ ))), tab === "impact" && /* @__PURE__ */ React.createElement(
853
887
  Table$f,
854
888
  {
855
889
  loading: props.loading,
@@ -882,12 +916,12 @@ const Dashboard = (props) => {
882
916
  items: props.students,
883
917
  onViewProfile: props.onViewStudentProfile
884
918
  }
885
- )))))));
919
+ )));
886
920
  };
887
921
 
888
922
  var __defProp$d = Object.defineProperty;
889
- var __defProps$9 = Object.defineProperties;
890
- var __getOwnPropDescs$9 = Object.getOwnPropertyDescriptors;
923
+ var __defProps$a = Object.defineProperties;
924
+ var __getOwnPropDescs$a = Object.getOwnPropertyDescriptors;
891
925
  var __getOwnPropSymbols$d = Object.getOwnPropertySymbols;
892
926
  var __hasOwnProp$d = Object.prototype.hasOwnProperty;
893
927
  var __propIsEnum$d = Object.prototype.propertyIsEnumerable;
@@ -903,8 +937,8 @@ var __spreadValues$d = (a, b) => {
903
937
  }
904
938
  return a;
905
939
  };
906
- var __spreadProps$9 = (a, b) => __defProps$9(a, __getOwnPropDescs$9(b));
907
- const openDeleteModal = (student, onDelete) => openConfirmModal({
940
+ var __spreadProps$a = (a, b) => __defProps$a(a, __getOwnPropDescs$a(b));
941
+ const openDeleteModal$2 = (student, onDelete) => openConfirmModal({
908
942
  title: `Remove "${student.givenName && student.familyName ? `${student.givenName} ${student.familyName}` : student.email}" from this class?`,
909
943
  centered: true,
910
944
  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."),
@@ -914,7 +948,7 @@ const openDeleteModal = (student, onDelete) => openConfirmModal({
914
948
  });
915
949
  function Table$c(props) {
916
950
  const preparedItems = React.useMemo(() => {
917
- return props.items.map((item) => __spreadProps$9(__spreadValues$d({}, item), {
951
+ return props.items.map((item) => __spreadProps$a(__spreadValues$d({}, item), {
918
952
  fullName: item.givenName && item.familyName ? `${item.givenName} ${item.familyName}`.toLowerCase() : item.email.toLowerCase()
919
953
  }));
920
954
  }, [props.items]);
@@ -956,7 +990,7 @@ function Table$c(props) {
956
990
  "button",
957
991
  {
958
992
  type: "button",
959
- onClick: () => openDeleteModal(row, props.onDelete),
993
+ onClick: () => openDeleteModal$2(row, props.onDelete),
960
994
  className: "flex h-7 w-7 items-center justify-center rounded-md text-slate-400 hover:bg-red-50 hover:text-red-500"
961
995
  },
962
996
  /* @__PURE__ */ React.createElement(IconTrash, { size: 14, stroke: 1.75 })
@@ -966,8 +1000,8 @@ function Table$c(props) {
966
1000
  }
967
1001
 
968
1002
  var __defProp$c = Object.defineProperty;
969
- var __defProps$8 = Object.defineProperties;
970
- var __getOwnPropDescs$8 = Object.getOwnPropertyDescriptors;
1003
+ var __defProps$9 = Object.defineProperties;
1004
+ var __getOwnPropDescs$9 = Object.getOwnPropertyDescriptors;
971
1005
  var __getOwnPropSymbols$c = Object.getOwnPropertySymbols;
972
1006
  var __hasOwnProp$c = Object.prototype.hasOwnProperty;
973
1007
  var __propIsEnum$c = Object.prototype.propertyIsEnumerable;
@@ -983,7 +1017,7 @@ var __spreadValues$c = (a, b) => {
983
1017
  }
984
1018
  return a;
985
1019
  };
986
- var __spreadProps$8 = (a, b) => __defProps$8(a, __getOwnPropDescs$8(b));
1020
+ var __spreadProps$9 = (a, b) => __defProps$9(a, __getOwnPropDescs$9(b));
987
1021
  const Class = (props) => {
988
1022
  const [opened, setOpened] = useState(false);
989
1023
  return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
@@ -995,7 +1029,7 @@ const Class = (props) => {
995
1029
  padding: "xl",
996
1030
  size: "xl"
997
1031
  },
998
- /* @__PURE__ */ React.createElement(DropzoneButton$1, __spreadProps$8(__spreadValues$c({}, props), { close: () => setOpened(false) }))
1032
+ /* @__PURE__ */ React.createElement(DropzoneButton$1, __spreadProps$9(__spreadValues$c({}, props), { close: () => setOpened(false) }))
999
1033
  ), /* @__PURE__ */ React.createElement("div", { className: "flex 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(
1000
1034
  "button",
1001
1035
  {
@@ -1148,6 +1182,14 @@ const DropzoneButton$1 = (props) => {
1148
1182
  ))));
1149
1183
  };
1150
1184
 
1185
+ const openDeleteModal$1 = (group, onDeleteClass) => openConfirmModal({
1186
+ title: `Delete "${group.name}"?`,
1187
+ centered: true,
1188
+ children: /* @__PURE__ */ React.createElement(Text, { size: "sm" }, "Are you sure you want to delete this class? This action is destructive and you will have to contact support to restore your data."),
1189
+ labels: { confirm: "Delete class", cancel: "No don't delete it" },
1190
+ confirmProps: { color: "red" },
1191
+ onConfirm: () => onDeleteClass(group)
1192
+ });
1151
1193
  function Table$b(props) {
1152
1194
  const { items: sortedItems, requestSort, sortConfig } = useSortableData(props.items);
1153
1195
  if (props.items.length === 0) {
@@ -1161,57 +1203,26 @@ function Table$b(props) {
1161
1203
  }
1162
1204
  );
1163
1205
  }
1164
- const openDeleteModal = (group) => openConfirmModal({
1165
- title: `Delete "${group.name}"?`,
1166
- centered: true,
1167
- children: /* @__PURE__ */ React.createElement(Text, { size: "sm" }, "Are you sure you want to delete this class? This action is destructive and you will have to contact support to restore your data."),
1168
- labels: { confirm: "Delete class", cancel: "No don't delete it" },
1169
- confirmProps: { color: "red" },
1170
- onConfirm: () => props.onDeleteClass(group)
1171
- });
1172
- const sortStatus = {
1173
- columnAccessor: sortConfig.key,
1174
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
1175
- };
1176
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(
1177
- DataTable,
1178
- {
1179
- withBorder: false,
1180
- borderRadius: "sm",
1181
- verticalSpacing: "sm",
1182
- sx: { minWidth: 700 },
1183
- highlightOnHover: true,
1184
- striped: true,
1185
- records: sortedItems,
1186
- idAccessor: "classId",
1187
- sortStatus,
1188
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
1189
- columns: [
1190
- {
1191
- accessor: "name",
1192
- title: "Class Name",
1193
- sortable: true,
1194
- render: (row) => /* @__PURE__ */ React.createElement(UnstyledButton, { component: Link, to: row.href }, /* @__PURE__ */ React.createElement(Text, { size: 14, weight: 500 }, row.name))
1195
- },
1196
- {
1197
- accessor: "description",
1198
- title: "Description",
1199
- render: (row) => /* @__PURE__ */ React.createElement(Text, { size: 14 }, row.description)
1200
- },
1201
- {
1202
- accessor: "numberOfStudents",
1203
- title: "# of Students",
1204
- sortable: true,
1205
- render: (row) => /* @__PURE__ */ React.createElement(Text, { size: 14 }, row.numberOfStudents || 0)
1206
- },
1207
- {
1208
- accessor: "actions",
1209
- title: "",
1210
- render: (row) => /* @__PURE__ */ React.createElement(Group, { noWrap: true, spacing: 0, position: "right" }, /* @__PURE__ */ React.createElement(ActionIcon, { color: "red", onClick: () => openDeleteModal(row) }, /* @__PURE__ */ React.createElement(IconTrash, { size: 16, stroke: 1.5 })))
1211
- }
1212
- ]
1213
- }
1214
- ));
1206
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
1207
+ 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-[1.5fr_2fr_1fr_0.6fr] gap-3 border-b border-slate-100 px-5 py-3 text-[10px] font-bold uppercase tracking-wide text-slate-500" }, /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("name"), className: "flex items-center text-left hover:text-slate-700" }, "Class Name", indicator("name")), /* @__PURE__ */ React.createElement("div", null, "Description"), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("numberOfStudents"), className: "flex items-center justify-center text-center hover:text-slate-700" }, "# of Students", indicator("numberOfStudents")), /* @__PURE__ */ React.createElement("div", null)), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
1208
+ "div",
1209
+ {
1210
+ key: row.classId,
1211
+ className: `grid grid-cols-[1.5fr_2fr_1fr_0.6fr] items-center gap-3 px-5 py-3.5 ${i < sortedItems.length - 1 ? "border-b border-slate-100" : ""}`
1212
+ },
1213
+ row.href ? /* @__PURE__ */ React.createElement(Link, { to: row.href, className: "truncate text-xs font-bold text-dark-blue-400 no-underline hover:text-sky-blue-400" }, row.name) : /* @__PURE__ */ React.createElement("span", { className: "truncate text-xs font-bold text-dark-blue-400" }, row.name),
1214
+ /* @__PURE__ */ React.createElement("div", { className: "truncate text-xs text-slate-500" }, row.description),
1215
+ /* @__PURE__ */ React.createElement("div", { className: "text-center text-xs font-bold text-dark-blue-400" }, row.numberOfStudents || 0),
1216
+ /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
1217
+ "button",
1218
+ {
1219
+ type: "button",
1220
+ onClick: () => openDeleteModal$1(row, props.onDeleteClass),
1221
+ className: "flex h-7 w-7 items-center justify-center rounded-md text-slate-400 hover:bg-red-50 hover:text-red-500"
1222
+ },
1223
+ /* @__PURE__ */ React.createElement(IconTrash, { size: 14, stroke: 1.75 })
1224
+ ))
1225
+ )));
1215
1226
  }
1216
1227
 
1217
1228
  var __defProp$b = Object.defineProperty;
@@ -1230,20 +1241,7 @@ var __spreadValues$b = (a, b) => {
1230
1241
  }
1231
1242
  return a;
1232
1243
  };
1233
- const useStyles$f = createStyles((theme) => ({
1234
- title: {
1235
- fontSize: 34,
1236
- fontWeight: 900,
1237
- [theme.fn.smallerThan("sm")]: {
1238
- fontSize: 24
1239
- }
1240
- },
1241
- description: {
1242
- maxWidth: 600
1243
- }
1244
- }));
1245
1244
  const Classes = (props) => {
1246
- const { classes } = useStyles$f();
1247
1245
  const form = useForm({
1248
1246
  initialValues: {
1249
1247
  classId: "",
@@ -1271,7 +1269,7 @@ const Classes = (props) => {
1271
1269
  form.reset();
1272
1270
  setOpened(false);
1273
1271
  props.onCreateClass && props.onCreateClass(values);
1274
- }) }, /* @__PURE__ */ React.createElement(Stack$5, null, /* @__PURE__ */ React.createElement(
1272
+ }) }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement(
1275
1273
  TextInput,
1276
1274
  __spreadValues$b({
1277
1275
  withAsterisk: true,
@@ -1284,34 +1282,44 @@ const Classes = (props) => {
1284
1282
  label: "Description",
1285
1283
  placeholder: "A class for my first period English students"
1286
1284
  }, form.getInputProps("description"))
1287
- )), /* @__PURE__ */ React.createElement(Button, { type: "submit", fullWidth: true, mt: "md" }, "Submit"))
1288
- ), /* @__PURE__ */ React.createElement(Container, { fluid: true, 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" }, "Classes"), /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, "Organize people into classes"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Create classes, cohorts, or custom subgroups")), /* @__PURE__ */ React.createElement(Grid.Col, { sm: "content" }, !props.loading && /* @__PURE__ */ React.createElement(
1289
- Button,
1285
+ ), /* @__PURE__ */ React.createElement(
1286
+ "button",
1287
+ {
1288
+ type: "submit",
1289
+ className: "mt-2 rounded-lg bg-dark-blue-400 px-4 py-2.5 text-xs font-bold text-white"
1290
+ },
1291
+ "Submit"
1292
+ )))
1293
+ ), /* @__PURE__ */ React.createElement("div", { className: "flex 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("h1", { className: "text-2xl font-extrabold tracking-tight text-dark-blue-400" }, "Organize people into classes"), /* @__PURE__ */ React.createElement("p", { className: "max-w-xl text-sm text-slate-500" }, "Create classes, cohorts, or custom subgroups")), !props.loading && /* @__PURE__ */ React.createElement(
1294
+ "button",
1290
1295
  {
1296
+ type: "button",
1291
1297
  onClick: () => setOpened(true),
1292
- leftIcon: /* @__PURE__ */ React.createElement(IconPlaylistAdd, { size: 14 })
1298
+ 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)]"
1293
1299
  },
1300
+ /* @__PURE__ */ React.createElement(IconPlaylistAdd, { size: 13, stroke: 2 }),
1294
1301
  "Create class"
1295
- ))), /* @__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: [
1302
+ )), /* @__PURE__ */ React.createElement(StatsGroup, { data: [
1296
1303
  {
1297
1304
  title: "# OF CLASSES",
1298
1305
  value: props.classes.length
1299
1306
  }
1300
- ] }), /* @__PURE__ */ React.createElement(
1301
- Autocomplete,
1307
+ ] }), /* @__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(
1308
+ "input",
1302
1309
  {
1310
+ type: "text",
1303
1311
  placeholder: "Search for classes",
1304
- data: props.classes.map((item) => item.name),
1305
- onChange: props.onAutocompleteChange
1312
+ onChange: (e) => props.onAutocompleteChange(e.target.value),
1313
+ 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"
1306
1314
  }
1307
- ), /* @__PURE__ */ React.createElement(
1315
+ )), /* @__PURE__ */ React.createElement(
1308
1316
  Table$b,
1309
1317
  {
1310
1318
  loading: props.loading,
1311
1319
  items: props.classes,
1312
1320
  onDeleteClass: props.onDeleteClass
1313
1321
  }
1314
- ))))));
1322
+ )));
1315
1323
  };
1316
1324
 
1317
1325
  function Table$a(props) {
@@ -1394,7 +1402,7 @@ function Table$8(props) {
1394
1402
  )));
1395
1403
  }
1396
1404
 
1397
- const TABS$1 = [
1405
+ const TABS$2 = [
1398
1406
  { label: "My badges", value: "badges" },
1399
1407
  { label: "My answers", value: "answers" },
1400
1408
  { label: "My reflections", value: "reflections" }
@@ -1416,7 +1424,7 @@ const Student = (props) => {
1416
1424
  title: "BADGE COMPLETION",
1417
1425
  value: numberOfBadgesCompleted
1418
1426
  }
1419
- ] }), /* @__PURE__ */ React.createElement("div", { className: "flex w-fit gap-1 rounded-xl border border-slate-200 bg-white p-1" }, TABS$1.map((t) => /* @__PURE__ */ React.createElement(
1427
+ ] }), /* @__PURE__ */ React.createElement("div", { className: "flex w-fit gap-1 rounded-xl border border-slate-200 bg-white p-1" }, TABS$2.map((t) => /* @__PURE__ */ React.createElement(
1420
1428
  "button",
1421
1429
  {
1422
1430
  key: t.value,
@@ -1534,65 +1542,35 @@ function Table$7(props) {
1534
1542
  }
1535
1543
  );
1536
1544
  }
1537
- const sortStatus = {
1538
- columnAccessor: sortConfig.key,
1539
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
1540
- };
1541
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(
1542
- DataTable,
1543
- {
1544
- records: sortedItems,
1545
- sortStatus,
1546
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
1547
- columns: [
1548
- { accessor: "studentName", title: "Student Name", sortable: true },
1549
- { accessor: "reflection", title: "Reflection" },
1550
- { accessor: "rating", title: "Rating", sortable: true }
1551
- ]
1552
- }
1553
- ));
1545
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
1546
+ 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("button", { onClick: () => requestSort("studentName"), className: "w-40 shrink-0 text-left hover:text-slate-600" }, "Student Name", indicator("studentName")), /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, "Reflection"), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("rating"), className: "w-20 shrink-0 text-right hover:text-slate-600" }, "Rating", indicator("rating"))), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement("div", { key: `${row.studentName}-${i}`, className: "rounded-xl border border-slate-200 bg-white p-4 shadow-sm" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-start gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "w-40 shrink-0 text-sm font-bold text-dark-blue-400" }, row.studentName), /* @__PURE__ */ React.createElement("div", { className: "flex-1 text-sm text-slate-600" }, row.reflection), /* @__PURE__ */ React.createElement("div", { className: "w-20 shrink-0 text-right text-sm text-slate-500" }, row.rating)))));
1554
1547
  }
1555
1548
 
1556
- const useStyles$e = createStyles((theme) => ({
1557
- button: {
1558
- borderTopRightRadius: 0,
1559
- borderBottomRightRadius: 0,
1560
- marginLeft: 0,
1561
- marginRight: 0
1562
- },
1563
- menuControl: {
1564
- borderTopLeftRadius: 0,
1565
- borderBottomLeftRadius: 0,
1566
- border: 0,
1567
- borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
1568
- }
1569
- }));
1570
1549
  const SplitButton$3 = (props) => {
1571
- const { classes, theme } = useStyles$e();
1572
- theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
1573
- return /* @__PURE__ */ React.createElement(Stack$5, { spacing: "sm" }, /* @__PURE__ */ React.createElement(
1574
- Button,
1550
+ return /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement(
1551
+ Link,
1575
1552
  {
1576
- component: Link,
1577
1553
  to: props.href,
1578
- className: classes.button,
1579
- variant: "gradient"
1554
+ 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 no-underline hover:bg-slate-50"
1580
1555
  },
1581
1556
  "Preview"
1582
1557
  ), /* @__PURE__ */ React.createElement(
1583
- Button,
1558
+ "button",
1584
1559
  {
1585
- variant: "gradient",
1586
- leftIcon: /* @__PURE__ */ React.createElement(IconClipboardCopy, { size: 14 }),
1587
- onClick: props.onCopyLinkClick
1560
+ type: "button",
1561
+ onClick: props.onCopyLinkClick,
1562
+ 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"
1588
1563
  },
1564
+ /* @__PURE__ */ React.createElement(IconClipboardCopy, { size: 13, stroke: 2 }),
1589
1565
  "Copy link"
1590
1566
  ), /* @__PURE__ */ React.createElement(
1591
- Button,
1567
+ "button",
1592
1568
  {
1593
- leftIcon: /* @__PURE__ */ React.createElement(IconTableExport, { size: 14 }),
1594
- onClick: props.onExportDataClick
1569
+ type: "button",
1570
+ onClick: props.onExportDataClick,
1571
+ 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)]"
1595
1572
  },
1573
+ /* @__PURE__ */ React.createElement(IconTableExport, { size: 13, stroke: 2 }),
1596
1574
  "Export data (.csv)"
1597
1575
  ));
1598
1576
  };
@@ -1601,13 +1579,12 @@ function Stack$3(props) {
1601
1579
  if (props.items.length === 0) {
1602
1580
  return null;
1603
1581
  }
1604
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0, key: row.questionName }, /* @__PURE__ */ React.createElement(Title, { color: "dark.4", size: "lg" }, row.questionName), /* @__PURE__ */ React.createElement(Text, null, row.answer.join(",") || "No answer.")));
1605
- 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)));
1582
+ return /* @__PURE__ */ React.createElement(Link, { to: props.href, className: "flex flex-col gap-4 no-underline" }, props.items.map((row) => /* @__PURE__ */ React.createElement("div", { key: row.questionName }, /* @__PURE__ */ React.createElement("div", { className: "text-sm font-bold text-dark-blue-400" }, row.questionName), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-sm text-slate-600" }, row.answer.join(", ") || "No answer."))));
1606
1583
  }
1607
1584
 
1608
1585
  var __defProp$a = Object.defineProperty;
1609
- var __defProps$7 = Object.defineProperties;
1610
- var __getOwnPropDescs$7 = Object.getOwnPropertyDescriptors;
1586
+ var __defProps$8 = Object.defineProperties;
1587
+ var __getOwnPropDescs$8 = Object.getOwnPropertyDescriptors;
1611
1588
  var __getOwnPropSymbols$a = Object.getOwnPropertySymbols;
1612
1589
  var __hasOwnProp$a = Object.prototype.hasOwnProperty;
1613
1590
  var __propIsEnum$a = Object.prototype.propertyIsEnumerable;
@@ -1623,18 +1600,15 @@ var __spreadValues$a = (a, b) => {
1623
1600
  }
1624
1601
  return a;
1625
1602
  };
1626
- var __spreadProps$7 = (a, b) => __defProps$7(a, __getOwnPropDescs$7(b));
1603
+ var __spreadProps$8 = (a, b) => __defProps$8(a, __getOwnPropDescs$8(b));
1627
1604
  function Table$6(props) {
1605
+ const [expanded, setExpanded] = React.useState({});
1628
1606
  const preparedItems = React.useMemo(() => {
1629
- return props.items.map((item) => __spreadProps$7(__spreadValues$a({}, item), {
1607
+ return props.items.map((item) => __spreadProps$8(__spreadValues$a({}, item), {
1630
1608
  status: item.isComplete ? 2 : item.isStarted ? 1 : 0
1631
1609
  }));
1632
1610
  }, [props.items]);
1633
1611
  const { items: sortedItems, requestSort, sortConfig } = useSortableData(preparedItems);
1634
- const sortStatus = {
1635
- columnAccessor: sortConfig.key,
1636
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
1637
- };
1638
1612
  if (props.items.length === 0) {
1639
1613
  return /* @__PURE__ */ React.createElement(
1640
1614
  PlaceholderBanner,
@@ -1646,36 +1620,22 @@ function Table$6(props) {
1646
1620
  }
1647
1621
  );
1648
1622
  }
1649
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(
1650
- DataTable,
1651
- {
1652
- verticalSpacing: "sm",
1653
- sx: { minWidth: 700 },
1654
- withBorder: false,
1655
- borderRadius: "sm",
1656
- withColumnBorders: true,
1657
- striped: true,
1658
- highlightOnHover: true,
1659
- idAccessor: "userId",
1660
- records: sortedItems,
1661
- sortStatus,
1662
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
1663
- columns: [{
1664
- accessor: "name",
1665
- title: "Student Name",
1666
- sortable: true,
1667
- render: (row) => /* @__PURE__ */ React.createElement(UnstyledButton, null, /* @__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))))
1668
- }, {
1669
- accessor: "status",
1670
- title: "Status",
1671
- sortable: true,
1672
- render: (row) => /* @__PURE__ */ React.createElement(React.Fragment, null, !!row.isComplete && /* @__PURE__ */ React.createElement(Badge$1, { variant: "filled" }, "Complete"), !row.isComplete && !row.isStarted && /* @__PURE__ */ React.createElement(Badge$1, { color: "red", variant: "filled" }, "Not started"), !row.isComplete && !!row.isStarted && /* @__PURE__ */ React.createElement(Badge$1, { color: "violet", variant: "filled" }, "In progress"))
1673
- }],
1674
- rowExpansion: {
1675
- content: ({ record }) => /* @__PURE__ */ React.createElement(Stack$3, { href: record.href, items: record.answers })
1676
- }
1677
- }
1678
- ));
1623
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
1624
+ 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("status"), className: "w-28 shrink-0 text-center hover:text-slate-600" }, "Status", indicator("status")), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), sortedItems.map((row) => {
1625
+ var _a;
1626
+ const isOpen = !!expanded[row.userId];
1627
+ const initials = (((_a = row.name) == null ? void 0 : _a[0]) || row.email[0] || "?").toUpperCase();
1628
+ return /* @__PURE__ */ React.createElement("div", { key: row.userId, className: "rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement(
1629
+ "div",
1630
+ {
1631
+ onClick: () => setExpanded(__spreadProps$8(__spreadValues$a({}, expanded), { [row.userId]: !isOpen })),
1632
+ className: "flex cursor-pointer items-center gap-4 p-4"
1633
+ },
1634
+ /* @__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-mint-400/20 text-xs font-bold text-dark-blue-400" }, initials), /* @__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))),
1635
+ /* @__PURE__ */ React.createElement("div", { className: "w-28 shrink-0 text-center" }, row.isComplete && /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-mint-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, "Complete"), !row.isComplete && !row.isStarted && /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[10px] font-bold text-slate-500" }, "Not started"), !row.isComplete && !!row.isStarted && /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-gold-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, "In progress")),
1636
+ /* @__PURE__ */ React.createElement(IconChevronDown, { size: 15, stroke: 2.3, className: `shrink-0 text-slate-400 transition-transform ${isOpen ? "rotate-180" : ""}` })
1637
+ ), isOpen && /* @__PURE__ */ React.createElement("div", { className: "border-t border-slate-100 px-4 py-3" }, /* @__PURE__ */ React.createElement(Stack$3, { href: row.href, items: row.answers })));
1638
+ }));
1679
1639
  }
1680
1640
 
1681
1641
  function Stack$2(props) {
@@ -1706,7 +1666,7 @@ function Stack$2(props) {
1706
1666
  }
1707
1667
  );
1708
1668
  }
1709
- const rows = props.items.map((row) => {
1669
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, props.items.map((row) => {
1710
1670
  if (row.chart) {
1711
1671
  const labelMap = {};
1712
1672
  const choices = row.choices || [];
@@ -1718,7 +1678,7 @@ function Stack$2(props) {
1718
1678
  labelMap[r] = labelMap[r] ? labelMap[r] + 1 : 1;
1719
1679
  }
1720
1680
  }));
1721
- return /* @__PURE__ */ React.createElement(Card, { key: row.question, withBorder: true, p: "xl", radius: "md" }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: 4 }, /* @__PURE__ */ React.createElement(Title, { size: "lg" }, row.question), /* @__PURE__ */ React.createElement(Text, { size: "sm" }, row.answers.length, " answers"), /* @__PURE__ */ React.createElement("div", { style: { background: "white", height: "300px", width: "100%", position: "relative" } }, /* @__PURE__ */ React.createElement(
1681
+ return /* @__PURE__ */ React.createElement("div", { key: row.question, className: "rounded-xl border border-slate-200 bg-white p-6 shadow-sm" }, /* @__PURE__ */ React.createElement("div", { className: "text-base font-extrabold text-dark-blue-400" }, row.question), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, row.answers.length, " answers"), /* @__PURE__ */ React.createElement("div", { className: "relative mt-4 h-[300px] w-full bg-white" }, /* @__PURE__ */ React.createElement(
1722
1682
  Chart,
1723
1683
  {
1724
1684
  options: {
@@ -1735,64 +1695,24 @@ function Stack$2(props) {
1735
1695
  secondaryAxes
1736
1696
  }
1737
1697
  }
1738
- ))));
1698
+ )));
1739
1699
  }
1740
- return /* @__PURE__ */ React.createElement(Card, { key: row.question, withBorder: true, p: "xl", radius: "md" }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: 4 }, /* @__PURE__ */ React.createElement(Title, { size: "lg" }, row.question), /* @__PURE__ */ React.createElement(Text, { size: "sm" }, row.answers.length, " answers"), /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(Stack$5, { spacing: 4 }, row.answers.map((a) => {
1700
+ return /* @__PURE__ */ React.createElement("div", { key: row.question, className: "rounded-xl border border-slate-200 bg-white p-6 shadow-sm" }, /* @__PURE__ */ React.createElement("div", { className: "text-base font-extrabold text-dark-blue-400" }, row.question), /* @__PURE__ */ React.createElement("div", { className: "mt-1 text-xs text-slate-500" }, row.answers.length, " answers"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-col gap-2" }, row.answers.map((a) => {
1741
1701
  const answerText = a.join("\n");
1742
- return /* @__PURE__ */ React.createElement(Card, { key: answerText, p: 5, radius: 0, bg: "gray.0" }, /* @__PURE__ */ React.createElement(Text, null, answerText));
1743
- })))));
1744
- });
1745
- return /* @__PURE__ */ React.createElement(Stack$5, { py: 4, spacing: 10, sx: { minWidth: 700 } }, rows);
1702
+ return /* @__PURE__ */ React.createElement("div", { key: answerText, className: "rounded-lg bg-slate-50 p-3 text-sm text-slate-700" }, answerText);
1703
+ })));
1704
+ }));
1746
1705
  }
1747
1706
  const truncateWithEllipses = (text, max) => text.substr(0, max - 1) + (text.length > max ? "&hellip;" : "");
1748
1707
 
1749
- const useStyles$d = createStyles((theme) => ({
1750
- title: {
1751
- fontSize: 34,
1752
- fontWeight: 900,
1753
- [theme.fn.smallerThan("sm")]: {
1754
- fontSize: 24
1755
- }
1756
- },
1757
- description: {
1758
- maxWidth: 600
1759
- }
1760
- }));
1708
+ const initialsFor = (name) => name.split(/[ -]/).map((n) => n.charAt(0)).join("").toUpperCase();
1761
1709
  const Lesson = (props) => {
1762
- const { classes } = useStyles$d();
1763
1710
  const [tab, setTab] = useState("question");
1764
1711
  const numberOfStudents = props.students.length;
1765
1712
  const numberOfLessons = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length : 0;
1766
- numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length / numberOfStudents : 0;
1767
1713
  const contributors = props.contributors || [];
1768
- const avatars = contributors.slice(0, 5).map((u, i) => {
1769
- const fullName = u.name;
1770
- let initials = fullName.split(/[ -]/).map((n) => n.charAt(0)).join("");
1771
- const src = AvatarInit.initialAvatar({
1772
- background: "#1c7ed6",
1773
- color: "#fff",
1774
- fontFamily: "'Lato', 'Lato-Regular', 'Helvetica Neue'",
1775
- fontSize: 10,
1776
- fontWeight: 250,
1777
- size: 30,
1778
- initials
1779
- });
1780
- return /* @__PURE__ */ React.createElement(Avatar, { key: i, src, radius: "xl" });
1781
- });
1782
- const remainingUsers = contributors.slice(5).length;
1783
- if (remainingUsers) {
1784
- const initials = "+" + compact(remainingUsers);
1785
- const src = AvatarInit.initialAvatar({
1786
- background: "#1c7ed6",
1787
- color: "#fff",
1788
- fontFamily: "'Lato', 'Lato-Regular', 'Helvetica Neue'",
1789
- fontSize: 10,
1790
- fontWeight: 250,
1791
- size: 30,
1792
- initials
1793
- });
1794
- avatars.push(/* @__PURE__ */ React.createElement(Avatar, { src, radius: "xl" }));
1795
- }
1714
+ const visibleContributors = contributors.slice(0, 5);
1715
+ const remainingContributors = contributors.slice(5).length;
1796
1716
  const tabs = props.trial ? [
1797
1717
  { label: "By question", value: "question" },
1798
1718
  { label: "By student", value: "students" }
@@ -1801,15 +1721,7 @@ const Lesson = (props) => {
1801
1721
  { label: "By student", value: "students" },
1802
1722
  { label: "By reflection", value: "reflections" }
1803
1723
  ];
1804
- return /* @__PURE__ */ React.createElement(Container, { fluid: true, 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(
1805
- Badge$1,
1806
- {
1807
- variant: "filled",
1808
- leftSection: /* @__PURE__ */ React.createElement(ActionIcon, { color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React.createElement(IconArrowLeft, { size: 14 })),
1809
- size: "lg"
1810
- },
1811
- "Back"
1812
- )), /* @__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 || "Lesson"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), /* @__PURE__ */ React.createElement(Stack$5, { ml: "auto" }, /* @__PURE__ */ React.createElement(
1724
+ return /* @__PURE__ */ React.createElement("div", { className: "flex 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 || "Lesson"), /* @__PURE__ */ React.createElement("p", { className: "max-w-xl text-sm text-slate-500" }, props.description || "No description")), /* @__PURE__ */ React.createElement(
1813
1725
  SplitButton$3,
1814
1726
  {
1815
1727
  href: props.href,
@@ -1817,58 +1729,36 @@ const Lesson = (props) => {
1817
1729
  onCopyLinkClick: props.onCopyLinkClick,
1818
1730
  onExportDataClick: props.onExportDataClick
1819
1731
  }
1820
- ))))), /* @__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(
1821
- StatsGroup,
1822
- {
1823
- data: [
1824
- {
1825
- title: props.trial ? "# OF SUBMISSIONS" : "LESSON COMPLETION",
1826
- value: props.trial ? props.lessonsCompleted || 0 : numberOfLessons,
1827
- unit: props.trial ? "" : ""
1828
- }
1829
- ]
1830
- }
1831
- ), /* @__PURE__ */ React.createElement(Group, { position: "apart" }, /* @__PURE__ */ React.createElement(Avatar.Group, { spacing: "sm" }, avatars)), !props.trial && /* @__PURE__ */ React.createElement(
1832
- Select,
1833
- {
1834
- clearable: true,
1835
- clearButtonLabel: "Clear class selection",
1836
- size: "sm",
1837
- placeholder: "Select a class",
1838
- nothingFound: "No options",
1839
- value: props.classId,
1840
- onChange: props.onClassChange,
1841
- icon: /* @__PURE__ */ React.createElement(IconCategory2, null),
1842
- data: props.classes.map((g) => {
1843
- return { value: g.classId, label: g.name };
1844
- })
1845
- }
1846
- ), /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0 }, /* @__PURE__ */ React.createElement(
1847
- Tabs,
1732
+ )), /* @__PURE__ */ React.createElement(StatsGroup, { data: [
1848
1733
  {
1849
- value: tab,
1850
- data: tabs,
1851
- onChange: setTab
1734
+ title: props.trial ? "# OF SUBMISSIONS" : "LESSON COMPLETION",
1735
+ value: props.trial ? props.lessonsCompleted || 0 : numberOfLessons
1852
1736
  }
1853
- ), tab === "question" && /* @__PURE__ */ React.createElement(
1854
- Stack$2,
1737
+ ] }), contributors.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "flex" }, visibleContributors.map((u, i) => /* @__PURE__ */ React.createElement(
1738
+ "div",
1855
1739
  {
1856
- loading: props.loading,
1857
- items: props.questions
1858
- }
1859
- ), tab === "reflections" && /* @__PURE__ */ React.createElement(
1860
- Table$7,
1740
+ key: i,
1741
+ className: "-ml-2 flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-2 border-white bg-mint-400/20 text-[10px] font-bold text-dark-blue-400 first:ml-0"
1742
+ },
1743
+ initialsFor(u.name)
1744
+ )), remainingContributors > 0 && /* @__PURE__ */ React.createElement("div", { className: "-ml-2 flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-2 border-white bg-slate-200 text-[10px] font-bold text-slate-600" }, "+", compact(remainingContributors))), !props.trial && /* @__PURE__ */ React.createElement("div", { className: "relative w-full max-w-xs" }, /* @__PURE__ */ React.createElement(IconCategory2, { size: 16, stroke: 2, className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" }), /* @__PURE__ */ React.createElement(
1745
+ "select",
1861
1746
  {
1862
- loading: props.loading,
1863
- items: props.reflections
1864
- }
1865
- ), tab === "students" && /* @__PURE__ */ React.createElement(
1866
- Table$6,
1747
+ value: props.classId,
1748
+ onChange: (e) => props.onClassChange(e.target.value),
1749
+ className: "w-full appearance-none rounded-lg border border-slate-200 bg-white py-2 pl-9 pr-4 text-sm text-dark-blue-400 focus:border-sky-blue-400 focus:outline-none"
1750
+ },
1751
+ /* @__PURE__ */ React.createElement("option", { value: "" }, "All classes"),
1752
+ props.classes.map((c) => /* @__PURE__ */ React.createElement("option", { key: c.classId, value: c.classId }, c.name))
1753
+ )), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__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(
1754
+ "button",
1867
1755
  {
1868
- loading: props.loading,
1869
- items: props.students
1870
- }
1871
- )))))));
1756
+ key: t.value,
1757
+ onClick: () => setTab(t.value),
1758
+ 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"}`
1759
+ },
1760
+ t.label
1761
+ ))), tab === "question" && /* @__PURE__ */ React.createElement(Stack$2, { loading: props.loading, items: props.questions }), tab === "reflections" && /* @__PURE__ */ React.createElement(Table$7, { loading: props.loading, items: props.reflections }), tab === "students" && /* @__PURE__ */ React.createElement(Table$6, { loading: props.loading, items: props.students })));
1872
1762
  };
1873
1763
 
1874
1764
  function Table$5(props) {
@@ -1878,7 +1768,7 @@ function Table$5(props) {
1878
1768
  if (props.items.length === 0) {
1879
1769
  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.");
1880
1770
  }
1881
- 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(
1771
+ 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" }, "Badge"), /* @__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(
1882
1772
  Link,
1883
1773
  {
1884
1774
  key: row.lessonId,
@@ -1886,13 +1776,14 @@ function Table$5(props) {
1886
1776
  className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
1887
1777
  },
1888
1778
  /* @__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)),
1779
+ /* @__PURE__ */ React.createElement("div", { className: "w-40 shrink-0 text-xs text-slate-500" }, row.badge || "\u2014"),
1889
1780
  /* @__PURE__ */ React.createElement("div", { className: "w-40 shrink-0 text-xs text-slate-500" }, row.pathway || "\u2014"),
1890
1781
  /* @__PURE__ */ React.createElement(IconChevronRight, { size: 16, stroke: 2, className: "w-4 shrink-0 text-slate-300" })
1891
1782
  )));
1892
1783
  }
1893
1784
 
1894
1785
  const Lessons = (props) => {
1895
- return /* @__PURE__ */ React.createElement("div", { className: "flex 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(
1786
+ return /* @__PURE__ */ React.createElement("div", { className: "flex 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(PathwayFilterPills, { pathways: props.pathways, selected: props.selectedPathway, onChange: props.onPathwayChange }), /* @__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(
1896
1787
  "input",
1897
1788
  {
1898
1789
  type: "text",
@@ -1903,37 +1794,23 @@ const Lessons = (props) => {
1903
1794
  )), /* @__PURE__ */ React.createElement(Table$5, { loading: props.loading, items: props.lessons }));
1904
1795
  };
1905
1796
 
1906
- const useStyles$c = createStyles((theme) => ({
1907
- title: {
1908
- fontSize: 22,
1909
- fontWeight: 900,
1910
- fontFamily: `Greycliff CF, ${theme.fontFamily}`
1911
- },
1912
- controls: {
1913
- [theme.fn.smallerThan("xs")]: {
1914
- flexDirection: "column-reverse"
1915
- }
1916
- },
1917
- control: {
1918
- [theme.fn.smallerThan("xs")]: {
1919
- width: "100%",
1920
- textAlign: "center"
1921
- }
1922
- }
1923
- }));
1924
1797
  function AccessCode(props) {
1925
- const { classes } = useStyles$c();
1926
- 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(
1927
- Anchor,
1928
- {
1929
- component: Link,
1930
- to: props.peopleLink,
1931
- color: "dimmed",
1932
- size: "sm",
1933
- className: classes.control
1798
+ return /* @__PURE__ */ React.createElement("div", { className: "max-w-[460px]" }, /* @__PURE__ */ React.createElement("h2", { className: "text-lg font-extrabold text-dark-blue-400" }, "Access code"), /* @__PURE__ */ React.createElement("p", { className: "text-sm text-slate-500" }, "Grant access to join your organization"), /* @__PURE__ */ React.createElement("div", { className: "mt-4 rounded-xl border border-slate-200 bg-white p-6 shadow-sm" }, /* @__PURE__ */ React.createElement(
1799
+ "input",
1800
+ {
1801
+ value: props.value,
1802
+ readOnly: true,
1803
+ className: "w-full rounded-lg border border-slate-200 bg-slate-50 px-3 py-2 text-sm text-dark-blue-400"
1804
+ }
1805
+ ), /* @__PURE__ */ React.createElement("div", { className: "mt-4 flex flex-wrap items-center justify-between gap-3" }, /* @__PURE__ */ React.createElement(Link, { to: props.peopleLink, className: "flex items-center gap-1.5 text-xs font-bold text-slate-500 no-underline hover:text-slate-700" }, /* @__PURE__ */ React.createElement(IconPointer, { size: 12, stroke: 1.5 }), "See people in my organization"), /* @__PURE__ */ React.createElement(
1806
+ "button",
1807
+ {
1808
+ type: "button",
1809
+ onClick: props.onCopyCode,
1810
+ className: "rounded-lg bg-gradient-to-r from-gold-400 to-[#f5c300] px-4 py-2 text-xs font-bold text-dark-blue-400 shadow-[0_3px_12px_rgba(255,212,77,0.35)]"
1934
1811
  },
1935
- /* @__PURE__ */ React.createElement(Center, { inline: true }, /* @__PURE__ */ React.createElement(IconPointer, { size: 12, stroke: 1.5 }), /* @__PURE__ */ React.createElement(Box, { ml: 5 }, "See people in my organization"))
1936
- ), /* @__PURE__ */ React.createElement(Button, { onClick: props.onCopyCode, className: classes.control }, "Copy code"))));
1812
+ "Copy code"
1813
+ ))));
1937
1814
  }
1938
1815
 
1939
1816
  const monthNames = [
@@ -1950,46 +1827,8 @@ const monthNames = [
1950
1827
  "November",
1951
1828
  "December"
1952
1829
  ];
1953
- const useStyles$b = createStyles((theme) => ({
1954
- title: {
1955
- fontSize: 34,
1956
- fontWeight: 900,
1957
- [theme.fn.smallerThan("sm")]: {
1958
- fontSize: 24
1959
- }
1960
- },
1961
- description: {
1962
- maxWidth: 600
1963
- },
1964
- wrapper: {
1965
- position: "relative",
1966
- marginBottom: 30
1967
- },
1968
- dropzone: {
1969
- borderWidth: 1,
1970
- paddingBottom: 50
1971
- },
1972
- icon: {
1973
- color: theme.colorScheme === "dark" ? theme.colors.dark[3] : theme.colors.gray[4]
1974
- },
1975
- control: {
1976
- position: "absolute",
1977
- width: 250,
1978
- left: "calc(50% - 125px)",
1979
- bottom: -20
1980
- }
1981
- }));
1982
1830
  const Organization = (props) => {
1983
- const { classes } = useStyles$b();
1984
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Container, { fluid: true, 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(
1985
- Badge$1,
1986
- {
1987
- variant: "filled",
1988
- leftSection: /* @__PURE__ */ React.createElement(ActionIcon, { color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React.createElement(IconArrowLeft, { size: 14 })),
1989
- size: "lg"
1990
- },
1991
- "Back"
1992
- )), /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "Overview"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description"))), /* @__PURE__ */ React.createElement(AccessCode, { value: props.accessCode, onCopyCode: props.onCopyAccessCode, peopleLink: props.peopleLink }), /* @__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: [
1831
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-5 px-4 py-8" }, /* @__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 || "Overview"), /* @__PURE__ */ React.createElement("p", { className: "max-w-xl text-sm text-slate-500" }, props.description || "No description")), /* @__PURE__ */ React.createElement(AccessCode, { value: props.accessCode, onCopyCode: props.onCopyAccessCode, peopleLink: props.peopleLink }), /* @__PURE__ */ React.createElement(StatsGroup, { data: [
1993
1832
  {
1994
1833
  title: "# OF STUDENTS",
1995
1834
  value: props.numberOfStudents || 0
@@ -1999,59 +1838,47 @@ const Organization = (props) => {
1999
1838
  value: props.numberOfEducators || 0
2000
1839
  },
2001
1840
  {
2002
- title: `ACTIVE USERS (${monthNames[new Date().getMonth()]})`,
2003
- value: props.percentageOfAccountsActive,
2004
- unit: "%"
2005
- }
2006
- ] }))))));
2007
- };
2008
-
2009
- const useStyles$a = createStyles((theme) => ({
2010
- button: {
2011
- borderTopRightRadius: 0,
2012
- borderBottomRightRadius: 0,
2013
- marginLeft: 0,
2014
- marginRight: 0
2015
- },
2016
- menuControl: {
2017
- borderTopLeftRadius: 0,
2018
- borderBottomLeftRadius: 0,
2019
- border: 0,
2020
- borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
2021
- }
2022
- }));
1841
+ title: `ACTIVE USERS (${monthNames[new Date().getMonth()]})`,
1842
+ value: props.percentageOfAccountsActive,
1843
+ unit: "%"
1844
+ }
1845
+ ] }));
1846
+ };
1847
+
2023
1848
  const SplitButton$2 = (props) => {
2024
- const { classes, theme } = useStyles$a();
2025
- const menuIconColor = theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
2026
- const hasMenu = !!props.withOrganizationLink;
2027
- return /* @__PURE__ */ React.createElement(Group, { noWrap: true, spacing: 0 }, /* @__PURE__ */ React.createElement(
2028
- Button,
1849
+ return /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement(
1850
+ "button",
2029
1851
  {
2030
- className: hasMenu ? classes.button : "",
2031
- leftIcon: /* @__PURE__ */ React.createElement(IconPlaylistAdd, { size: 14 }),
2032
- onClick: props.onAddUsersClick
1852
+ type: "button",
1853
+ onClick: props.onAddUsersClick,
1854
+ 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)]"
2033
1855
  },
1856
+ /* @__PURE__ */ React.createElement(IconPlaylistAdd, { size: 13, stroke: 2 }),
2034
1857
  "Add members"
2035
- ), hasMenu && /* @__PURE__ */ React.createElement(Menu, { transition: "pop", position: "bottom-end" }, /* @__PURE__ */ React.createElement(Menu.Target, null, /* @__PURE__ */ React.createElement(
2036
- ActionIcon,
2037
- {
2038
- variant: "filled",
2039
- color: theme.primaryColor,
2040
- size: 36,
2041
- className: classes.menuControl
2042
- },
2043
- /* @__PURE__ */ React.createElement(IconChevronDown, { size: 16, stroke: 1.5 })
2044
- )), /* @__PURE__ */ React.createElement(Menu.Dropdown, null, !!props.withOrganizationLink && /* @__PURE__ */ React.createElement(
2045
- Menu.Item,
1858
+ ), props.withOrganizationLink && /* @__PURE__ */ React.createElement(
1859
+ "button",
2046
1860
  {
2047
- icon: /* @__PURE__ */ React.createElement(IconClipboardCopy, { size: 16, stroke: 1.5, color: menuIconColor }),
2048
- onClick: props.onCopyOrganizationLinkClick
1861
+ type: "button",
1862
+ onClick: props.onCopyOrganizationLinkClick,
1863
+ 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"
2049
1864
  },
1865
+ /* @__PURE__ */ React.createElement(IconClipboardCopy, { size: 13, stroke: 2 }),
2050
1866
  "Copy organization link"
2051
- ))));
1867
+ ));
2052
1868
  };
2053
1869
 
1870
+ const openDeleteModal = (person, onDelete) => openConfirmModal({
1871
+ title: `Remove "${person.givenName && person.familyName ? `${person.givenName} ${person.familyName}` : person.email}" from your organization?`,
1872
+ centered: true,
1873
+ children: /* @__PURE__ */ React.createElement(Text, { size: "sm" }, "Click confirm if you want to remove this person from your organization. This will NOT remove them from the Tech Platform."),
1874
+ labels: { confirm: "Remove", cancel: "Cancel" },
1875
+ confirmProps: { color: "red" },
1876
+ onConfirm: () => onDelete(person)
1877
+ });
2054
1878
  function Table$4(props) {
1879
+ if (props.loading) {
1880
+ return /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Loading\u2026");
1881
+ }
2055
1882
  if (props.items.length === 0) {
2056
1883
  return /* @__PURE__ */ React.createElement(
2057
1884
  PlaceholderBanner,
@@ -2063,29 +1890,48 @@ function Table$4(props) {
2063
1890
  }
2064
1891
  );
2065
1892
  }
2066
- const openDeleteModal = (student) => openConfirmModal({
2067
- title: `Remove "${student.givenName && student.familyName ? `${student.givenName} ${student.familyName}` : student.email}" from this class?`,
2068
- centered: true,
2069
- 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."),
2070
- labels: { confirm: "Remove Student", cancel: "Cancel" },
2071
- confirmProps: { color: "red" },
2072
- onConfirm: () => props.onDelete && props.onDelete(student)
2073
- });
2074
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement("tr", { key: row.email }, /* @__PURE__ */ React.createElement("td", null, /* @__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))))), /* @__PURE__ */ React.createElement("td", null, /* @__PURE__ */ React.createElement(Box, { maw: 150 }, /* @__PURE__ */ React.createElement(
2075
- Select,
2076
- {
2077
- size: "sm",
2078
- value: row.isAdmin ? "admin" : row.isGroupAdmin ? "educator" : "student",
2079
- onChange: (value) => props.onRoleChange && props.onRoleChange(row, value),
2080
- data: [{ value: "student", label: "Student" }, { value: "educator", label: "Educator" }, { value: "admin", label: "Admin" }]
2081
- }
2082
- ))), /* @__PURE__ */ React.createElement("td", null, row.hasAccount && /* @__PURE__ */ React.createElement(IconCheck, { color: "green" })), /* @__PURE__ */ React.createElement("td", null, row.numberOfClasses), /* @__PURE__ */ React.createElement("td", null, /* @__PURE__ */ React.createElement(Group, { noWrap: true, spacing: 0, position: "right" }, !row.readonly && !!props.onDelete && /* @__PURE__ */ React.createElement(ActionIcon, { color: "red" }, /* @__PURE__ */ React.createElement(IconTrash, { onClick: () => openDeleteModal(row), size: 16, stroke: 1.5 }))))));
2083
- 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)));
1893
+ 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_1fr_0.6fr] gap-3 border-b border-slate-100 px-5 py-3 text-[10px] font-bold uppercase tracking-wide text-slate-500" }, /* @__PURE__ */ React.createElement("div", null, "Name"), /* @__PURE__ */ React.createElement("div", { className: "text-center" }, "Role"), /* @__PURE__ */ React.createElement("div", { className: "text-center" }, "Account Created?"), /* @__PURE__ */ React.createElement("div", { className: "text-center" }, "# of Classes"), /* @__PURE__ */ React.createElement("div", null)), props.items.map((row, i) => {
1894
+ var _a, _b;
1895
+ const name = row.givenName && row.familyName ? `${row.givenName} ${row.familyName}` : row.email;
1896
+ const initials = (((_a = row.givenName) == null ? void 0 : _a[0]) || row.email[0] || "?") + (((_b = row.familyName) == null ? void 0 : _b[0]) || "");
1897
+ const identity = /* @__PURE__ */ React.createElement(React.Fragment, null, 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-500" }, row.email)));
1898
+ return /* @__PURE__ */ React.createElement(
1899
+ "div",
1900
+ {
1901
+ key: row.email,
1902
+ className: `grid grid-cols-[2.2fr_1.2fr_1fr_1fr_0.6fr] items-center gap-3 px-5 py-3.5 ${i < props.items.length - 1 ? "border-b border-slate-100" : ""}`
1903
+ },
1904
+ row.href ? /* @__PURE__ */ React.createElement(Link, { to: row.href, className: "flex min-w-0 items-center gap-2.5 no-underline" }, identity) : /* @__PURE__ */ React.createElement("div", { className: "flex min-w-0 items-center gap-2.5" }, identity),
1905
+ /* @__PURE__ */ React.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React.createElement(
1906
+ "select",
1907
+ {
1908
+ disabled: row.readonly,
1909
+ value: row.isAdmin ? "admin" : row.isGroupAdmin ? "educator" : "student",
1910
+ onChange: (e) => props.onRoleChange && props.onRoleChange(row, e.target.value),
1911
+ 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"
1912
+ },
1913
+ /* @__PURE__ */ React.createElement("option", { value: "student" }, "Student"),
1914
+ /* @__PURE__ */ React.createElement("option", { value: "educator" }, "Educator"),
1915
+ /* @__PURE__ */ React.createElement("option", { value: "admin" }, "Admin")
1916
+ )),
1917
+ /* @__PURE__ */ React.createElement("div", { className: "flex justify-center" }, row.hasAccount && /* @__PURE__ */ React.createElement(IconCheck, { size: 16, stroke: 3, className: "text-mint-400" })),
1918
+ /* @__PURE__ */ React.createElement("div", { className: "text-center text-xs font-bold text-dark-blue-400" }, row.numberOfClasses),
1919
+ /* @__PURE__ */ React.createElement("div", null, !row.readonly && !!props.onDelete && /* @__PURE__ */ React.createElement(
1920
+ "button",
1921
+ {
1922
+ type: "button",
1923
+ onClick: () => openDeleteModal(row, props.onDelete),
1924
+ className: "flex h-7 w-7 items-center justify-center rounded-md text-slate-400 hover:bg-red-50 hover:text-red-500"
1925
+ },
1926
+ /* @__PURE__ */ React.createElement(IconTrash, { size: 14, stroke: 1.75 })
1927
+ ))
1928
+ );
1929
+ }));
2084
1930
  }
2085
1931
 
2086
1932
  var __defProp$9 = Object.defineProperty;
2087
- var __defProps$6 = Object.defineProperties;
2088
- var __getOwnPropDescs$6 = Object.getOwnPropertyDescriptors;
1933
+ var __defProps$7 = Object.defineProperties;
1934
+ var __getOwnPropDescs$7 = Object.getOwnPropertyDescriptors;
2089
1935
  var __getOwnPropSymbols$9 = Object.getOwnPropertySymbols;
2090
1936
  var __hasOwnProp$9 = Object.prototype.hasOwnProperty;
2091
1937
  var __propIsEnum$9 = Object.prototype.propertyIsEnumerable;
@@ -2101,38 +1947,8 @@ var __spreadValues$9 = (a, b) => {
2101
1947
  }
2102
1948
  return a;
2103
1949
  };
2104
- var __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b));
2105
- const useStyles$9 = createStyles((theme) => ({
2106
- title: {
2107
- fontSize: 34,
2108
- fontWeight: 900,
2109
- [theme.fn.smallerThan("sm")]: {
2110
- fontSize: 24
2111
- }
2112
- },
2113
- description: {
2114
- maxWidth: 600
2115
- },
2116
- wrapper: {
2117
- position: "relative",
2118
- marginBottom: 30
2119
- },
2120
- dropzone: {
2121
- borderWidth: 1,
2122
- paddingBottom: 50
2123
- },
2124
- icon: {
2125
- color: theme.colorScheme === "dark" ? theme.colors.dark[3] : theme.colors.gray[4]
2126
- },
2127
- control: {
2128
- position: "absolute",
2129
- width: 250,
2130
- left: "calc(50% - 125px)",
2131
- bottom: -20
2132
- }
2133
- }));
1950
+ var __spreadProps$7 = (a, b) => __defProps$7(a, __getOwnPropDescs$7(b));
2134
1951
  const People = (props) => {
2135
- const { classes } = useStyles$9();
2136
1952
  const form = useForm({
2137
1953
  initialValues: {
2138
1954
  userId: "",
@@ -2163,12 +1979,12 @@ const People = (props) => {
2163
1979
  padding: "xl",
2164
1980
  size: "xl"
2165
1981
  },
2166
- /* @__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(() => {
1982
+ /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4" }, /* @__PURE__ */ React.createElement(DropzoneButton, __spreadProps$7(__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(() => {
2167
1983
  const values = form.values;
2168
1984
  form.reset();
2169
1985
  setOpened(false);
2170
1986
  props.onCreateUsers && props.onCreateUsers([values]);
2171
- }) }, /* @__PURE__ */ React.createElement(Stack$5, null, /* @__PURE__ */ React.createElement(
1987
+ }) }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement(
2172
1988
  TextInput,
2173
1989
  __spreadValues$9({
2174
1990
  withAsterisk: true,
@@ -2187,23 +2003,22 @@ const People = (props) => {
2187
2003
  label: "Family name",
2188
2004
  placeholder: "Family name"
2189
2005
  }, form.getInputProps("familyName"))
2190
- )), /* @__PURE__ */ React.createElement(Button, { type: "submit", fullWidth: true, mt: "md" }, "Submit"))))
2191
- ), /* @__PURE__ */ React.createElement(Container, { fluid: true, 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(
2192
- Badge$1,
2193
- {
2194
- variant: "filled",
2195
- leftSection: /* @__PURE__ */ React.createElement(ActionIcon, { color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React.createElement(IconArrowLeft, { size: 14 })),
2196
- size: "lg"
2197
- },
2198
- "Back"
2199
- )), /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, "People"), /* @__PURE__ */ React.createElement(Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Manage members of your organization")), /* @__PURE__ */ React.createElement(Grid.Col, { sm: "content" }, !props.loading && /* @__PURE__ */ React.createElement(
2006
+ )), /* @__PURE__ */ React.createElement(
2007
+ "button",
2008
+ {
2009
+ type: "submit",
2010
+ className: "mt-2 rounded-lg bg-dark-blue-400 px-4 py-2.5 text-xs font-bold text-white"
2011
+ },
2012
+ "Submit"
2013
+ ))))
2014
+ ), /* @__PURE__ */ React.createElement("div", { className: "flex 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" }, "People"), /* @__PURE__ */ React.createElement("p", { className: "max-w-xl text-sm text-slate-500" }, "Manage members of your organization")), !props.loading && /* @__PURE__ */ React.createElement(
2200
2015
  SplitButton$2,
2201
2016
  {
2202
2017
  withOrganizationLink: props.withOrganizationLink,
2203
2018
  onAddUsersClick: () => setOpened(true),
2204
2019
  onCopyOrganizationLinkClick: props.onCopyLinkClick
2205
2020
  }
2206
- ))), /* @__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: [
2021
+ )), /* @__PURE__ */ React.createElement(StatsGroup, { data: [
2207
2022
  {
2208
2023
  title: "# OF PEOPLE",
2209
2024
  value: props.users.length
@@ -2218,14 +2033,15 @@ const People = (props) => {
2218
2033
  unit: "%",
2219
2034
  value: props.percentageRostered
2220
2035
  }
2221
- ] }), /* @__PURE__ */ React.createElement(
2222
- Autocomplete,
2036
+ ] }), /* @__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(
2037
+ "input",
2223
2038
  {
2039
+ type: "text",
2224
2040
  placeholder: "Search for a people in your organization",
2225
- data: props.users.map((item) => item.email),
2226
- onChange: props.onAutocompleteChange
2041
+ onChange: (e) => props.onAutocompleteChange(e.target.value),
2042
+ 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"
2227
2043
  }
2228
- ), /* @__PURE__ */ React.createElement(
2044
+ )), /* @__PURE__ */ React.createElement(
2229
2045
  Table$4,
2230
2046
  {
2231
2047
  loading: props.loading,
@@ -2233,10 +2049,9 @@ const People = (props) => {
2233
2049
  onDelete: props.onDeleteUser,
2234
2050
  onRoleChange: props.onChangeUserRole
2235
2051
  }
2236
- ))))));
2052
+ )));
2237
2053
  };
2238
2054
  const DropzoneButton = (props) => {
2239
- const { classes, theme } = useStyles$9();
2240
2055
  const openRef = React.useRef(null);
2241
2056
  const [loading, setLoading] = React.useState(false);
2242
2057
  const onDrop = React.useCallback((acceptedFiles) => {
@@ -2257,32 +2072,33 @@ const DropzoneButton = (props) => {
2257
2072
  });
2258
2073
  });
2259
2074
  }, []);
2260
- return /* @__PURE__ */ React.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React.createElement(
2075
+ return /* @__PURE__ */ React.createElement("div", { className: "relative mb-8" }, /* @__PURE__ */ React.createElement(
2261
2076
  Dropzone,
2262
2077
  {
2263
2078
  loading,
2264
2079
  openRef,
2265
2080
  onDrop,
2266
- className: classes.dropzone,
2267
2081
  radius: "md",
2082
+ className: "border pb-12",
2268
2083
  accept: [MIME_TYPES.csv],
2269
2084
  maxSize: 5 * 1024 ** 2
2270
2085
  },
2271
- /* @__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(
2272
- IconCloudUpload,
2273
- {
2274
- size: 50,
2275
- color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
2276
- stroke: 1.5
2277
- }
2278
- ))), /* @__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."))
2279
- ), /* @__PURE__ */ React.createElement(Button, { className: classes.control, size: "md", radius: "xl", onClick: () => {
2280
- var _a;
2281
- return (_a = openRef.current) == null ? void 0 : _a.call(openRef);
2282
- } }, "Select file"));
2086
+ /* @__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: "#1EE2AF", stroke: 1.5 })), /* @__PURE__ */ React.createElement(Dropzone.Reject, null, /* @__PURE__ */ React.createElement(IconX, { size: 50, color: "#ef4444", stroke: 1.5 })), /* @__PURE__ */ React.createElement(Dropzone.Idle, null, /* @__PURE__ */ React.createElement(IconCloudUpload, { size: 50, color: "#232A3A", stroke: 1.5 }))), /* @__PURE__ */ React.createElement("p", { className: "mt-6 text-center text-lg font-bold text-dark-blue-400" }, /* @__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("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."))
2087
+ ), /* @__PURE__ */ React.createElement(
2088
+ "button",
2089
+ {
2090
+ type: "button",
2091
+ onClick: () => {
2092
+ var _a;
2093
+ return (_a = openRef.current) == null ? void 0 : _a.call(openRef);
2094
+ },
2095
+ className: "absolute bottom-[-20px] left-1/2 w-[250px] -translate-x-1/2 rounded-full bg-dark-blue-400 px-6 py-2.5 text-xs font-bold text-white"
2096
+ },
2097
+ "Select file"
2098
+ ));
2283
2099
  };
2284
2100
 
2285
- const useStyles$8 = createStyles((theme) => ({
2101
+ const useStyles$6 = createStyles((theme) => ({
2286
2102
  form: {
2287
2103
  backgroundColor: theme.white,
2288
2104
  padding: theme.spacing.xl,
@@ -2345,7 +2161,7 @@ const useStyles$8 = createStyles((theme) => ({
2345
2161
  }
2346
2162
  }));
2347
2163
  const StartAnonymousLesson = (props) => {
2348
- const { classes } = useStyles$8();
2164
+ const { classes } = useStyles$6();
2349
2165
  const [name, setName] = React.useState("");
2350
2166
  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(
2351
2167
  TextInput,
@@ -2402,7 +2218,7 @@ function TaskCard(props) {
2402
2218
  ));
2403
2219
  }
2404
2220
 
2405
- const useStyles$7 = createStyles((theme) => ({
2221
+ const useStyles$5 = createStyles((theme) => ({
2406
2222
  title: {
2407
2223
  fontSize: 34,
2408
2224
  fontWeight: 900,
@@ -2416,7 +2232,7 @@ const useStyles$7 = createStyles((theme) => ({
2416
2232
  }
2417
2233
  }));
2418
2234
  const UserInfo = (props) => {
2419
- const { classes } = useStyles$7();
2235
+ const { classes } = useStyles$5();
2420
2236
  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));
2421
2237
  };
2422
2238
 
@@ -2448,7 +2264,7 @@ var __objRest$1 = (source, exclude) => {
2448
2264
  }
2449
2265
  return target;
2450
2266
  };
2451
- const useStyles$6 = createStyles((theme) => ({
2267
+ const useStyles$4 = createStyles((theme) => ({
2452
2268
  card: {
2453
2269
  height: 240,
2454
2270
  backgroundSize: "cover",
@@ -2493,7 +2309,7 @@ const TenantBanner = (_a) => {
2493
2309
  "className",
2494
2310
  "code"
2495
2311
  ]);
2496
- const { classes, cx, theme } = useStyles$6();
2312
+ const { classes, cx, theme } = useStyles$4();
2497
2313
  const handleCopy = async () => {
2498
2314
  if (!code)
2499
2315
  return;
@@ -2540,7 +2356,7 @@ const TenantBanner = (_a) => {
2540
2356
  );
2541
2357
  };
2542
2358
 
2543
- const useStyles$5 = createStyles((theme) => ({
2359
+ const useStyles$3 = createStyles((theme) => ({
2544
2360
  action: {
2545
2361
  backgroundColor: "inherit",
2546
2362
  ":hover": {
@@ -2559,7 +2375,7 @@ const useStyles$5 = createStyles((theme) => ({
2559
2375
  }
2560
2376
  }));
2561
2377
  const TrialHome = (props) => {
2562
- const { classes } = useStyles$5();
2378
+ const { classes } = useStyles$3();
2563
2379
  return /* @__PURE__ */ React.createElement(Container, { fluid: true }, /* @__PURE__ */ React.createElement(Badge$1, null, props.daysRemaining, " day", props.daysRemaining !== 1 ? "s" : "", " left"), /* @__PURE__ */ React.createElement(
2564
2380
  Button,
2565
2381
  {
@@ -2589,8 +2405,8 @@ const TrialHome = (props) => {
2589
2405
  };
2590
2406
 
2591
2407
  var __defProp$6 = Object.defineProperty;
2592
- var __defProps$5 = Object.defineProperties;
2593
- var __getOwnPropDescs$5 = Object.getOwnPropertyDescriptors;
2408
+ var __defProps$6 = Object.defineProperties;
2409
+ var __getOwnPropDescs$6 = Object.getOwnPropertyDescriptors;
2594
2410
  var __getOwnPropSymbols$6 = Object.getOwnPropertySymbols;
2595
2411
  var __hasOwnProp$6 = Object.prototype.hasOwnProperty;
2596
2412
  var __propIsEnum$6 = Object.prototype.propertyIsEnumerable;
@@ -2606,7 +2422,7 @@ var __spreadValues$6 = (a, b) => {
2606
2422
  }
2607
2423
  return a;
2608
2424
  };
2609
- var __spreadProps$5 = (a, b) => __defProps$5(a, __getOwnPropDescs$5(b));
2425
+ var __spreadProps$6 = (a, b) => __defProps$6(a, __getOwnPropDescs$6(b));
2610
2426
  var __objRest = (source, exclude) => {
2611
2427
  var target = {};
2612
2428
  for (var prop in source)
@@ -2619,7 +2435,7 @@ var __objRest = (source, exclude) => {
2619
2435
  }
2620
2436
  return target;
2621
2437
  };
2622
- const useStyles$4 = createStyles((theme, { checked }) => ({
2438
+ const useStyles$2 = createStyles((theme, { checked }) => ({
2623
2439
  button: {
2624
2440
  display: "flex",
2625
2441
  alignItems: "center",
@@ -2661,10 +2477,10 @@ function ImageCheckbox(_a) {
2661
2477
  finalValue: false,
2662
2478
  onChange
2663
2479
  });
2664
- const { classes, cx } = useStyles$4({ checked: value });
2480
+ const { classes, cx } = useStyles$2({ checked: value });
2665
2481
  return /* @__PURE__ */ React.createElement(
2666
2482
  UnstyledButton,
2667
- __spreadProps$5(__spreadValues$6({}, others), {
2483
+ __spreadProps$6(__spreadValues$6({}, others), {
2668
2484
  onClick: () => handleChange(!value),
2669
2485
  className: cx(classes.button, className)
2670
2486
  }),
@@ -2685,7 +2501,7 @@ function ImageCheckbox(_a) {
2685
2501
  function SelectGrid(props) {
2686
2502
  const items = props.items.map((item) => /* @__PURE__ */ React.createElement(
2687
2503
  ImageCheckbox,
2688
- __spreadProps$5(__spreadValues$6({}, item), {
2504
+ __spreadProps$6(__spreadValues$6({}, item), {
2689
2505
  key: item.title,
2690
2506
  onChange: (checked) => props.onChange(item.title, checked)
2691
2507
  })
@@ -2704,8 +2520,8 @@ function SelectGrid(props) {
2704
2520
  }
2705
2521
 
2706
2522
  var __defProp$5 = Object.defineProperty;
2707
- var __defProps$4 = Object.defineProperties;
2708
- var __getOwnPropDescs$4 = Object.getOwnPropertyDescriptors;
2523
+ var __defProps$5 = Object.defineProperties;
2524
+ var __getOwnPropDescs$5 = Object.getOwnPropertyDescriptors;
2709
2525
  var __getOwnPropSymbols$5 = Object.getOwnPropertySymbols;
2710
2526
  var __hasOwnProp$5 = Object.prototype.hasOwnProperty;
2711
2527
  var __propIsEnum$5 = Object.prototype.propertyIsEnumerable;
@@ -2721,8 +2537,8 @@ var __spreadValues$5 = (a, b) => {
2721
2537
  }
2722
2538
  return a;
2723
2539
  };
2724
- var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
2725
- const useStyles$3 = createStyles((theme) => ({
2540
+ var __spreadProps$5 = (a, b) => __defProps$5(a, __getOwnPropDescs$5(b));
2541
+ const useStyles$1 = createStyles((theme) => ({
2726
2542
  wrapper: {
2727
2543
  minHeight: "100%",
2728
2544
  boxSizing: "border-box",
@@ -2785,7 +2601,7 @@ const OPTIONS = [
2785
2601
  { description: "project-based learning", title: "Project-Based Learning", icon: IconTools }
2786
2602
  ];
2787
2603
  const TrialRegistration = (props) => {
2788
- const { classes } = useStyles$3();
2604
+ const { classes } = useStyles$1();
2789
2605
  const [firstName, setFirstName] = React.useState("");
2790
2606
  const [lastName, setLastName] = React.useState("");
2791
2607
  const [organization, setOrganization] = React.useState({ organizationId: "", displayName: "" });
@@ -2831,7 +2647,7 @@ const TrialRegistration = (props) => {
2831
2647
  label: "School/Organization Name",
2832
2648
  placeholder: "What's the name of your school?",
2833
2649
  data: props.organizations.map((o) => {
2834
- return __spreadProps$4(__spreadValues$5({}, o), { value: o.displayName });
2650
+ return __spreadProps$5(__spreadValues$5({}, o), { value: o.displayName });
2835
2651
  }),
2836
2652
  onItemSubmit: (item) => setOrganization({ organizationId: item.organizationId, displayName: item.displayName }),
2837
2653
  onChange: (next) => {
@@ -2843,7 +2659,7 @@ const TrialRegistration = (props) => {
2843
2659
  SelectGrid,
2844
2660
  {
2845
2661
  items: OPTIONS,
2846
- onChange: (e, checked) => setInterests(__spreadProps$4(__spreadValues$5({}, interests), { [e]: checked }))
2662
+ onChange: (e, checked) => setInterests(__spreadProps$5(__spreadValues$5({}, interests), { [e]: checked }))
2847
2663
  }
2848
2664
  ), /* @__PURE__ */ React.createElement(Group, { position: "right", mt: "md" }, /* @__PURE__ */ React.createElement(
2849
2665
  Button,
@@ -2882,8 +2698,8 @@ const AdminProvider = (props) => {
2882
2698
  };
2883
2699
 
2884
2700
  var __defProp$4 = Object.defineProperty;
2885
- var __defProps$3 = Object.defineProperties;
2886
- var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
2701
+ var __defProps$4 = Object.defineProperties;
2702
+ var __getOwnPropDescs$4 = Object.getOwnPropertyDescriptors;
2887
2703
  var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
2888
2704
  var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
2889
2705
  var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
@@ -2899,8 +2715,8 @@ var __spreadValues$4 = (a, b) => {
2899
2715
  }
2900
2716
  return a;
2901
2717
  };
2902
- var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
2903
- const useStyles$2 = createStyles((theme, props) => ({
2718
+ var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
2719
+ const useStyles = createStyles((theme, props) => ({
2904
2720
  footer: {
2905
2721
  paddingTop: theme.spacing.md,
2906
2722
  paddingBottom: theme.spacing.md,
@@ -2987,7 +2803,7 @@ const useStyles$2 = createStyles((theme, props) => ({
2987
2803
  }
2988
2804
  }));
2989
2805
  const App = (props) => {
2990
- const { classes } = useStyles$2(props);
2806
+ const { classes } = useStyles(props);
2991
2807
  const account = useAccount(props.account, props.accounts, props.onAccountChange);
2992
2808
  return /* @__PURE__ */ React.createElement(
2993
2809
  AppShell,
@@ -2995,7 +2811,7 @@ const App = (props) => {
2995
2811
  padding: "xs",
2996
2812
  navbar: props.navbar && /* @__PURE__ */ React.createElement(
2997
2813
  Navbar,
2998
- __spreadProps$3(__spreadValues$4({}, props.navbar.props), {
2814
+ __spreadProps$4(__spreadValues$4({}, props.navbar.props), {
2999
2815
  onSwitchAccounts: account.accounts && account.accounts.length > 1 ? () => account.setChangeModalOpen(true) : void 0
3000
2816
  })
3001
2817
  ),
@@ -3089,61 +2905,52 @@ function Table$3(props) {
3089
2905
  if (props.items.length === 0) {
3090
2906
  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.");
3091
2907
  }
3092
- return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, props.items.map((row) => /* @__PURE__ */ React.createElement(
3093
- Link,
3094
- {
3095
- key: row.badgeId,
3096
- to: row.href,
3097
- className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
3098
- },
3099
- /* @__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)),
3100
- /* @__PURE__ */ React.createElement(IconChevronRight, { size: 16, stroke: 2, className: "shrink-0 text-slate-300" })
3101
- )));
2908
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, props.items.map((row) => {
2909
+ var _a;
2910
+ return /* @__PURE__ */ React.createElement(
2911
+ Link,
2912
+ {
2913
+ key: row.pathwayId,
2914
+ to: row.href,
2915
+ className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
2916
+ },
2917
+ /* @__PURE__ */ React.createElement(Emblem, { imageURL: row.imageURL, alt: row.name, size: "sm", icon: IconRoute, accent: "cyan" }),
2918
+ /* @__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), !!((_a = row.displayTags) == null ? void 0 : _a.length) && /* @__PURE__ */ React.createElement("div", { className: "mt-1.5 flex flex-wrap gap-1.5" }, row.displayTags.map((tag) => /* @__PURE__ */ React.createElement("span", { key: tag, className: "rounded-full bg-slate-100 px-2 py-0.5 text-[10px] font-bold text-slate-500" }, tag)))),
2919
+ !!row.numberOfBadges && /* @__PURE__ */ React.createElement("div", { className: "w-24 shrink-0 text-right text-xs text-slate-500" }, row.numberOfBadges, " badge", row.numberOfBadges === 1 ? "" : "s"),
2920
+ /* @__PURE__ */ React.createElement(IconChevronRight, { size: 16, stroke: 2, className: "shrink-0 text-slate-300" })
2921
+ );
2922
+ }));
3102
2923
  }
3103
2924
 
3104
2925
  const Pathways = (props) => {
3105
2926
  return /* @__PURE__ */ React.createElement("div", { className: "flex 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 }));
3106
2927
  };
3107
2928
 
3108
- const useStyles$1 = createStyles((theme) => ({
3109
- button: {
3110
- borderTopRightRadius: 0,
3111
- borderBottomRightRadius: 0,
3112
- marginLeft: 0,
3113
- marginRight: 0
3114
- },
3115
- menuControl: {
3116
- borderTopLeftRadius: 0,
3117
- borderBottomLeftRadius: 0,
3118
- border: 0,
3119
- borderLeft: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.white}`
3120
- }
3121
- }));
3122
2929
  const SplitButton$1 = (props) => {
3123
- const { classes, theme } = useStyles$1();
3124
- theme.colors[theme.primaryColor][theme.colorScheme === "dark" ? 5 : 6];
3125
- return /* @__PURE__ */ React.createElement(Stack$5, { spacing: "sm" }, /* @__PURE__ */ React.createElement(
3126
- Button,
2930
+ return /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement(
2931
+ Link,
3127
2932
  {
3128
- component: Link,
3129
2933
  to: props.href,
3130
- className: classes.button,
3131
- variant: "gradient"
2934
+ 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 no-underline hover:bg-slate-50"
3132
2935
  },
3133
2936
  "Preview"
3134
2937
  ), /* @__PURE__ */ React.createElement(
3135
- Button,
2938
+ "button",
3136
2939
  {
3137
- leftIcon: /* @__PURE__ */ React.createElement(IconClipboardCopy, { size: 14 }),
3138
- onClick: props.onCopyLinkClick
2940
+ type: "button",
2941
+ onClick: props.onCopyLinkClick,
2942
+ 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"
3139
2943
  },
2944
+ /* @__PURE__ */ React.createElement(IconClipboardCopy, { size: 13, stroke: 2 }),
3140
2945
  "Copy link"
3141
2946
  ), /* @__PURE__ */ React.createElement(
3142
- Button,
2947
+ "button",
3143
2948
  {
3144
- leftIcon: /* @__PURE__ */ React.createElement(IconTableExport, { size: 14 }),
3145
- onClick: props.onExportDataClick
2949
+ type: "button",
2950
+ onClick: props.onExportDataClick,
2951
+ 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)]"
3146
2952
  },
2953
+ /* @__PURE__ */ React.createElement(IconTableExport, { size: 13, stroke: 2 }),
3147
2954
  "Export data (.csv)"
3148
2955
  ));
3149
2956
  };
@@ -3152,11 +2959,12 @@ function Stack$1(props) {
3152
2959
  if (props.items.length === 0) {
3153
2960
  return null;
3154
2961
  }
3155
- const rows = props.items.map((row) => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Grid.Col, { span: 6 }, /* @__PURE__ */ React.createElement(Text, { component: Link, to: row.href, color: "dark.4", weight: "bold", size: "md" }, row.badgeName)), /* @__PURE__ */ React.createElement(Grid.Col, { span: 6 }, row.completion >= 1 && /* @__PURE__ */ React.createElement(Badge$1, { variant: "filled" }, "Complete"), row.completion === 0 && !row.isStarted && /* @__PURE__ */ React.createElement(Badge$1, { color: "red", variant: "filled" }, "Not started"), row.completion > 0 && row.completion < 1 && /* @__PURE__ */ React.createElement(Badge$1, { color: "violet", variant: "filled" }, Math.round((row.completion + Number.EPSILON) * 100), "% Complete"))));
3156
- return /* @__PURE__ */ React.createElement(Grid, { grow: true, gutter: "lg", sx: { padding: 20, minWidth: 700 } }, rows);
2962
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2" }, props.items.map((row) => /* @__PURE__ */ React.createElement("div", { key: row.badgeName, className: "flex items-center justify-between gap-4 py-1.5" }, /* @__PURE__ */ React.createElement(Link, { to: row.href, className: "text-sm font-bold text-dark-blue-400 no-underline hover:underline" }, row.badgeName), row.completion >= 1 && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 rounded-full bg-mint-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, "Complete"), row.completion === 0 && !row.isStarted && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 rounded-full bg-slate-100 px-2.5 py-1 text-[10px] font-bold text-slate-500" }, "Not started"), row.completion > 0 && row.completion < 1 && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 rounded-full bg-gold-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, Math.round((row.completion + Number.EPSILON) * 100), "% Complete"))));
3157
2963
  }
3158
2964
 
3159
2965
  var __defProp$3 = Object.defineProperty;
2966
+ var __defProps$3 = Object.defineProperties;
2967
+ var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
3160
2968
  var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
3161
2969
  var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
3162
2970
  var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
@@ -3172,7 +2980,10 @@ var __spreadValues$3 = (a, b) => {
3172
2980
  }
3173
2981
  return a;
3174
2982
  };
2983
+ var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
3175
2984
  function Table$2(props) {
2985
+ const [expanded, setExpanded] = React.useState({});
2986
+ const categories = props.categories || [];
3176
2987
  const preparedItems = React.useMemo(() => {
3177
2988
  return (props.items || []).map((item) => __spreadValues$3(__spreadValues$3({}, item), item.categoryPoints));
3178
2989
  }, [props.items]);
@@ -3188,55 +2999,26 @@ function Table$2(props) {
3188
2999
  }
3189
3000
  );
3190
3001
  }
3191
- const sortStatus = {
3192
- columnAccessor: sortConfig.key,
3193
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
3194
- };
3195
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(
3196
- DataTable,
3197
- {
3198
- verticalSpacing: "sm",
3199
- sx: { minWidth: 700 },
3200
- withBorder: false,
3201
- borderRadius: "sm",
3202
- withColumnBorders: true,
3203
- striped: true,
3204
- highlightOnHover: true,
3205
- records: sortedItems,
3206
- idAccessor: "userId",
3207
- sortStatus,
3208
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
3209
- columns: [
3210
- {
3211
- accessor: "name",
3212
- title: "Student Name",
3213
- sortable: true,
3214
- titleStyle: { whiteSpace: "nowrap" },
3215
- render: (row) => /* @__PURE__ */ React.createElement(Group, { spacing: "sm", noWrap: true }, /* @__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)))
3216
- },
3217
- {
3218
- accessor: "isComplete",
3219
- title: "Status",
3220
- sortable: true,
3221
- titleStyle: { whiteSpace: "nowrap" },
3222
- render: (row) => /* @__PURE__ */ React.createElement(Badge$1, { color: row.isComplete ? "blue" : "red", variant: "filled" }, row.isComplete ? "Complete" : "Incomplete")
3223
- },
3224
- ...props.categories.map((category) => ({
3225
- accessor: category.categoryId,
3226
- title: category.name,
3227
- sortable: true,
3228
- titleStyle: { whiteSpace: "nowrap" },
3229
- render: (row) => {
3230
- var _a;
3231
- return /* @__PURE__ */ React.createElement(Badge$1, { color: "blue", variant: "filled" }, (_a = row[category.categoryId]) != null ? _a : 0, " pts");
3232
- }
3233
- }))
3234
- ],
3235
- rowExpansion: {
3236
- content: ({ record }) => /* @__PURE__ */ React.createElement(Stack$1, { items: record.badges })
3237
- }
3238
- }
3239
- ));
3002
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
3003
+ 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("isComplete"), className: "w-28 shrink-0 text-center hover:text-slate-600" }, "Status", indicator("isComplete")), categories.map((category) => /* @__PURE__ */ React.createElement("button", { key: category.categoryId, onClick: () => requestSort(category.categoryId), className: "w-24 shrink-0 text-center hover:text-slate-600" }, category.name, indicator(category.categoryId))), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), sortedItems.map((row) => {
3004
+ var _a;
3005
+ const isOpen = !!expanded[row.userId];
3006
+ const initials = (((_a = row.name) == null ? void 0 : _a[0]) || row.email[0] || "?").toUpperCase();
3007
+ return /* @__PURE__ */ React.createElement("div", { key: row.userId, className: "rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement(
3008
+ "div",
3009
+ {
3010
+ onClick: () => setExpanded(__spreadProps$3(__spreadValues$3({}, expanded), { [row.userId]: !isOpen })),
3011
+ className: "flex cursor-pointer items-center gap-4 p-4"
3012
+ },
3013
+ /* @__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-mint-400/20 text-xs font-bold text-dark-blue-400" }, initials), /* @__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))),
3014
+ /* @__PURE__ */ React.createElement("div", { className: "w-28 shrink-0 text-center" }, row.isComplete ? /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-mint-100 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, "Complete") : /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-slate-100 px-2.5 py-1 text-[10px] font-bold text-slate-500" }, "Incomplete")),
3015
+ categories.map((category) => {
3016
+ var _a2;
3017
+ return /* @__PURE__ */ React.createElement("div", { key: category.categoryId, className: "w-24 shrink-0 text-center" }, /* @__PURE__ */ React.createElement("span", { className: "rounded-full bg-sky-blue-400/15 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, (_a2 = row[category.categoryId]) != null ? _a2 : 0, " pts"));
3018
+ }),
3019
+ /* @__PURE__ */ React.createElement(IconChevronDown, { size: 15, stroke: 2.3, className: `shrink-0 text-slate-400 transition-transform ${isOpen ? "rotate-180" : ""}` })
3020
+ ), isOpen && /* @__PURE__ */ React.createElement("div", { className: "border-t border-slate-100 px-4 py-3" }, /* @__PURE__ */ React.createElement(Stack$1, { items: row.badges })));
3021
+ }));
3240
3022
  }
3241
3023
 
3242
3024
  function Table$1(props) {
@@ -3252,138 +3034,60 @@ function Table$1(props) {
3252
3034
  }
3253
3035
  );
3254
3036
  }
3255
- const sortStatus = {
3256
- columnAccessor: sortConfig.key,
3257
- direction: sortConfig.direction === "desc" ? "desc" : "asc"
3258
- };
3259
- return /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(
3260
- DataTable,
3261
- {
3262
- verticalSpacing: "sm",
3263
- withBorder: false,
3264
- borderRadius: "sm",
3265
- sx: { minWidth: 700 },
3266
- highlightOnHover: true,
3267
- striped: true,
3268
- records: sortedItems,
3269
- idAccessor: "badgeId",
3270
- sortStatus,
3271
- onSortStatusChange: (status) => requestSort(status.columnAccessor),
3272
- columns: [
3273
- {
3274
- accessor: "badgeName",
3275
- title: "Badge Name",
3276
- sortable: true,
3277
- render: (row) => /* @__PURE__ */ React.createElement(
3278
- Text,
3279
- {
3280
- component: Link,
3281
- to: row.href,
3282
- sx: (theme) => ({
3283
- color: theme.colorScheme === "dark" ? theme.white : theme.black,
3284
- textDecoration: "none",
3285
- fontWeight: 500,
3286
- "&:hover": {
3287
- textDecoration: "underline",
3288
- color: theme.colors.blue[6]
3289
- }
3290
- })
3291
- },
3292
- row.badgeName
3293
- )
3294
- },
3295
- {
3296
- accessor: "percentageCompletion",
3297
- title: "Badge Completion",
3298
- sortable: true,
3299
- render: (row) => {
3300
- const roundedValue = Math.round((row.percentageCompletion + Number.EPSILON) * 100);
3301
- return `${roundedValue}%`;
3302
- }
3303
- }
3304
- ]
3305
- }
3306
- ));
3037
+ const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
3038
+ 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("button", { onClick: () => requestSort("badgeName"), className: "flex-1 text-left hover:text-slate-600" }, "Badge Name", indicator("badgeName")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("percentageCompletion"), className: "w-36 shrink-0 text-right hover:text-slate-600" }, "Badge Completion", indicator("percentageCompletion"))), sortedItems.map((row) => /* @__PURE__ */ React.createElement(
3039
+ Link,
3040
+ {
3041
+ key: row.badgeId,
3042
+ to: row.href,
3043
+ className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
3044
+ },
3045
+ /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1 text-sm font-bold text-dark-blue-400" }, row.badgeName),
3046
+ /* @__PURE__ */ React.createElement("div", { className: "w-36 shrink-0 text-right text-xs text-slate-500" }, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")
3047
+ )));
3307
3048
  }
3308
3049
 
3309
- const useStyles = createStyles((theme) => ({
3310
- title: {
3311
- fontSize: 34,
3312
- fontWeight: 900,
3313
- [theme.fn.smallerThan("sm")]: {
3314
- fontSize: 24
3315
- }
3316
- },
3317
- description: {
3318
- maxWidth: 600
3319
- }
3320
- }));
3050
+ const TABS$1 = [
3051
+ { label: "By Badge", value: "badges" },
3052
+ { label: "By student", value: "students" }
3053
+ ];
3321
3054
  const Pathway = (props) => {
3322
- const { classes } = useStyles();
3055
+ var _a;
3323
3056
  const [tab, setTab] = useState("badges");
3324
3057
  const numberOfStudents = props.students.length;
3325
- numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length / numberOfStudents : 0;
3326
3058
  const numberOfBadgesEarned = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length : 0;
3327
- return /* @__PURE__ */ React.createElement(Container, { fluid: true, 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(
3328
- Badge$1,
3329
- {
3330
- variant: "filled",
3331
- leftSection: /* @__PURE__ */ React.createElement(ActionIcon, { color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React.createElement(IconArrowLeft, { size: 14 })),
3332
- size: "lg"
3333
- },
3334
- "Back"
3335
- )), /* @__PURE__ */ React.createElement(Group, null, /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0 }, /* @__PURE__ */ React.createElement(Title, { order: 2, className: classes.title, mt: "md" }, props.title || "Pathway"), /* @__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(
3059
+ const criteria = props.criteria || {};
3060
+ const criteriaCategories = (props.categories || []).filter((c) => criteria[c.categoryId] !== void 0);
3061
+ return /* @__PURE__ */ React.createElement("div", { className: "flex 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: "flex items-start gap-4" }, /* @__PURE__ */ React.createElement(Emblem, { imageURL: props.imageURL, alt: props.title, size: "lg", icon: IconRoute, accent: "cyan" }), /* @__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.title || "Pathway"), !!((_a = props.displayTags) == null ? void 0 : _a.length) && /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-1.5" }, props.displayTags.map((tag) => /* @__PURE__ */ React.createElement("span", { key: tag, className: "rounded-full bg-slate-100 px-2.5 py-1 text-[10px] font-bold text-slate-500" }, tag))), /* @__PURE__ */ React.createElement("p", { className: "max-w-xl text-sm text-slate-500" }, props.description || "No description"), criteriaCategories.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-1.5 pt-0.5" }, /* @__PURE__ */ React.createElement("span", { className: "text-[10.5px] font-extrabold uppercase tracking-wide text-slate-400" }, "Criteria"), criteriaCategories.map((c) => /* @__PURE__ */ React.createElement("span", { key: c.categoryId, className: "rounded-full bg-sky-blue-400/15 px-2.5 py-1 text-[10px] font-bold text-dark-blue-400" }, c.name, ": ", criteria[c.categoryId], "+", c.maxPoints ? ` of ${c.maxPoints}` : "", " pts"))))), !props.trial && /* @__PURE__ */ React.createElement(
3336
3062
  SplitButton$1,
3337
3063
  {
3338
3064
  href: props.href,
3339
3065
  onCopyLinkClick: props.onCopyLinkClick,
3340
3066
  onExportDataClick: props.onExportDataClick
3341
3067
  }
3342
- ))))), /* @__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: [
3068
+ )), /* @__PURE__ */ React.createElement(StatsGroup, { data: [
3343
3069
  {
3344
3070
  title: props.trial ? "BADGES SUBMITTED" : "PATHWAY COMPLETION",
3345
- value: props.trial ? 0 : numberOfBadgesEarned,
3346
- unit: props.trial ? "" : ""
3071
+ value: props.trial ? 0 : numberOfBadgesEarned
3347
3072
  }
3348
- ] }), !props.trial && /* @__PURE__ */ React.createElement(
3349
- Select,
3073
+ ] }), !props.trial && /* @__PURE__ */ React.createElement("div", { className: "relative w-full max-w-xs" }, /* @__PURE__ */ React.createElement(IconCategory2, { size: 16, stroke: 2, className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" }), /* @__PURE__ */ React.createElement(
3074
+ "select",
3350
3075
  {
3351
- clearable: true,
3352
- clearButtonLabel: "Clear class selection",
3353
- size: "sm",
3354
- placeholder: "Select a class",
3355
- nothingFound: "No options",
3356
3076
  value: props.classId,
3357
- onChange: props.onClassChange,
3358
- icon: /* @__PURE__ */ React.createElement(IconCategory2, null),
3359
- data: props.classes.map((g) => {
3360
- return { value: g.classId, label: g.name };
3361
- })
3362
- }
3363
- ), /* @__PURE__ */ React.createElement(Stack$5, { spacing: 0 }, !props.trial && /* @__PURE__ */ React.createElement(
3364
- Tabs,
3365
- {
3366
- value: tab,
3367
- data: [
3368
- { label: "By Badge", value: "badges" },
3369
- { label: "By student", value: "students" }
3370
- ],
3371
- onChange: setTab
3372
- }
3373
- ), (!!props.trial || tab === "badges") && /* @__PURE__ */ React.createElement(
3374
- Table$1,
3375
- {
3376
- loading: props.loading,
3377
- items: props.badges
3378
- }
3379
- ), !props.trial && tab === "students" && /* @__PURE__ */ React.createElement(
3380
- Table$2,
3077
+ onChange: (e) => props.onClassChange(e.target.value),
3078
+ className: "w-full appearance-none rounded-lg border border-slate-200 bg-white py-2 pl-9 pr-4 text-sm text-dark-blue-400 focus:border-sky-blue-400 focus:outline-none"
3079
+ },
3080
+ /* @__PURE__ */ React.createElement("option", { value: "" }, "All classes"),
3081
+ props.classes.map((c) => /* @__PURE__ */ React.createElement("option", { key: c.classId, value: c.classId }, c.name))
3082
+ )), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, !props.trial && /* @__PURE__ */ React.createElement("div", { className: "flex w-fit gap-1 rounded-xl border border-slate-200 bg-white p-1" }, TABS$1.map((t) => /* @__PURE__ */ React.createElement(
3083
+ "button",
3381
3084
  {
3382
- loading: props.loading,
3383
- items: props.students,
3384
- categories: props.categories
3385
- }
3386
- )))))));
3085
+ key: t.value,
3086
+ onClick: () => setTab(t.value),
3087
+ 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"}`
3088
+ },
3089
+ t.label
3090
+ ))), (!!props.trial || tab === "badges") && /* @__PURE__ */ React.createElement(Table$1, { loading: props.loading, items: props.badges }), !props.trial && tab === "students" && /* @__PURE__ */ React.createElement(Table$2, { loading: props.loading, items: props.students, categories: props.categories })));
3387
3091
  };
3388
3092
 
3389
3093
  const SplitButton = (props) => {