@local-civics/mgmt-ui 0.1.221 → 0.1.223

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,11 +1,11 @@
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, 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';
3
+ import { IconChevronRight, IconVideo, IconSwitchHorizontal, IconLogout, IconHome2, IconGauge, IconCategory2, IconRoute, IconAlbum, IconLambda, IconClipboard, IconBuilding, IconBooks, IconBackpack, IconClipboardCopy, IconTableExport, IconCaretDown, IconCaretUp, 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, Image, Drawer, Divider, TextInput, Tooltip, ActionIcon, SimpleGrid, Badge as Badge$1, Card, UnstyledButton, Overlay, Stack as Stack$5, ThemeIcon, Checkbox, Autocomplete, createEmotionCache, MantineProvider, AppShell } from '@mantine/core';
5
5
  import { Link } from 'react-router-dom';
6
+ import 'external-svg-loader';
6
7
  import { showNotification, NotificationsProvider } from '@mantine/notifications';
7
8
  export { showNotification, updateNotification } from '@mantine/notifications';
8
- import 'external-svg-loader';
9
9
  import { Dropzone, MIME_TYPES } from '@mantine/dropzone';
10
10
  import { useForm } from '@mantine/form';
11
11
  import * as papa from 'papaparse';
@@ -40,7 +40,7 @@ function styleInject(css, ref) {
40
40
  }
41
41
  }
42
42
 
43
- 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}.mt-3{margin-top:.75rem}.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}.max-h-\\[70vh\\]{max-height:70vh}.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-6{gap:1.5rem}.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-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-l{border-left-width:1px}.border-dashed{border-style:dashed}.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-slate-50\\/60{background-color:rgba(248,250,252,.6)}.bg-sky-blue-400\\/15{background-color:rgba(59,208,242,.15)}.bg-gold-400\\/15{background-color:rgba(255,212,77,.15)}.bg-mint-400\\/15{background-color:rgba(30,226,175,.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}.px-1{padding-left:.25rem;padding-right:.25rem}.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}.pr-1{padding-right:.25rem}.pl-4{padding-left:1rem}.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}";
43
+ 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}.mt-3{margin-top:.75rem}.mb-8{margin-bottom:2rem}.ml-\\[29px\\]{margin-left:29px}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-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-14{height:3.5rem}.h-16{height:4rem}.h-28{height:7rem}.h-\\[30px\\]{height:30px}.h-\\[400px\\]{height:400px}.max-h-\\[70vh\\]{max-height:70vh}.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-\\[500px\\]{width:500px}.w-14{width:3.5rem}.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}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.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-end{justify-content:flex-end}.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)))}.-space-y-\\[3px\\]>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(-3px*var(--tw-space-y-reverse));margin-top:calc(-3px*(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-3xl{border-radius:1.5rem}.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-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-l{border-left-width:1px}.border-dashed{border-style:dashed}.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\\/40{border-color:rgba(59,208,242,.4)}.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-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-slate-50\\/60{background-color:rgba(248,250,252,.6)}.bg-sky-blue-400\\/15{background-color:rgba(59,208,242,.15)}.bg-gold-400\\/15{background-color:rgba(255,212,77,.15)}.bg-mint-400\\/15{background-color:rgba(30,226,175,.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}.pr-1{padding-right:.25rem}.pl-4{padding-left:1rem}.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-\\[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);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.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-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-700:hover{--tw-text-opacity:1;color:rgb(51 65 85/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}@media (min-width:640px){.sm\\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:768px){.md\\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}";
44
44
  styleInject(css_248z);
45
45
 
46
46
  function UserButton({ image, name, email }) {
@@ -124,25 +124,25 @@ function LinksGroup({ icon: Icon, href, label, accent = "cyan", initiallyOpened,
124
124
  ), 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));
125
125
  }
126
126
 
127
- var __defProp$h = Object.defineProperty;
128
- var __defProps$e = Object.defineProperties;
129
- var __getOwnPropDescs$e = Object.getOwnPropertyDescriptors;
130
- var __getOwnPropSymbols$h = Object.getOwnPropertySymbols;
131
- var __hasOwnProp$h = Object.prototype.hasOwnProperty;
132
- var __propIsEnum$h = Object.prototype.propertyIsEnumerable;
133
- var __defNormalProp$h = (obj, key, value) => key in obj ? __defProp$h(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
134
- var __spreadValues$h = (a, b) => {
127
+ var __defProp$i = Object.defineProperty;
128
+ var __defProps$f = Object.defineProperties;
129
+ var __getOwnPropDescs$f = Object.getOwnPropertyDescriptors;
130
+ var __getOwnPropSymbols$i = Object.getOwnPropertySymbols;
131
+ var __hasOwnProp$i = Object.prototype.hasOwnProperty;
132
+ var __propIsEnum$i = Object.prototype.propertyIsEnumerable;
133
+ var __defNormalProp$i = (obj, key, value) => key in obj ? __defProp$i(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
134
+ var __spreadValues$i = (a, b) => {
135
135
  for (var prop in b || (b = {}))
136
- if (__hasOwnProp$h.call(b, prop))
137
- __defNormalProp$h(a, prop, b[prop]);
138
- if (__getOwnPropSymbols$h)
139
- for (var prop of __getOwnPropSymbols$h(b)) {
140
- if (__propIsEnum$h.call(b, prop))
141
- __defNormalProp$h(a, prop, b[prop]);
136
+ if (__hasOwnProp$i.call(b, prop))
137
+ __defNormalProp$i(a, prop, b[prop]);
138
+ if (__getOwnPropSymbols$i)
139
+ for (var prop of __getOwnPropSymbols$i(b)) {
140
+ if (__propIsEnum$i.call(b, prop))
141
+ __defNormalProp$i(a, prop, b[prop]);
142
142
  }
143
143
  return a;
144
144
  };
145
- var __spreadProps$e = (a, b) => __defProps$e(a, __getOwnPropDescs$e(b));
145
+ var __spreadProps$f = (a, b) => __defProps$f(a, __getOwnPropDescs$f(b));
146
146
  const data = [
147
147
  { label: "Home", icon: IconHome2, accent: "cyan" },
148
148
  { label: "Dashboard", icon: IconGauge, accent: "mint" },
@@ -169,12 +169,12 @@ function Navbar(props) {
169
169
  }
170
170
  return /* @__PURE__ */ React.createElement(
171
171
  LinksGroup,
172
- __spreadProps$e(__spreadValues$h(__spreadValues$h({
172
+ __spreadProps$f(__spreadValues$i(__spreadValues$i({
173
173
  key: item.label,
174
174
  active: props.active
175
175
  }, item), context), {
176
176
  links: (item.links || []).map((link) => {
177
- return __spreadValues$h(__spreadValues$h({}, link), props.links[`${item.label}/${link.label}`] || { notifications: 0, href: "" });
177
+ return __spreadValues$i(__spreadValues$i({}, link), props.links[`${item.label}/${link.label}`] || { notifications: 0, href: "" });
178
178
  })
179
179
  })
180
180
  );
@@ -194,7 +194,7 @@ const UtilLink = (props) => {
194
194
  );
195
195
  };
196
196
 
197
- const useStyles$9 = createStyles((theme) => ({
197
+ const useStyles$8 = createStyles((theme) => ({
198
198
  inner: {
199
199
  paddingTop: theme.spacing.xl,
200
200
  paddingBottom: theme.spacing.xl * 4
@@ -230,7 +230,7 @@ const useStyles$9 = createStyles((theme) => ({
230
230
  }
231
231
  }));
232
232
  const GettingStarted = (props) => {
233
- const { classes } = useStyles$9();
233
+ const { classes } = useStyles$8();
234
234
  return /* @__PURE__ */ React.createElement(
235
235
  Modal,
236
236
  {
@@ -244,81 +244,10 @@ const GettingStarted = (props) => {
244
244
  );
245
245
  };
246
246
 
247
- const useStyles$8 = createStyles((theme) => ({
248
- title: {
249
- fontSize: 34,
250
- fontWeight: 900,
251
- [theme.fn.smallerThan("sm")]: {
252
- fontSize: 24
253
- }
254
- },
255
- description: {
256
- maxWidth: 600,
257
- margin: "auto",
258
- "&::after": {
259
- content: '""',
260
- display: "block",
261
- backgroundColor: theme.fn.primaryColor(),
262
- width: 45,
263
- height: 2,
264
- marginTop: theme.spacing.sm,
265
- marginLeft: "auto",
266
- marginRight: "auto"
267
- }
268
- },
269
- card: {
270
- transition: "box-shadow 150ms ease, transform 100ms ease",
271
- "&:hover": {
272
- boxShadow: `${theme.shadows.md} !important`,
273
- transform: "scale(1.02)"
274
- }
275
- },
276
- cardTitle: {
277
- "&::after": {
278
- content: '""',
279
- display: "block",
280
- backgroundColor: theme.fn.primaryColor(),
281
- width: 45,
282
- height: 2,
283
- marginTop: theme.spacing.sm
284
- }
285
- }
286
- }));
287
- const SwitchAccount = (props) => {
288
- const { classes, theme } = useStyles$8();
289
- const options = props.accounts.map((a) => {
290
- 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")));
291
- });
292
- return /* @__PURE__ */ React.createElement(
293
- Modal,
294
- {
295
- centered: true,
296
- fullScreen: true,
297
- opened: props.opened,
298
- onClose: () => props.onClose && props.onClose(),
299
- size: "sm"
300
- },
301
- /* @__PURE__ */ React.createElement("div", { style: { position: "relative" } }, props.loading && /* @__PURE__ */ React.createElement(Center, { style: { height: 400 } }, /* @__PURE__ */ React.createElement(Loader, null)), !props.loading && /* @__PURE__ */ React.createElement(ScrollArea.Autosize, { maxHeight: 600 }, /* @__PURE__ */ React.createElement(SimpleGrid, { p: 20, cols: 3, spacing: "xl", breakpoints: [{ maxWidth: "md", cols: 1 }] }, options)))
302
- );
303
- };
304
-
305
- const StatsGroup = ({ data, footer }) => {
306
- const stats = data.map((stat) => {
307
- const value = (() => {
308
- if (stat.unit === "%") {
309
- return Math.round((stat.value + Number.EPSILON) * 100);
310
- }
311
- return stat.value;
312
- })();
313
- const safeValue = Number.isFinite(value) ? value : 0;
314
- return /* @__PURE__ */ React.createElement("div", { key: stat.title }, /* @__PURE__ */ React.createElement("div", { className: "text-3xl font-black text-white" }, safeValue.toLocaleString(), stat.unit), /* @__PURE__ */ React.createElement("div", { className: "mt-1.5 text-[11px] font-bold uppercase tracking-wide text-white/70" }, stat.title));
315
- });
316
- 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);
317
- };
318
-
319
247
  const SIZE = {
320
- sm: { box: "h-11 w-11", rounded: "rounded-xl", icon: 20 },
321
- lg: { box: "h-16 w-16", rounded: "rounded-2xl", icon: 28 }
248
+ sm: { box: "h-14 w-14", rounded: "rounded-xl", icon: 24 },
249
+ lg: { box: "h-16 w-16", rounded: "rounded-2xl", icon: 28 },
250
+ xl: { box: "h-28 w-28", rounded: "rounded-3xl", icon: 48 }
322
251
  };
323
252
  const ACCENT = {
324
253
  cyan: { bg: "bg-sky-blue-400/15", text: "text-sky-blue-400" },
@@ -354,6 +283,8 @@ function Emblem(props) {
354
283
  "svg",
355
284
  {
356
285
  ref,
286
+ role: "img",
287
+ "aria-label": props.alt,
357
288
  "data-cache": "disabled",
358
289
  "data-src": props.imageURL,
359
290
  className: `${s.box} shrink-0 ${s.rounded} object-cover`,
@@ -365,9 +296,53 @@ function Emblem(props) {
365
296
  }
366
297
  );
367
298
  }
368
- 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 }));
299
+ return /* @__PURE__ */ React.createElement("div", { role: "img", "aria-label": props.alt, 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, "aria-hidden": "true" }));
369
300
  }
370
301
 
302
+ const ROLE = {
303
+ admin: { icon: IconBuilding, accent: "gold", label: "Admin" },
304
+ educator: { icon: IconBooks, accent: "mint", label: "Educator" },
305
+ student: { icon: IconBackpack, accent: "cyan", label: "Student" }
306
+ };
307
+ const PILL = {
308
+ cyan: "bg-sky-blue-400/15 text-dark-blue-400",
309
+ mint: "bg-mint-400/15 text-dark-blue-400",
310
+ gold: "bg-gold-400/15 text-dark-blue-400"
311
+ };
312
+ const roleFor = (a) => a.isAdmin ? ROLE.admin : a.isGroupAdmin ? ROLE.educator : ROLE.student;
313
+ const SwitchAccount = (props) => {
314
+ const options = props.accounts.map((a) => {
315
+ const role = roleFor(a);
316
+ return /* @__PURE__ */ React.createElement(
317
+ "button",
318
+ {
319
+ type: "button",
320
+ key: a.accountId,
321
+ onClick: () => props.onClick && props.onClick(a.accountId),
322
+ className: "flex flex-col items-center gap-3 rounded-xl border border-slate-200 bg-white p-6 text-center hover:bg-slate-50"
323
+ },
324
+ /* @__PURE__ */ React.createElement(Emblem, { icon: role.icon, accent: role.accent, size: "lg" }),
325
+ /* @__PURE__ */ React.createElement("span", { className: "text-base font-extrabold text-dark-blue-400" }, a.name),
326
+ /* @__PURE__ */ React.createElement("span", { className: `rounded-full px-2.5 py-1 text-[10px] font-bold ${PILL[role.accent]}` }, role.label)
327
+ );
328
+ });
329
+ return /* @__PURE__ */ React.createElement(Modal, { centered: true, fullScreen: true, title: "Change account", opened: props.opened, onClose: () => props.onClose && props.onClose() }, /* @__PURE__ */ React.createElement("div", { className: "relative" }, props.loading && /* @__PURE__ */ React.createElement("div", { className: "flex h-[400px] items-center justify-center" }, /* @__PURE__ */ React.createElement(Loader, null)), !props.loading && /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-1 gap-4 p-5 sm:grid-cols-2 md:grid-cols-3" }, options)));
330
+ };
331
+
332
+ const StatsGroup = ({ data, footer }) => {
333
+ const stats = data.map((stat) => {
334
+ const value = (() => {
335
+ if (stat.unit === "%") {
336
+ return Math.round((stat.value + Number.EPSILON) * 100);
337
+ }
338
+ return stat.value;
339
+ })();
340
+ const safeValue = Number.isFinite(value) ? value : 0;
341
+ return /* @__PURE__ */ React.createElement("div", { key: stat.title }, /* @__PURE__ */ React.createElement("div", { className: "text-3xl font-black text-white" }, safeValue.toLocaleString(), stat.unit), /* @__PURE__ */ React.createElement("div", { className: "mt-1.5 text-[11px] font-bold uppercase tracking-wide text-white/70" }, stat.title));
342
+ });
343
+ 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);
344
+ };
345
+
371
346
  const SplitButton$4 = (props) => {
372
347
  return /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement(
373
348
  Link,
@@ -454,6 +429,22 @@ const PlaceholderBanner = (props) => {
454
429
  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 }));
455
430
  };
456
431
 
432
+ function SortableHeader(props) {
433
+ const active = props.sortConfig.key === props.sortKey;
434
+ const direction = active ? props.sortConfig.direction : null;
435
+ const justify = props.align === "right" ? "justify-end" : props.align === "center" ? "justify-center" : "";
436
+ return /* @__PURE__ */ React.createElement(
437
+ "button",
438
+ {
439
+ type: "button",
440
+ onClick: () => props.onSort(props.sortKey),
441
+ className: `inline-flex items-center gap-1 text-[10px] font-bold uppercase tracking-wide text-slate-500 hover:text-slate-700 ${justify} ${props.className || ""}`
442
+ },
443
+ /* @__PURE__ */ React.createElement("span", null, props.label),
444
+ active ? direction === "desc" ? /* @__PURE__ */ React.createElement(IconCaretDown, { size: 12, stroke: 2.5, className: "shrink-0 text-sky-blue-400" }) : /* @__PURE__ */ React.createElement(IconCaretUp, { size: 12, stroke: 2.5, className: "shrink-0 text-sky-blue-400" }) : /* @__PURE__ */ React.createElement("span", { className: "flex shrink-0 flex-col -space-y-[3px]" }, /* @__PURE__ */ React.createElement(IconCaretUp, { size: 10, stroke: 2.5 }), /* @__PURE__ */ React.createElement(IconCaretDown, { size: 10, stroke: 2.5 }))
445
+ );
446
+ }
447
+
457
448
  function Stack$4(props) {
458
449
  if (props.items.length === 0) {
459
450
  return null;
@@ -499,29 +490,29 @@ function useSortableData(items, config = { key: "", direction: null }) {
499
490
  return { items: sortedItems, requestSort, sortConfig };
500
491
  }
501
492
 
502
- var __defProp$g = Object.defineProperty;
503
- var __defProps$d = Object.defineProperties;
504
- var __getOwnPropDescs$d = Object.getOwnPropertyDescriptors;
505
- var __getOwnPropSymbols$g = Object.getOwnPropertySymbols;
506
- var __hasOwnProp$g = Object.prototype.hasOwnProperty;
507
- var __propIsEnum$g = Object.prototype.propertyIsEnumerable;
508
- var __defNormalProp$g = (obj, key, value) => key in obj ? __defProp$g(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
509
- var __spreadValues$g = (a, b) => {
493
+ var __defProp$h = Object.defineProperty;
494
+ var __defProps$e = Object.defineProperties;
495
+ var __getOwnPropDescs$e = Object.getOwnPropertyDescriptors;
496
+ var __getOwnPropSymbols$h = Object.getOwnPropertySymbols;
497
+ var __hasOwnProp$h = Object.prototype.hasOwnProperty;
498
+ var __propIsEnum$h = Object.prototype.propertyIsEnumerable;
499
+ var __defNormalProp$h = (obj, key, value) => key in obj ? __defProp$h(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
500
+ var __spreadValues$h = (a, b) => {
510
501
  for (var prop in b || (b = {}))
511
- if (__hasOwnProp$g.call(b, prop))
512
- __defNormalProp$g(a, prop, b[prop]);
513
- if (__getOwnPropSymbols$g)
514
- for (var prop of __getOwnPropSymbols$g(b)) {
515
- if (__propIsEnum$g.call(b, prop))
516
- __defNormalProp$g(a, prop, b[prop]);
502
+ if (__hasOwnProp$h.call(b, prop))
503
+ __defNormalProp$h(a, prop, b[prop]);
504
+ if (__getOwnPropSymbols$h)
505
+ for (var prop of __getOwnPropSymbols$h(b)) {
506
+ if (__propIsEnum$h.call(b, prop))
507
+ __defNormalProp$h(a, prop, b[prop]);
517
508
  }
518
509
  return a;
519
510
  };
520
- var __spreadProps$d = (a, b) => __defProps$d(a, __getOwnPropDescs$d(b));
511
+ var __spreadProps$e = (a, b) => __defProps$e(a, __getOwnPropDescs$e(b));
521
512
  function Table$k(props) {
522
513
  const [expanded, setExpanded] = React.useState({});
523
514
  const preparedItems = React.useMemo(() => {
524
- return props.items.map((item) => __spreadProps$d(__spreadValues$g({}, item), {
515
+ return props.items.map((item) => __spreadProps$e(__spreadValues$h({}, item), {
525
516
  status: item.isComplete ? 1 : 0
526
517
  }));
527
518
  }, [props.items]);
@@ -537,15 +528,14 @@ function Table$k(props) {
537
528
  }
538
529
  );
539
530
  }
540
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
541
- 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) => {
531
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 px-4" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Student Name", sortKey: "name", sortConfig, onSort: requestSort, className: "flex-1" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Status", sortKey: "status", sortConfig, onSort: requestSort, align: "center", className: "w-28 shrink-0" }), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), sortedItems.map((row) => {
542
532
  var _a;
543
533
  const isOpen = !!expanded[row.userId];
544
534
  const initials = (((_a = row.name) == null ? void 0 : _a[0]) || row.email[0] || "?").toUpperCase();
545
535
  return /* @__PURE__ */ React.createElement("div", { key: row.userId, className: "rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement(
546
536
  "div",
547
537
  {
548
- onClick: () => setExpanded(__spreadProps$d(__spreadValues$g({}, expanded), { [row.userId]: !isOpen })),
538
+ onClick: () => setExpanded(__spreadProps$e(__spreadValues$h({}, expanded), { [row.userId]: !isOpen })),
549
539
  className: "flex cursor-pointer items-center gap-4 p-4"
550
540
  },
551
541
  /* @__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))),
@@ -568,8 +558,7 @@ function Table$j(props) {
568
558
  }
569
559
  );
570
560
  }
571
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
572
- 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(
561
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex gap-4 px-4" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Lesson Name", sortKey: "lessonName", sortConfig, onSort: requestSort, className: "flex-1" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Lesson Completion", sortKey: "percentageCompletion", sortConfig, onSort: requestSort, align: "right", className: "w-36 shrink-0" })), sortedItems.map((row) => /* @__PURE__ */ React.createElement(
573
562
  Link,
574
563
  {
575
564
  key: row.lessonId,
@@ -589,7 +578,7 @@ const Badge = (props) => {
589
578
  const [tab, setTab] = useState("lessons");
590
579
  const numberOfStudents = props.students.length;
591
580
  const numberOfBadges = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length : 0;
592
- 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(
581
+ 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: "xl", 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(
593
582
  SplitButton$4,
594
583
  {
595
584
  href: props.href,
@@ -689,8 +678,7 @@ function Table$h(props) {
689
678
  }
690
679
  );
691
680
  }
692
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
693
- 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(
681
+ 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] items-center gap-3 border-b border-slate-100 px-5 py-3" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Student Name", sortKey: "studentName", sortConfig, onSort: requestSort }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Class Name", sortKey: "className", sortConfig, onSort: requestSort })), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
694
682
  "div",
695
683
  {
696
684
  key: row.studentId,
@@ -733,28 +721,28 @@ function relativeTimeFromElapsed(elapsed) {
733
721
  return "";
734
722
  }
735
723
 
736
- var __defProp$f = Object.defineProperty;
737
- var __defProps$c = Object.defineProperties;
738
- var __getOwnPropDescs$c = Object.getOwnPropertyDescriptors;
739
- var __getOwnPropSymbols$f = Object.getOwnPropertySymbols;
740
- var __hasOwnProp$f = Object.prototype.hasOwnProperty;
741
- var __propIsEnum$f = Object.prototype.propertyIsEnumerable;
742
- var __defNormalProp$f = (obj, key, value) => key in obj ? __defProp$f(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
743
- var __spreadValues$f = (a, b) => {
724
+ var __defProp$g = Object.defineProperty;
725
+ var __defProps$d = Object.defineProperties;
726
+ var __getOwnPropDescs$d = Object.getOwnPropertyDescriptors;
727
+ var __getOwnPropSymbols$g = Object.getOwnPropertySymbols;
728
+ var __hasOwnProp$g = Object.prototype.hasOwnProperty;
729
+ var __propIsEnum$g = Object.prototype.propertyIsEnumerable;
730
+ var __defNormalProp$g = (obj, key, value) => key in obj ? __defProp$g(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
731
+ var __spreadValues$g = (a, b) => {
744
732
  for (var prop in b || (b = {}))
745
- if (__hasOwnProp$f.call(b, prop))
746
- __defNormalProp$f(a, prop, b[prop]);
747
- if (__getOwnPropSymbols$f)
748
- for (var prop of __getOwnPropSymbols$f(b)) {
749
- if (__propIsEnum$f.call(b, prop))
750
- __defNormalProp$f(a, prop, b[prop]);
733
+ if (__hasOwnProp$g.call(b, prop))
734
+ __defNormalProp$g(a, prop, b[prop]);
735
+ if (__getOwnPropSymbols$g)
736
+ for (var prop of __getOwnPropSymbols$g(b)) {
737
+ if (__propIsEnum$g.call(b, prop))
738
+ __defNormalProp$g(a, prop, b[prop]);
751
739
  }
752
740
  return a;
753
741
  };
754
- var __spreadProps$c = (a, b) => __defProps$c(a, __getOwnPropDescs$c(b));
742
+ var __spreadProps$d = (a, b) => __defProps$d(a, __getOwnPropDescs$d(b));
755
743
  function Table$g(props) {
756
744
  const preparedItems = React.useMemo(() => {
757
- return props.items.map((item) => __spreadProps$c(__spreadValues$f({}, item), {
745
+ return props.items.map((item) => __spreadProps$d(__spreadValues$g({}, item), {
758
746
  updatedAtDate: new Date(item.updatedAt)
759
747
  }));
760
748
  }, [props.items]);
@@ -770,8 +758,7 @@ function Table$g(props) {
770
758
  }
771
759
  );
772
760
  }
773
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
774
- 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(
761
+ 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] items-center gap-3 border-b border-slate-100 px-5 py-3" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Student Name", sortKey: "studentName", sortConfig, onSort: requestSort }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Lesson Name", sortKey: "lessonName", sortConfig, onSort: requestSort }), /* @__PURE__ */ React.createElement("div", { className: "text-[10.5px] font-extrabold uppercase tracking-wide text-slate-400" }, "Reflection"), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Updated At", sortKey: "updatedAtDate", sortConfig, onSort: requestSort })), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
775
762
  "div",
776
763
  {
777
764
  key: row.studentName + row.lessonName,
@@ -797,8 +784,7 @@ function Table$f(props) {
797
784
  }
798
785
  );
799
786
  }
800
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
801
- 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(
787
+ 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] items-center gap-3 border-b border-slate-100 px-5 py-3" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Student Name", sortKey: "studentName", sortConfig, onSort: requestSort }), /* @__PURE__ */ React.createElement("div", { className: "text-[10.5px] font-extrabold uppercase tracking-wide text-slate-400" }, "Impact Statement")), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
802
788
  "div",
803
789
  {
804
790
  key: row.studentName,
@@ -822,8 +808,7 @@ function Table$e(props) {
822
808
  }
823
809
  );
824
810
  }
825
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
826
- 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(
811
+ 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] items-center gap-3 border-b border-slate-100 px-5 py-3" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Badge Name", sortKey: "name", sortConfig, onSort: requestSort }), /* @__PURE__ */ React.createElement("div", { className: "text-[10.5px] font-extrabold uppercase tracking-wide text-slate-400" }, "Description"), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Completion", sortKey: "percentageCompletion", sortConfig, onSort: requestSort, align: "center" })), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
827
812
  "div",
828
813
  {
829
814
  key: row.badgeId,
@@ -856,8 +841,7 @@ function Table$d(props) {
856
841
  }
857
842
  );
858
843
  }
859
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
860
- 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(
844
+ 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] items-center gap-3 border-b border-slate-100 px-5 py-3" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Lesson Name", sortKey: "name", sortConfig, onSort: requestSort }), /* @__PURE__ */ React.createElement("div", { className: "text-[10.5px] font-extrabold uppercase tracking-wide text-slate-400" }, "Description"), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Completion", sortKey: "percentageCompletion", sortConfig, onSort: requestSort, align: "center" })), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
861
845
  "div",
862
846
  {
863
847
  key: row.lessonId,
@@ -957,25 +941,25 @@ const Dashboard = (props) => {
957
941
  )));
958
942
  };
959
943
 
960
- var __defProp$e = Object.defineProperty;
961
- var __defProps$b = Object.defineProperties;
962
- var __getOwnPropDescs$b = Object.getOwnPropertyDescriptors;
963
- var __getOwnPropSymbols$e = Object.getOwnPropertySymbols;
964
- var __hasOwnProp$e = Object.prototype.hasOwnProperty;
965
- var __propIsEnum$e = Object.prototype.propertyIsEnumerable;
966
- var __defNormalProp$e = (obj, key, value) => key in obj ? __defProp$e(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
967
- var __spreadValues$e = (a, b) => {
944
+ var __defProp$f = Object.defineProperty;
945
+ var __defProps$c = Object.defineProperties;
946
+ var __getOwnPropDescs$c = Object.getOwnPropertyDescriptors;
947
+ var __getOwnPropSymbols$f = Object.getOwnPropertySymbols;
948
+ var __hasOwnProp$f = Object.prototype.hasOwnProperty;
949
+ var __propIsEnum$f = Object.prototype.propertyIsEnumerable;
950
+ var __defNormalProp$f = (obj, key, value) => key in obj ? __defProp$f(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
951
+ var __spreadValues$f = (a, b) => {
968
952
  for (var prop in b || (b = {}))
969
- if (__hasOwnProp$e.call(b, prop))
970
- __defNormalProp$e(a, prop, b[prop]);
971
- if (__getOwnPropSymbols$e)
972
- for (var prop of __getOwnPropSymbols$e(b)) {
973
- if (__propIsEnum$e.call(b, prop))
974
- __defNormalProp$e(a, prop, b[prop]);
953
+ if (__hasOwnProp$f.call(b, prop))
954
+ __defNormalProp$f(a, prop, b[prop]);
955
+ if (__getOwnPropSymbols$f)
956
+ for (var prop of __getOwnPropSymbols$f(b)) {
957
+ if (__propIsEnum$f.call(b, prop))
958
+ __defNormalProp$f(a, prop, b[prop]);
975
959
  }
976
960
  return a;
977
961
  };
978
- var __spreadProps$b = (a, b) => __defProps$b(a, __getOwnPropDescs$b(b));
962
+ var __spreadProps$c = (a, b) => __defProps$c(a, __getOwnPropDescs$c(b));
979
963
  const openDeleteModal$2 = (student, onDelete) => openConfirmModal({
980
964
  title: `Remove "${student.givenName && student.familyName ? `${student.givenName} ${student.familyName}` : student.email}" from this class?`,
981
965
  centered: true,
@@ -986,7 +970,7 @@ const openDeleteModal$2 = (student, onDelete) => openConfirmModal({
986
970
  });
987
971
  function Table$c(props) {
988
972
  const preparedItems = React.useMemo(() => {
989
- return props.items.map((item) => __spreadProps$b(__spreadValues$e({}, item), {
973
+ return props.items.map((item) => __spreadProps$c(__spreadValues$f({}, item), {
990
974
  fullName: item.givenName && item.familyName ? `${item.givenName} ${item.familyName}`.toLowerCase() : item.email.toLowerCase()
991
975
  }));
992
976
  }, [props.items]);
@@ -997,8 +981,7 @@ function Table$c(props) {
997
981
  if (props.items.length === 0) {
998
982
  return /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-slate-200 bg-white p-8 text-center text-sm text-slate-400 shadow-sm" }, "You have not rostered any students yet.");
999
983
  }
1000
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
1001
- return /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-[2.2fr_1.2fr_1fr_1.2fr_1fr_0.6fr] gap-3 border-b border-slate-100 px-5 py-3 text-[10px] font-bold uppercase tracking-wide text-slate-500" }, /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("fullName"), className: "flex items-center text-left hover:text-slate-700" }, "Name", indicator("fullName")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("isAdmin"), className: "flex items-center justify-center text-center hover:text-slate-700" }, "Role", indicator("isAdmin")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("badgesEarned"), className: "flex items-center justify-center text-center hover:text-slate-700" }, "Badges Earned", indicator("badgesEarned")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("lessonsCompleted"), className: "flex items-center justify-center text-center hover:text-slate-700" }, "Lessons Completed", indicator("lessonsCompleted")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("hasAccount"), className: "flex items-center justify-center text-center hover:text-slate-700" }, "Account Created?", indicator("hasAccount")), /* @__PURE__ */ React.createElement("div", null)), sortedItems.map((row, i) => {
984
+ return /* @__PURE__ */ React.createElement("div", { className: "overflow-hidden rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-[2.2fr_1.2fr_1fr_1.2fr_1fr_0.6fr] items-center gap-3 border-b border-slate-100 px-5 py-3" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Name", sortKey: "fullName", sortConfig, onSort: requestSort }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Role", sortKey: "isAdmin", sortConfig, onSort: requestSort, align: "center" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Badges Earned", sortKey: "badgesEarned", sortConfig, onSort: requestSort, align: "center" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Lessons Completed", sortKey: "lessonsCompleted", sortConfig, onSort: requestSort, align: "center" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Account Created?", sortKey: "hasAccount", sortConfig, onSort: requestSort, align: "center" }), /* @__PURE__ */ React.createElement("div", null)), sortedItems.map((row, i) => {
1002
985
  var _a, _b;
1003
986
  const name = row.givenName && row.familyName ? `${row.givenName} ${row.familyName}` : row.email;
1004
987
  const initials = (((_a = row.givenName) == null ? void 0 : _a[0]) || row.email[0] || "?") + (((_b = row.familyName) == null ? void 0 : _b[0]) || "");
@@ -1037,25 +1020,25 @@ function Table$c(props) {
1037
1020
  }));
1038
1021
  }
1039
1022
 
1040
- var __defProp$d = Object.defineProperty;
1041
- var __defProps$a = Object.defineProperties;
1042
- var __getOwnPropDescs$a = Object.getOwnPropertyDescriptors;
1043
- var __getOwnPropSymbols$d = Object.getOwnPropertySymbols;
1044
- var __hasOwnProp$d = Object.prototype.hasOwnProperty;
1045
- var __propIsEnum$d = Object.prototype.propertyIsEnumerable;
1046
- var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1047
- var __spreadValues$d = (a, b) => {
1023
+ var __defProp$e = Object.defineProperty;
1024
+ var __defProps$b = Object.defineProperties;
1025
+ var __getOwnPropDescs$b = Object.getOwnPropertyDescriptors;
1026
+ var __getOwnPropSymbols$e = Object.getOwnPropertySymbols;
1027
+ var __hasOwnProp$e = Object.prototype.hasOwnProperty;
1028
+ var __propIsEnum$e = Object.prototype.propertyIsEnumerable;
1029
+ var __defNormalProp$e = (obj, key, value) => key in obj ? __defProp$e(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1030
+ var __spreadValues$e = (a, b) => {
1048
1031
  for (var prop in b || (b = {}))
1049
- if (__hasOwnProp$d.call(b, prop))
1050
- __defNormalProp$d(a, prop, b[prop]);
1051
- if (__getOwnPropSymbols$d)
1052
- for (var prop of __getOwnPropSymbols$d(b)) {
1053
- if (__propIsEnum$d.call(b, prop))
1054
- __defNormalProp$d(a, prop, b[prop]);
1032
+ if (__hasOwnProp$e.call(b, prop))
1033
+ __defNormalProp$e(a, prop, b[prop]);
1034
+ if (__getOwnPropSymbols$e)
1035
+ for (var prop of __getOwnPropSymbols$e(b)) {
1036
+ if (__propIsEnum$e.call(b, prop))
1037
+ __defNormalProp$e(a, prop, b[prop]);
1055
1038
  }
1056
1039
  return a;
1057
1040
  };
1058
- var __spreadProps$a = (a, b) => __defProps$a(a, __getOwnPropDescs$a(b));
1041
+ var __spreadProps$b = (a, b) => __defProps$b(a, __getOwnPropDescs$b(b));
1059
1042
  const Class = (props) => {
1060
1043
  const [opened, setOpened] = useState(false);
1061
1044
  return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
@@ -1067,7 +1050,7 @@ const Class = (props) => {
1067
1050
  padding: "xl",
1068
1051
  size: "xl"
1069
1052
  },
1070
- /* @__PURE__ */ React.createElement(DropzoneButton$1, __spreadProps$a(__spreadValues$d({}, props), { close: () => setOpened(false) }))
1053
+ /* @__PURE__ */ React.createElement(DropzoneButton$1, __spreadProps$b(__spreadValues$e({}, props), { close: () => setOpened(false) }))
1071
1054
  ), /* @__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(
1072
1055
  "button",
1073
1056
  {
@@ -1193,20 +1176,20 @@ const DropzoneButton$1 = (props) => {
1193
1176
  props.onCreateMembers && props.onCreateMembers([values]);
1194
1177
  }) }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement(
1195
1178
  TextInput,
1196
- __spreadValues$d({
1179
+ __spreadValues$e({
1197
1180
  withAsterisk: true,
1198
1181
  label: "Email",
1199
1182
  placeholder: "Email"
1200
1183
  }, form.getInputProps("email"))
1201
1184
  ), /* @__PURE__ */ React.createElement(Group, { grow: true }, /* @__PURE__ */ React.createElement(
1202
1185
  TextInput,
1203
- __spreadValues$d({
1186
+ __spreadValues$e({
1204
1187
  label: "Given name",
1205
1188
  placeholder: "Given name"
1206
1189
  }, form.getInputProps("givenName"))
1207
1190
  ), /* @__PURE__ */ React.createElement(
1208
1191
  TextInput,
1209
- __spreadValues$d({
1192
+ __spreadValues$e({
1210
1193
  label: "Family name",
1211
1194
  placeholder: "Family name"
1212
1195
  }, form.getInputProps("familyName"))
@@ -1241,8 +1224,7 @@ function Table$b(props) {
1241
1224
  }
1242
1225
  );
1243
1226
  }
1244
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
1245
- 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(
1227
+ 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] items-center gap-3 border-b border-slate-100 px-5 py-3" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Class Name", sortKey: "name", sortConfig, onSort: requestSort }), /* @__PURE__ */ React.createElement("div", { className: "text-[10px] font-bold uppercase tracking-wide text-slate-500" }, "Description"), /* @__PURE__ */ React.createElement(SortableHeader, { label: "# of Students", sortKey: "numberOfStudents", sortConfig, onSort: requestSort, align: "center" }), /* @__PURE__ */ React.createElement("div", null)), sortedItems.map((row, i) => /* @__PURE__ */ React.createElement(
1246
1228
  "div",
1247
1229
  {
1248
1230
  key: row.classId,
@@ -1263,19 +1245,19 @@ function Table$b(props) {
1263
1245
  )));
1264
1246
  }
1265
1247
 
1266
- var __defProp$c = Object.defineProperty;
1267
- var __getOwnPropSymbols$c = Object.getOwnPropertySymbols;
1268
- var __hasOwnProp$c = Object.prototype.hasOwnProperty;
1269
- var __propIsEnum$c = Object.prototype.propertyIsEnumerable;
1270
- var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1271
- var __spreadValues$c = (a, b) => {
1248
+ var __defProp$d = Object.defineProperty;
1249
+ var __getOwnPropSymbols$d = Object.getOwnPropertySymbols;
1250
+ var __hasOwnProp$d = Object.prototype.hasOwnProperty;
1251
+ var __propIsEnum$d = Object.prototype.propertyIsEnumerable;
1252
+ var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1253
+ var __spreadValues$d = (a, b) => {
1272
1254
  for (var prop in b || (b = {}))
1273
- if (__hasOwnProp$c.call(b, prop))
1274
- __defNormalProp$c(a, prop, b[prop]);
1275
- if (__getOwnPropSymbols$c)
1276
- for (var prop of __getOwnPropSymbols$c(b)) {
1277
- if (__propIsEnum$c.call(b, prop))
1278
- __defNormalProp$c(a, prop, b[prop]);
1255
+ if (__hasOwnProp$d.call(b, prop))
1256
+ __defNormalProp$d(a, prop, b[prop]);
1257
+ if (__getOwnPropSymbols$d)
1258
+ for (var prop of __getOwnPropSymbols$d(b)) {
1259
+ if (__propIsEnum$d.call(b, prop))
1260
+ __defNormalProp$d(a, prop, b[prop]);
1279
1261
  }
1280
1262
  return a;
1281
1263
  };
@@ -1309,14 +1291,14 @@ const Classes = (props) => {
1309
1291
  props.onCreateClass && props.onCreateClass(values);
1310
1292
  }) }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement(
1311
1293
  TextInput,
1312
- __spreadValues$c({
1294
+ __spreadValues$d({
1313
1295
  withAsterisk: true,
1314
1296
  label: "Name",
1315
1297
  placeholder: "Class name"
1316
1298
  }, form.getInputProps("name"))
1317
1299
  ), /* @__PURE__ */ React.createElement(
1318
1300
  TextInput,
1319
- __spreadValues$c({
1301
+ __spreadValues$d({
1320
1302
  label: "Description",
1321
1303
  placeholder: "A class for my first period English students"
1322
1304
  }, form.getInputProps("description"))
@@ -1580,8 +1562,7 @@ function Table$7(props) {
1580
1562
  }
1581
1563
  );
1582
1564
  }
1583
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
1584
- 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)))));
1565
+ 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(SortableHeader, { label: "Student Name", sortKey: "studentName", sortConfig, onSort: requestSort, className: "w-40 shrink-0" }), /* @__PURE__ */ React.createElement("div", { className: "flex-1" }, "Reflection"), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Rating", sortKey: "rating", sortConfig, onSort: requestSort, align: "right", className: "w-20 shrink-0" })), 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)))));
1585
1566
  }
1586
1567
 
1587
1568
  const SplitButton$3 = (props) => {
@@ -1620,29 +1601,29 @@ function Stack$3(props) {
1620
1601
  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."))));
1621
1602
  }
1622
1603
 
1623
- var __defProp$b = Object.defineProperty;
1624
- var __defProps$9 = Object.defineProperties;
1625
- var __getOwnPropDescs$9 = Object.getOwnPropertyDescriptors;
1626
- var __getOwnPropSymbols$b = Object.getOwnPropertySymbols;
1627
- var __hasOwnProp$b = Object.prototype.hasOwnProperty;
1628
- var __propIsEnum$b = Object.prototype.propertyIsEnumerable;
1629
- var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1630
- var __spreadValues$b = (a, b) => {
1604
+ var __defProp$c = Object.defineProperty;
1605
+ var __defProps$a = Object.defineProperties;
1606
+ var __getOwnPropDescs$a = Object.getOwnPropertyDescriptors;
1607
+ var __getOwnPropSymbols$c = Object.getOwnPropertySymbols;
1608
+ var __hasOwnProp$c = Object.prototype.hasOwnProperty;
1609
+ var __propIsEnum$c = Object.prototype.propertyIsEnumerable;
1610
+ var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1611
+ var __spreadValues$c = (a, b) => {
1631
1612
  for (var prop in b || (b = {}))
1632
- if (__hasOwnProp$b.call(b, prop))
1633
- __defNormalProp$b(a, prop, b[prop]);
1634
- if (__getOwnPropSymbols$b)
1635
- for (var prop of __getOwnPropSymbols$b(b)) {
1636
- if (__propIsEnum$b.call(b, prop))
1637
- __defNormalProp$b(a, prop, b[prop]);
1613
+ if (__hasOwnProp$c.call(b, prop))
1614
+ __defNormalProp$c(a, prop, b[prop]);
1615
+ if (__getOwnPropSymbols$c)
1616
+ for (var prop of __getOwnPropSymbols$c(b)) {
1617
+ if (__propIsEnum$c.call(b, prop))
1618
+ __defNormalProp$c(a, prop, b[prop]);
1638
1619
  }
1639
1620
  return a;
1640
1621
  };
1641
- var __spreadProps$9 = (a, b) => __defProps$9(a, __getOwnPropDescs$9(b));
1622
+ var __spreadProps$a = (a, b) => __defProps$a(a, __getOwnPropDescs$a(b));
1642
1623
  function Table$6(props) {
1643
1624
  const [expanded, setExpanded] = React.useState({});
1644
1625
  const preparedItems = React.useMemo(() => {
1645
- return props.items.map((item) => __spreadProps$9(__spreadValues$b({}, item), {
1626
+ return props.items.map((item) => __spreadProps$a(__spreadValues$c({}, item), {
1646
1627
  status: item.isComplete ? 2 : item.isStarted ? 1 : 0
1647
1628
  }));
1648
1629
  }, [props.items]);
@@ -1658,15 +1639,14 @@ function Table$6(props) {
1658
1639
  }
1659
1640
  );
1660
1641
  }
1661
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
1662
- 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) => {
1642
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 px-4" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Student Name", sortKey: "name", sortConfig, onSort: requestSort, className: "flex-1" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Status", sortKey: "status", sortConfig, onSort: requestSort, align: "center", className: "w-28 shrink-0" }), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), sortedItems.map((row) => {
1663
1643
  var _a;
1664
1644
  const isOpen = !!expanded[row.userId];
1665
1645
  const initials = (((_a = row.name) == null ? void 0 : _a[0]) || row.email[0] || "?").toUpperCase();
1666
1646
  return /* @__PURE__ */ React.createElement("div", { key: row.userId, className: "rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement(
1667
1647
  "div",
1668
1648
  {
1669
- onClick: () => setExpanded(__spreadProps$9(__spreadValues$b({}, expanded), { [row.userId]: !isOpen })),
1649
+ onClick: () => setExpanded(__spreadProps$a(__spreadValues$c({}, expanded), { [row.userId]: !isOpen })),
1670
1650
  className: "flex cursor-pointer items-center gap-4 p-4"
1671
1651
  },
1672
1652
  /* @__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))),
@@ -1905,6 +1885,25 @@ const SplitButton$2 = (props) => {
1905
1885
  ));
1906
1886
  };
1907
1887
 
1888
+ var __defProp$b = Object.defineProperty;
1889
+ var __defProps$9 = Object.defineProperties;
1890
+ var __getOwnPropDescs$9 = Object.getOwnPropertyDescriptors;
1891
+ var __getOwnPropSymbols$b = Object.getOwnPropertySymbols;
1892
+ var __hasOwnProp$b = Object.prototype.hasOwnProperty;
1893
+ var __propIsEnum$b = Object.prototype.propertyIsEnumerable;
1894
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1895
+ var __spreadValues$b = (a, b) => {
1896
+ for (var prop in b || (b = {}))
1897
+ if (__hasOwnProp$b.call(b, prop))
1898
+ __defNormalProp$b(a, prop, b[prop]);
1899
+ if (__getOwnPropSymbols$b)
1900
+ for (var prop of __getOwnPropSymbols$b(b)) {
1901
+ if (__propIsEnum$b.call(b, prop))
1902
+ __defNormalProp$b(a, prop, b[prop]);
1903
+ }
1904
+ return a;
1905
+ };
1906
+ var __spreadProps$9 = (a, b) => __defProps$9(a, __getOwnPropDescs$9(b));
1908
1907
  const openDeleteModal = (person, onDelete) => openConfirmModal({
1909
1908
  title: `Remove "${person.givenName && person.familyName ? `${person.givenName} ${person.familyName}` : person.email}" from your organization?`,
1910
1909
  centered: true,
@@ -1914,6 +1913,13 @@ const openDeleteModal = (person, onDelete) => openConfirmModal({
1914
1913
  onConfirm: () => onDelete(person)
1915
1914
  });
1916
1915
  function Table$4(props) {
1916
+ const preparedItems = React.useMemo(() => {
1917
+ return props.items.map((item) => __spreadProps$9(__spreadValues$b({}, item), {
1918
+ fullName: item.givenName && item.familyName ? `${item.givenName} ${item.familyName}`.toLowerCase() : item.email.toLowerCase(),
1919
+ roleRank: item.isAdmin ? 2 : item.isGroupAdmin ? 1 : 0
1920
+ }));
1921
+ }, [props.items]);
1922
+ const { items: sortedItems, requestSort, sortConfig } = useSortableData(preparedItems);
1917
1923
  if (props.loading) {
1918
1924
  return /* @__PURE__ */ React.createElement("div", { className: "text-sm text-slate-400" }, "Loading\u2026");
1919
1925
  }
@@ -1928,7 +1934,7 @@ function Table$4(props) {
1928
1934
  }
1929
1935
  );
1930
1936
  }
1931
- 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) => {
1937
+ 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] items-center gap-3 border-b border-slate-100 px-5 py-3" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Name", sortKey: "fullName", sortConfig, onSort: requestSort }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Role", sortKey: "roleRank", sortConfig, onSort: requestSort, align: "center" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Account Created?", sortKey: "hasAccount", sortConfig, onSort: requestSort, align: "center" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "# of Classes", sortKey: "numberOfClasses", sortConfig, onSort: requestSort, align: "center" }), /* @__PURE__ */ React.createElement("div", null)), sortedItems.map((row, i) => {
1932
1938
  var _a, _b;
1933
1939
  const name = row.givenName && row.familyName ? `${row.givenName} ${row.familyName}` : row.email;
1934
1940
  const initials = (((_a = row.givenName) == null ? void 0 : _a[0]) || row.email[0] || "?") + (((_b = row.familyName) == null ? void 0 : _b[0]) || "");
@@ -1937,7 +1943,7 @@ function Table$4(props) {
1937
1943
  "div",
1938
1944
  {
1939
1945
  key: row.email,
1940
- 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" : ""}`
1946
+ className: `grid grid-cols-[2.2fr_1.2fr_1fr_1fr_0.6fr] items-center gap-3 px-5 py-3.5 ${i < sortedItems.length - 1 ? "border-b border-slate-100" : ""}`
1941
1947
  },
1942
1948
  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),
1943
1949
  /* @__PURE__ */ React.createElement("div", { className: "flex justify-center" }, /* @__PURE__ */ React.createElement(
@@ -3037,8 +3043,7 @@ function Table$2(props) {
3037
3043
  }
3038
3044
  );
3039
3045
  }
3040
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
3041
- 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) => {
3046
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 px-4" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Student Name", sortKey: "name", sortConfig, onSort: requestSort, className: "flex-1" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Status", sortKey: "isComplete", sortConfig, onSort: requestSort, align: "center", className: "w-28 shrink-0" }), categories.map((category) => /* @__PURE__ */ React.createElement(SortableHeader, { key: category.categoryId, label: category.name, sortKey: category.categoryId, sortConfig, onSort: requestSort, align: "center", className: "w-24 shrink-0" })), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), sortedItems.map((row) => {
3042
3047
  var _a;
3043
3048
  const isOpen = !!expanded[row.userId];
3044
3049
  const initials = (((_a = row.name) == null ? void 0 : _a[0]) || row.email[0] || "?").toUpperCase();
@@ -3059,8 +3064,10 @@ function Table$2(props) {
3059
3064
  }));
3060
3065
  }
3061
3066
 
3067
+ const OTHER_FILTER = "__other__";
3062
3068
  function Table$1(props) {
3063
3069
  const { items: sortedBadges, requestSort, sortConfig } = useSortableData(props.badges);
3070
+ const [categoryFilter, setCategoryFilter] = React.useState("");
3064
3071
  if (props.badges.length === 0) {
3065
3072
  return /* @__PURE__ */ React.createElement(
3066
3073
  PlaceholderBanner,
@@ -3072,29 +3079,44 @@ function Table$1(props) {
3072
3079
  }
3073
3080
  );
3074
3081
  }
3075
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
3076
3082
  const groupedIds = new Set(props.categories.map((c) => c.categoryId));
3077
- const forCategory = (categoryId) => sortedBadges.filter((b) => {
3078
- var _a;
3079
- return (_a = b.categories) == null ? void 0 : _a.includes(categoryId);
3080
- });
3081
3083
  const other = sortedBadges.filter((b) => {
3082
3084
  var _a;
3083
3085
  return !((_a = b.categories) == null ? void 0 : _a.some((id) => groupedIds.has(id)));
3084
3086
  });
3085
- return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-6" }, /* @__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("weight"), className: "w-24 shrink-0 text-right hover:text-slate-600" }, "Point Value", indicator("weight")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("percentageCompletion"), className: "w-36 shrink-0 text-right hover:text-slate-600" }, "Badge Completion", indicator("percentageCompletion"))), props.categories.map((category) => /* @__PURE__ */ React.createElement(CategorySection, { key: category.categoryId, name: category.name, badges: forCategory(category.categoryId) })), other.length > 0 && /* @__PURE__ */ React.createElement(CategorySection, { name: "Other badges", badges: other }));
3087
+ const visibleBadges = !categoryFilter ? sortedBadges : categoryFilter === OTHER_FILTER ? other : sortedBadges.filter((b) => {
3088
+ var _a;
3089
+ return (_a = b.categories) == null ? void 0 : _a.includes(categoryFilter);
3090
+ });
3091
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-4" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap gap-2" }, /* @__PURE__ */ React.createElement(CategoryPill, { label: "All", active: !categoryFilter, onClick: () => setCategoryFilter("") }), props.categories.map((category) => /* @__PURE__ */ React.createElement(
3092
+ CategoryPill,
3093
+ {
3094
+ key: category.categoryId,
3095
+ label: category.name,
3096
+ active: categoryFilter === category.categoryId,
3097
+ onClick: () => setCategoryFilter(category.categoryId)
3098
+ }
3099
+ )), other.length > 0 && /* @__PURE__ */ React.createElement(CategoryPill, { label: "Other", active: categoryFilter === OTHER_FILTER, onClick: () => setCategoryFilter(OTHER_FILTER) })), /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex gap-4 px-4" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Badge Name", sortKey: "badgeName", sortConfig, onSort: requestSort, className: "flex-1" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Point Value", sortKey: "weight", sortConfig, onSort: requestSort, align: "right", className: "w-24 shrink-0" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Badge Completion", sortKey: "percentageCompletion", sortConfig, onSort: requestSort, align: "right", className: "w-36 shrink-0" })), visibleBadges.length === 0 && /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-dashed border-slate-200 px-4 py-3 text-xs text-slate-400" }, categoryFilter ? "No badges in this category yet." : "No badges yet."), visibleBadges.map((row) => /* @__PURE__ */ React.createElement(
3100
+ Link,
3101
+ {
3102
+ key: row.badgeId,
3103
+ to: row.href,
3104
+ className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
3105
+ },
3106
+ /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1 text-sm font-bold text-dark-blue-400" }, row.badgeName),
3107
+ /* @__PURE__ */ React.createElement("div", { className: "w-24 shrink-0 text-right text-xs font-black text-mint-400" }, row.weight, " pts"),
3108
+ /* @__PURE__ */ React.createElement("div", { className: "w-36 shrink-0 text-right text-xs text-slate-500" }, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")
3109
+ ))));
3086
3110
  }
3087
- const CategorySection = (props) => /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2" }, /* @__PURE__ */ React.createElement("div", { className: "px-1 text-sm font-extrabold tracking-tight text-dark-blue-400" }, props.name), props.badges.length === 0 && /* @__PURE__ */ React.createElement("div", { className: "rounded-xl border border-dashed border-slate-200 px-4 py-3 text-xs text-slate-400" }, "No badges yet."), props.badges.map((row) => /* @__PURE__ */ React.createElement(
3088
- Link,
3111
+ const CategoryPill = (props) => /* @__PURE__ */ React.createElement(
3112
+ "button",
3089
3113
  {
3090
- key: row.badgeId,
3091
- to: row.href,
3092
- className: "flex items-center gap-4 rounded-xl border border-slate-200 bg-white p-4 no-underline shadow-sm hover:bg-slate-50"
3114
+ type: "button",
3115
+ onClick: props.onClick,
3116
+ className: `rounded-full border px-3.5 py-1.5 text-xs font-bold ${props.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"}`
3093
3117
  },
3094
- /* @__PURE__ */ React.createElement("div", { className: "min-w-0 flex-1 text-sm font-bold text-dark-blue-400" }, row.badgeName),
3095
- /* @__PURE__ */ React.createElement("div", { className: "w-24 shrink-0 text-right text-xs font-black text-mint-400" }, row.weight, " pts"),
3096
- /* @__PURE__ */ React.createElement("div", { className: "w-36 shrink-0 text-right text-xs text-slate-500" }, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")
3097
- )));
3118
+ props.label
3119
+ );
3098
3120
 
3099
3121
  var __defProp$3 = Object.defineProperty;
3100
3122
  var __defProps$3 = Object.defineProperties;
@@ -3174,7 +3196,7 @@ const Pathway = (props) => {
3174
3196
  (props.allCategories || []).filter((c) => !c.parentCategoryId).map((c) => c.categoryId)
3175
3197
  );
3176
3198
  const badgeGroupCategories = criteriaCategories.filter((c) => !rootCategoryIds.has(c.categoryId));
3177
- 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 || !!((_b = props.allCategories) == null ? void 0 : _b.length)) && /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-1.5 pt-0.5" }, criteriaCategories.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__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"))), !!((_c = props.allCategories) == null ? void 0 : _c.length) && /* @__PURE__ */ React.createElement(
3199
+ 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: "xl", 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 || !!((_b = props.allCategories) == null ? void 0 : _b.length)) && /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-1.5 pt-0.5" }, criteriaCategories.length > 0 && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__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"))), !!((_c = props.allCategories) == null ? void 0 : _c.length) && /* @__PURE__ */ React.createElement(
3178
3200
  "button",
3179
3201
  {
3180
3202
  onClick: () => setCategoriesOpen(true),
@@ -3316,8 +3338,7 @@ function Table(props) {
3316
3338
  }
3317
3339
  );
3318
3340
  }
3319
- const indicator = (key) => sortConfig.key !== key ? "" : sortConfig.direction === "desc" ? " \u25BE" : " \u25B4";
3320
- return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 px-4 text-[10.5px] font-extrabold uppercase tracking-wide text-slate-400" }, /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("name"), className: "flex-1 text-left hover:text-slate-600" }, "Student Name", indicator("name")), /* @__PURE__ */ React.createElement("button", { onClick: () => requestSort("submissionCount"), className: "w-16 shrink-0 text-left hover:text-slate-600" }, "Files", indicator("submissionCount")), props.onReview && /* @__PURE__ */ React.createElement("div", { className: "w-36 shrink-0" }), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), sortedItems.map((row) => {
3341
+ return /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-4 px-4" }, /* @__PURE__ */ React.createElement(SortableHeader, { label: "Student Name", sortKey: "name", sortConfig, onSort: requestSort, className: "flex-1" }), /* @__PURE__ */ React.createElement(SortableHeader, { label: "Files", sortKey: "submissionCount", sortConfig, onSort: requestSort, className: "w-16 shrink-0" }), props.onReview && /* @__PURE__ */ React.createElement("div", { className: "w-36 shrink-0" }), /* @__PURE__ */ React.createElement("div", { className: "w-4 shrink-0" })), sortedItems.map((row) => {
3321
3342
  const isOpen = !!expanded[row.userId];
3322
3343
  return /* @__PURE__ */ React.createElement("div", { key: row.userId, className: "rounded-xl border border-slate-200 bg-white shadow-sm" }, /* @__PURE__ */ React.createElement(
3323
3344
  "div",