@local-civics/mgmt-ui 0.1.50 → 0.1.52

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.
Files changed (61) hide show
  1. package/dist/index.d.ts +486 -12
  2. package/dist/index.js +1742 -1
  3. package/dist/index.js.map +1 -0
  4. package/dist/index.mjs +1702 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/package.json +5 -3
  7. package/dist/components/banners/PlaceholderBanner/PlaceholderBanner.d.ts +0 -14
  8. package/dist/components/banners/PlaceholderBanner/component.stories.d.ts +0 -14
  9. package/dist/components/banners/TenantBanner/TenantBanner.d.ts +0 -23
  10. package/dist/components/cards/CardGradient.d.ts +0 -10
  11. package/dist/components/cards/component.stories.d.ts +0 -14
  12. package/dist/components/data/LineChart/LineChart.d.ts +0 -18
  13. package/dist/components/data/StatsGrid/StatsGrid.d.ts +0 -14
  14. package/dist/components/data/StatsGroup/StatsGroup.d.ts +0 -14
  15. package/dist/components/navigation/Navbar/Navbar.d.ts +0 -15
  16. package/dist/components/navigation/Navbar/component.stories.d.ts +0 -14
  17. package/dist/components/navigation/Tabs/Tabs.d.ts +0 -18
  18. package/dist/components/users/UserInfo/UserInfo.d.ts +0 -11
  19. package/dist/hooks/notifications.d.ts +0 -1
  20. package/dist/index.es.js +0 -1
  21. package/dist/pages/Badge/Badge.d.ts +0 -37
  22. package/dist/pages/Badge/LessonTable.d.ts +0 -31
  23. package/dist/pages/Badge/Table.d.ts +0 -33
  24. package/dist/pages/Badge/component.stories.d.ts +0 -18
  25. package/dist/pages/Badges/Badges.d.ts +0 -20
  26. package/dist/pages/Badges/Table.d.ts +0 -31
  27. package/dist/pages/Badges/component.stories.d.ts +0 -14
  28. package/dist/pages/Class/Class.d.ts +0 -27
  29. package/dist/pages/Class/Table.d.ts +0 -31
  30. package/dist/pages/Class/component.stories.d.ts +0 -18
  31. package/dist/pages/Classes/Classes.d.ts +0 -21
  32. package/dist/pages/Classes/Table.d.ts +0 -23
  33. package/dist/pages/Classes/component.stories.d.ts +0 -18
  34. package/dist/pages/Dashboard/BadgeTable.d.ts +0 -32
  35. package/dist/pages/Dashboard/Dashboard.d.ts +0 -38
  36. package/dist/pages/Dashboard/ImpactTable.d.ts +0 -28
  37. package/dist/pages/Dashboard/LessonTable.d.ts +0 -32
  38. package/dist/pages/Dashboard/ReflectionTable.d.ts +0 -30
  39. package/dist/pages/Dashboard/StudentTable.d.ts +0 -31
  40. package/dist/pages/Dashboard/component.stories.d.ts +0 -18
  41. package/dist/pages/Home/Home.d.ts +0 -25
  42. package/dist/pages/Home/component.stories.d.ts +0 -14
  43. package/dist/pages/Lesson/Lesson.d.ts +0 -38
  44. package/dist/pages/Lesson/QuestionStack.d.ts +0 -30
  45. package/dist/pages/Lesson/ReflectionTable.d.ts +0 -29
  46. package/dist/pages/Lesson/Table.d.ts +0 -25
  47. package/dist/pages/Lesson/component.stories.d.ts +0 -18
  48. package/dist/pages/Lessons/Lessons.d.ts +0 -20
  49. package/dist/pages/Lessons/Table.d.ts +0 -22
  50. package/dist/pages/Lessons/component.stories.d.ts +0 -14
  51. package/dist/pages/Student/AnswerTable.d.ts +0 -32
  52. package/dist/pages/Student/BadgeTable.d.ts +0 -31
  53. package/dist/pages/Student/ReflectionTable.d.ts +0 -32
  54. package/dist/pages/Student/Student.d.ts +0 -21
  55. package/dist/pages/Student/component.stories.d.ts +0 -18
  56. package/dist/providers/AdminProvider/AdminProvider.d.ts +0 -14
  57. package/dist/shells/App/App.d.ts +0 -21
  58. package/dist/shells/App/SwitchAccount/SwitchAccount.d.ts +0 -23
  59. package/dist/shells/App/SwitchAccount/component.stories.d.ts +0 -14
  60. package/dist/shells/App/component.stories.d.ts +0 -14
  61. package/dist/utils/time.d.ts +0 -11
package/dist/index.js CHANGED
@@ -1 +1,1742 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("@mantine/notifications"),require("react/jsx-runtime"),require("@tabler/icons"),require("react"),require("@mantine/core"),require("@mantine/dropzone"),require("@mantine/form"),require("papaparse"),require("@mantine/modals"),require("react-charts")):"function"==typeof define&&define.amd?define(["exports","@mantine/notifications","react/jsx-runtime","@tabler/icons","react","@mantine/core","@mantine/dropzone","@mantine/form","papaparse","@mantine/modals","react-charts"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).components={},e.MantineNotifications,e.ReactJSXRuntime,e.TablerIcons,e.React,e.MantineCore,e.MantineDropzone,e.MantineForm,e.Papaparse,e.MantineModals,e.ReactCharts)}(this,(function(e,n,t,i,s,r,o,l,a,c,d){"use strict";function h(e){if(e&&e.__esModule)return e;var n=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var i=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,i.get?i:{enumerable:!0,get:function(){return e[t]}})}})),n.default=e,Object.freeze(n)}var u=h(s),m=h(a),x=function(){return x=Object.assign||function(e){for(var n,t=1,i=arguments.length;t<i;t++)for(var s in n=arguments[t])Object.prototype.hasOwnProperty.call(n,s)&&(e[s]=n[s]);return e},x.apply(this,arguments)};var g=r.createStyles((function(e){var n,t;return{root:(n={display:"flex",backgroundImage:"linear-gradient(-60deg, ".concat(e.colors[e.primaryColor][4]," 0%, ").concat(e.colors[e.primaryColor][7]," 100%)"),padding:1.5*e.spacing.xl,borderRadius:e.radius.md},n[e.fn.smallerThan("sm")]={flexDirection:"column"},n),title:{color:e.white,textTransform:"uppercase",fontWeight:700,fontSize:e.fontSizes.sm},count:{color:e.white,fontSize:32,lineHeight:1,fontWeight:700,marginBottom:e.spacing.md,fontFamily:"Greycliff CF, ".concat(e.fontFamily)},description:{color:e.colors[e.primaryColor][0],fontSize:e.fontSizes.sm,marginTop:5},stat:{flex:1,"& + &":(t={paddingLeft:e.spacing.xl,marginLeft:e.spacing.xl,borderLeft:"1px solid ".concat(e.colors[e.primaryColor][3])},t[e.fn.smallerThan("sm")]={paddingLeft:0,marginLeft:0,borderLeft:0,paddingTop:e.spacing.xl,marginTop:e.spacing.xl,borderTop:"1px solid ".concat(e.colors[e.primaryColor][3])},t)}}})),p=function(e){var n=e.data,i=g().classes,s=n.map((function(e){var n="%"===e.unit?Math.round(100*(e.value+Number.EPSILON)):e.value;return t.jsxs("div",x({className:i.stat},{children:[t.jsxs(r.Text,x({className:i.count},{children:[n.toLocaleString(),e.unit]})),t.jsx(r.Text,x({className:i.title},{children:e.title}))]}),e.title)}));return t.jsx("div",x({className:i.root},{children:s}))},j=function(e){var n,i=null===(n=e.data)||void 0===n?void 0:n.map((function(e){return t.jsx(r.Tabs.Tab,x({value:e.value},{children:e.label||e.value}),e.value)}));return t.jsx(r.Tabs,x({value:e.value,onTabChange:e.onChange},{children:t.jsx(r.Tabs.List,{children:i})}))},f=r.createStyles((function(e){var n,t,i;return{wrapper:(n={display:"flex",alignItems:"center",padding:2*e.spacing.xl,borderRadius:e.radius.md,backgroundColor:"dark"===e.colorScheme?e.colors.dark[8]:e.white,border:"1px solid ".concat("dark"===e.colorScheme?e.colors.dark[8]:e.colors.gray[3])},n["@media (max-width: ".concat(e.breakpoints.sm,"px)")]={flexDirection:"column-reverse",padding:e.spacing.xl},n),image:(t={maxWidth:"40%"},t["@media (max-width: ".concat(e.breakpoints.sm,"px)")]={maxWidth:"100%"},t),body:(i={paddingRight:4*e.spacing.xl},i["@media (max-width: ".concat(e.breakpoints.sm,"px)")]={paddingRight:0,marginTop:e.spacing.xl},i),title:{color:"dark"===e.colorScheme?e.white:e.black,fontFamily:"Greycliff CF, ".concat(e.fontFamily),lineHeight:1,marginBottom:e.spacing.md},controls:{display:"flex",marginTop:e.spacing.xl},inputWrapper:{width:"100%",flex:"1"},input:{borderTopRightRadius:0,borderBottomRightRadius:0,borderRight:0},control:{borderTopLeftRadius:0,borderBottomLeftRadius:0}}})),v=function(e){var n=f().classes,i=e.title||"Nothing to display",s=e.description||"We don't have anything to show you here just yet. Add data, check back later, or adjust your search.";return t.jsxs("div",x({className:n.wrapper},{children:[t.jsxs("div",x({className:n.body},{children:[t.jsx(r.Title,x({className:n.title},{children:e.loading?"Loading...":i})),t.jsx(r.Text,x({size:"sm",color:"dimmed"},{children:e.loading?"Hold on, we're loading your data.":s}))]})),t.jsx(r.Image,{src:"https://cdn.localcivics.io/illustrations/".concat(e.icon,".svg"),className:n.image})]}))};function b(e){if(0===e.items.length)return t.jsx(v,{title:"No badges to display",description:"There has not been any badge progress just yet.",loading:e.loading,icon:"badges"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onClick&&e.onClick(n)}},{children:t.jsxs(r.Group,x({spacing:"sm"},{children:[t.jsx(r.Avatar,{size:40,src:n.avatar,radius:40}),t.jsxs("div",{children:[t.jsx(r.Text,x({size:"sm",weight:500},{children:n.name})),t.jsx(r.Text,x({size:"xs",color:"dimmed"},{children:n.email}))]})]}))}))}),t.jsxs("td",{children:[!!n.isComplete&&t.jsx(r.Badge,x({variant:"filled"},{children:"Complete"})),!n.isComplete&&t.jsx(r.Badge,x({color:"red",variant:"filled"},{children:"Incomplete"}))]})]},n.name)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Student Name"}),t.jsx("th",{children:"Badge Status"})]})}),t.jsx("tbody",{children:n})]}))}))}function y(e){if(0===e.items.length)return t.jsx(v,{title:"No lessons to display",description:"There are not lessons in badge.",loading:e.loading,icon:"badges"});var n=e.items.map((function(n){var i=Math.round(100*(n.percentageCompletion+Number.EPSILON));return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onClick&&e.onClick(n)}},{children:n.lessonName}))}),t.jsxs("td",{children:[i,"%"]})]},n.lessonName)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Lesson Name"}),t.jsx("th",{children:"Lesson Completion"})]})}),t.jsx("tbody",{children:n})]}))}))}var C=r.createStyles((function(e){var n;return{title:(n={fontSize:34,fontWeight:900},n[e.fn.smallerThan("sm")]={fontSize:24},n),description:{maxWidth:600}}}));function S(e){if(0===e.items.length)return t.jsx(v,{title:"No badges to display",description:"We don't have any badges to show you just yet.",loading:e.loading,icon:"badges"});var n=e.items.map((function(n){return t.jsx("tr",{children:t.jsx("td",{children:t.jsx(r.UnstyledButton,x({sx:function(e){return{display:"block",width:"100%",padding:e.spacing.md,color:"dark"===e.colorScheme?e.colors.dark[0]:e.black,"&:hover":{backgroundColor:"dark"===e.colorScheme?e.colors.dark[8]:e.colors.gray[1]}}},onClick:function(){return e.onClick&&e.onClick(n)}},{children:t.jsx(r.Group,{children:t.jsxs("div",{children:[t.jsx(r.Text,x({size:"sm",weight:500},{children:n.name})),t.jsx(r.Text,x({size:"xs",color:"dimmed"},{children:n.description}))]})})}))})},n.badgeId)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsx(r.Table,x({horizontalSpacing:0,verticalSpacing:0,sx:{minWidth:700}},{children:t.jsx("tbody",{children:n})}))}))}var k=r.createStyles((function(e){var n;return{title:(n={fontSize:34,fontWeight:900},n[e.fn.smallerThan("sm")]={fontSize:24},n),description:{maxWidth:600}}}));function N(e){if(0===e.items.length)return t.jsx(v,{title:"No students to display",description:"You don't have any students yet, add them and revisit.",loading:e.loading,icon:"groups"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onViewProfile(n)}},{children:n.studentName}))}),t.jsx("td",{children:n.className})]},n.studentName)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Student Name"}),t.jsx("th",{children:"Class Name"})]})}),t.jsx("tbody",{children:n})]}))}))}var T=[{unit:"year",ms:31536e6},{unit:"month",ms:2628e6},{unit:"day",ms:864e5},{unit:"hour",ms:36e5},{unit:"minute",ms:6e4},{unit:"second",ms:1e3}],z=new Intl.RelativeTimeFormat("en",{numeric:"auto"});function w(e,n){return void 0===n&&(n=new Date),e?function(e){for(var n=0,t=T;n<t.length;n++){var i=t[n],s=i.unit,r=i.ms;if(Math.abs(e)>=r||"second"===s)return z.format(Math.round(e/r),s)}return""}(e.getTime()-n.getTime()):""}function I(e){if(0===e.items.length)return t.jsx(v,{title:"No reflections to display",description:"There has not been any lesson progress just yet.",loading:e.loading,icon:"lessons"});var n=e.items.map((function(e){return t.jsxs("tr",{children:[t.jsx("td",{children:e.studentName}),t.jsx("td",{children:e.lessonName}),t.jsx("td",{children:e.reflection}),t.jsx("td",{children:w(new Date(e.updatedAt))})]},e.studentName+e.lessonName)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Student Name"}),t.jsx("th",{children:"Lesson Name"}),t.jsx("th",{children:"Reflection"}),t.jsx("th",{children:"Updated At"})]})}),t.jsx("tbody",{children:n})]}))}))}function A(e){if(0===e.items.length)return t.jsx(v,{title:"No impact statements to display",description:"There are no students with impact statements yet.",loading:e.loading,icon:"kindergarten"});var n=e.items.map((function(e){return t.jsxs("tr",{children:[t.jsx("td",{children:e.studentName}),t.jsx("td",{children:e.impactStatement})]},e.studentName)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Student Name"}),t.jsx("th",{children:"Impact Statement"})]})}),t.jsx("tbody",{children:n})]}))}))}function B(e){if(0===e.items.length)return t.jsx(v,{title:"No badges to display",description:"We don't have any badges to show you just yet.",loading:e.loading,icon:"badges"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onClick&&e.onClick(n)}},{children:n.name}))}),t.jsx("td",{children:n.description}),t.jsxs("td",{children:[Math.round(100*(n.percentageCompletion+Number.EPSILON)),"%"]})]},n.badgeId)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Badge Name"}),t.jsx("th",{children:"Description"}),t.jsx("th",{children:"Completion"})]})}),t.jsx("tbody",{children:n})]}))}))}function O(e){if(0===e.items.length)return t.jsx(v,{title:"No lessons to display",description:"We don't have any lessons to show you just yet.",loading:e.loading,icon:"lessons"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onClick&&e.onClick(n)}},{children:n.name}))}),t.jsx("td",{children:n.description}),t.jsxs("td",{children:[Math.round(100*(n.percentageCompletion+Number.EPSILON)),"%"]})]},n.lessonId)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Lesson Name"}),t.jsx("th",{children:"Description"}),t.jsx("th",{children:"Completion"})]})}),t.jsx("tbody",{children:n})]}))}))}function L(e){if(0===e.items.length)return t.jsx(v,{title:"No students to display",description:"You have not rostered any students yet.",loading:e.loading,icon:"groups"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onViewProfile&&e.onViewProfile(n)}},{children:t.jsxs(r.Group,x({spacing:"sm"},{children:[t.jsx(r.Avatar,{size:40,src:n.avatar,radius:40}),t.jsxs("div",{children:[t.jsx(r.Text,x({size:"sm",weight:500},{children:n.givenName&&n.familyName?"".concat(n.givenName," ").concat(n.familyName):n.email})),t.jsx(r.Text,x({size:"xs",color:"dimmed"},{children:n.email}))]})]}))}))}),t.jsx("td",{children:n.badgesEarned}),t.jsx("td",{children:n.lessonsCompleted}),t.jsx("td",{children:n.hasAccount&&t.jsx(i.IconCheck,{color:"green"})}),t.jsx("td",{children:n.lastActivity?w(n.lastActivity):""}),t.jsx("td",{children:t.jsx(r.Group,x({noWrap:!0,spacing:0,position:"right"},{children:!n.readonly&&!!e.onDelete&&t.jsx(r.ActionIcon,x({color:"red"},{children:t.jsx(i.IconTrash,{onClick:function(){return i=n,c.openConfirmModal({title:'Delete "'.concat(i.givenName&&i.familyName?"".concat(i.givenName," ").concat(i.familyName):i.email,'"?'),centered:!0,children:t.jsx(r.Text,x({size:"sm"},{children:"Are you sure you want to delete this person? This action is destructive and you will have to contact support to restore your data."})),labels:{confirm:"Delete",cancel:"No don't delete them"},confirmProps:{color:"red"},onConfirm:function(){return e.onDelete&&e.onDelete(i)}});var i},size:16,stroke:1.5})}))}))})]},n.email)}));return t.jsx(r.ScrollArea,{children:t.jsxs(r.Table,x({verticalSpacing:20,sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Student Name"}),t.jsx("th",{children:"Badges Earned"}),t.jsx("th",{children:"Lessons Completed"}),t.jsx("th",{children:"Account Created?"}),t.jsx("th",{children:"Last Active"}),t.jsx("th",{})]})}),t.jsx("tbody",{children:n})]}))})}var P=r.createStyles((function(e){var n;return{title:(n={fontSize:34,fontWeight:900},n[e.fn.smallerThan("sm")]={fontSize:24},n),description:{maxWidth:600},wrapper:{position:"relative",marginBottom:30},dropzone:{borderWidth:1,paddingBottom:50},icon:{color:"dark"===e.colorScheme?e.colors.dark[3]:e.colors.gray[4]},control:{position:"absolute",width:250,left:"calc(50% - 125px)",bottom:-20}}})),D=function(e){var n=P(),s=n.classes,l=n.theme,a=u.useRef(null),c=u.useState(!1),d=c[0],h=c[1],g=u.useCallback((function(n){h(!0),n.forEach((function(n){m.parse(n,{download:!0,header:!0,dynamicTyping:!0,skipEmptyLines:!0,worker:!0,complete:function(n){var t=n.data.filter((function(n){return/^\S+@\S+$/.test(n.email)&&0===e.students.filter((function(e){return e.email===n.email})).length}));t.length>0&&e.onCreateStudents&&e.onCreateStudents(t),h(!1),e.close()}})}))}),[]);return t.jsxs("div",x({className:s.wrapper},{children:[t.jsx(o.Dropzone,x({loading:d,openRef:a,onDrop:g,className:s.dropzone,radius:"md",accept:[o.MIME_TYPES.csv],maxSize:5*Math.pow(1024,2)},{children:t.jsxs("div",x({style:{pointerEvents:"none"}},{children:[t.jsxs(r.Group,x({position:"center"},{children:[t.jsx(o.Dropzone.Accept,{children:t.jsx(i.IconDownload,{size:50,color:l.colors[l.primaryColor][6],stroke:1.5})}),t.jsx(o.Dropzone.Reject,{children:t.jsx(i.IconX,{size:50,color:l.colors.red[6],stroke:1.5})}),t.jsx(o.Dropzone.Idle,{children:t.jsx(i.IconCloudUpload,{size:50,color:"dark"===l.colorScheme?l.colors.dark[0]:l.black,stroke:1.5})})]})),t.jsxs(r.Text,x({align:"center",weight:700,size:"lg",mt:"xl"},{children:[t.jsx(o.Dropzone.Accept,{children:"Drop files here"}),t.jsx(o.Dropzone.Reject,{children:"Csv file less than 5mb"}),t.jsx(o.Dropzone.Idle,{children:"Upload multiple"})]})),t.jsxs(r.Text,x({align:"center",size:"sm",mt:"xs",color:"dimmed"},{children:["Drag'n'drop files here to upload. We can accept only ",t.jsx("i",{children:".csv"})," files that are less than 5mb in size."]}))]}))})),t.jsx(r.Button,x({className:s.control,size:"md",radius:"xl",onClick:function(){var e;return null===(e=a.current)||void 0===e?void 0:e.call(a)}},{children:"Select file"}))]}))};function W(e){if(0===e.items.length)return t.jsx(v,{title:"No classes to display",description:"You don't have any classes yet. Try creating one first...",loading:e.loading,icon:"groups"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onClick(n)}},{children:t.jsx(r.Text,x({size:14},{children:n.name}))}))}),t.jsx("td",{children:t.jsx(r.Text,x({size:14},{children:n.description}))}),t.jsx("td",{children:t.jsx(r.Group,x({noWrap:!0,spacing:0,position:"right"},{children:t.jsx(r.ActionIcon,x({color:"red"},{children:t.jsx(i.IconTrash,{onClick:function(){return i=n,c.openConfirmModal({title:'Delete "'.concat(i.name,'"?'),centered:!0,children:t.jsx(r.Text,x({size:"sm"},{children:"Are you sure you want to delete this class? This action is destructive and you will have to contact support to restore your data."})),labels:{confirm:"Delete class",cancel:"No don't delete it"},confirmProps:{color:"red"},onConfirm:function(){return e.onDeleteClass(i)}});var i},size:16,stroke:1.5})}))}))})]},n.classId)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:300},{children:t.jsxs(r.Table,x({verticalSpacing:20,sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Class Name"}),t.jsx("th",{children:"Description"}),t.jsx("th",{})]})}),t.jsx("tbody",{children:n})]}))}))}var G=r.createStyles((function(e){var n;return{title:(n={fontSize:34,fontWeight:900},n[e.fn.smallerThan("sm")]={fontSize:24},n),description:{maxWidth:600}}})),E=r.createStyles((function(e){var n;return{title:(n={fontSize:34,fontWeight:900,marginTop:16},n[e.fn.smallerThan("sm")]={fontSize:24},n),description:{maxWidth:600}}})),M=function(e){var n=E().classes;return t.jsxs(t.Fragment,{children:[t.jsx(r.Title,x({className:n.title},{children:e.name})),t.jsx(r.Text,x({color:"dimmed",className:n.description,mt:"xs"},{children:e.impactStatement}))]})};function H(e){if(0===e.items.length)return t.jsx(v,{title:"No badges to display",description:"There has not been any badge progress just yet.",loading:e.loading,icon:"badges"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onClick(n)}},{children:n.badgeName}))}),t.jsxs("td",{children:[!!n.isComplete&&t.jsx(r.Badge,x({variant:"filled"},{children:"Complete"})),!n.isComplete&&t.jsx(r.Badge,x({color:"red",variant:"filled"},{children:"Incomplete"}))]})]},n.badgeName)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Badge Name"}),t.jsx("th",{children:"Status"})]})}),t.jsx("tbody",{children:n})]}))}))}function R(e){if(0===e.items.length)return t.jsx(v,{title:"No answers to display",description:"There has not been any lesson progress just yet.",loading:e.loading,icon:"lessons"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onClick(n)}},{children:n.lessonName}))}),t.jsx("td",{children:n.questionName}),t.jsx("td",{children:n.answer.join(",")})]},n.questionName)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Lesson Name"}),t.jsx("th",{children:"Question"}),t.jsx("th",{children:"Answer"})]})}),t.jsx("tbody",{children:n})]}))}))}function F(e){if(0===e.items.length)return t.jsx(v,{title:"No reflections to display",description:"There has not been any lesson progress just yet.",loading:e.loading,icon:"lessons"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onClick(n)}},{children:n.lessonName}))}),t.jsx("td",{children:n.reflection}),t.jsx("td",{children:n.rating.toLocaleString()})]},n.lessonName)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Lesson Name"}),t.jsx("th",{children:"Reflection"}),t.jsx("th",{children:"Rating"})]})}),t.jsx("tbody",{children:n})]}))}))}var q=r.createStyles((function(e,n){var t=n.from||"blue",i=n.to||"green";return{card:{position:"relative",cursor:"pointer",overflow:"hidden",transition:"transform 150ms ease, box-shadow 100ms ease",padding:e.spacing.xl,paddingLeft:2*e.spacing.xl,"&:hover":{boxShadow:e.shadows.md,transform:"scale(1.02)"},"&::before":{content:'""',position:"absolute",top:0,bottom:0,left:0,width:6,backgroundImage:e.fn.linearGradient(0,e.colors[t][6],e.colors[i][6])}}}}));function U(e){var n=q(e).classes,s=e.from||"blue",o=e.to||"green",l=e.icon||t.jsx(i.IconColorSwatch,{size:28,stroke:1.5});return t.jsxs(r.Paper,x({withBorder:!0,radius:"md",className:n.card,onClick:e.onClick},{children:[t.jsx(r.ThemeIcon,x({size:"xl",radius:"md",variant:"gradient",gradient:{deg:0,from:s,to:o}},{children:l})),t.jsx(r.Text,x({size:"xl",weight:500,mt:"md"},{children:e.title})),t.jsx(r.Text,x({size:"sm",mt:"sm",color:"dimmed"},{children:e.description}))]}))}var V=r.createStyles((function(e){return{card:{height:240,backgroundSize:"cover",backgroundPosition:"center"},content:{position:"absolute",padding:e.spacing.xl,zIndex:1,top:0,bottom:0,right:0,left:0},action:{position:"absolute",bottom:e.spacing.xl,right:e.spacing.xl},title:{color:e.white,marginBottom:e.spacing.xs/2},description:{color:e.white,maxWidth:220}}})),_=function(e){var n=e.title,i=e.description,s=e.image,o=e.action,l=e.style,a=e.className,c=function(e,n){var t={};for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&n.indexOf(i)<0&&(t[i]=e[i]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var s=0;for(i=Object.getOwnPropertySymbols(e);s<i.length;s++)n.indexOf(i[s])<0&&Object.prototype.propertyIsEnumerable.call(e,i[s])&&(t[i[s]]=e[i[s]])}return t}(e,["title","description","image","action","style","className"]),d=V(),h=d.classes,u=d.cx,m=d.theme;return t.jsxs(r.Card,x({radius:"md",style:x({backgroundImage:"url(".concat(s,")")},l),className:u(h.card,a)},c,{children:[t.jsx(r.Overlay,{gradient:"linear-gradient(105deg, ".concat(m.black," 20%, #312f2f 50%, ").concat(m.colors.gray[4]," 100%)"),opacity:.55,zIndex:0}),t.jsxs("div",x({className:h.content},{children:[t.jsx(r.Text,x({size:"lg",weight:700,className:h.title},{children:n})),t.jsx(r.Text,x({size:"sm",className:h.description},{children:i})),t.jsx(r.Button,x({className:h.action,variant:"white",color:"dark",component:"a",size:"xs",href:o.link,target:"_blank"},{children:o.label}))]}))]}))};function Y(e){if(0===e.items.length)return t.jsx(v,{title:"No reflections to display",description:"There has not been any lesson progress just yet.",loading:e.loading,icon:"lessons"});var n=e.items.map((function(e){return t.jsxs("tr",{children:[t.jsx("td",{children:e.studentName}),t.jsx("td",{children:e.reflection}),t.jsx("td",{children:e.rating.toLocaleString()})]},e.studentName)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Student Name"}),t.jsx("th",{children:"Reflection"}),t.jsx("th",{children:"Rating"})]})}),t.jsx("tbody",{children:n})]}))}))}function J(e){if(0===e.items.length)return t.jsx(v,{title:"No students to display",description:"You don't have any student data yet for this lesson",loading:e.loading,icon:"lessons"});var n=e.items.map((function(n){return t.jsxs("tr",{children:[t.jsx("td",{children:t.jsx(r.UnstyledButton,x({onClick:function(){return e.onClick&&e.onClick(n)}},{children:t.jsxs(r.Group,x({spacing:"sm"},{children:[t.jsx(r.Avatar,{size:40,src:n.avatar,radius:40}),t.jsxs("div",{children:[t.jsx(r.Text,x({size:"sm",weight:500},{children:n.name})),t.jsx(r.Text,x({size:"xs",color:"dimmed"},{children:n.email}))]})]}))}))}),t.jsxs("td",{children:[!!n.isComplete&&t.jsx(r.Badge,x({variant:"filled"},{children:"Complete"})),!n.isComplete&&!n.isStarted&&t.jsx(r.Badge,x({color:"red",variant:"filled"},{children:"Not started"})),!n.isComplete&&!!n.isStarted&&t.jsx(r.Badge,x({color:"violet",variant:"filled"},{children:"In progress"}))]})]},n.name)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsxs(r.Table,x({verticalSpacing:"sm",sx:{minWidth:700},highlightOnHover:!0,striped:!0},{children:[t.jsx("thead",{children:t.jsxs("tr",{children:[t.jsx("th",{children:"Lesson Name"}),t.jsx("th",{children:"Status"})]})}),t.jsx("tbody",{children:n})]}))}))}function X(e){var n=u.useMemo((function(){return{position:"left",getValue:function(e){return e.primary}}}),[]),i=u.useMemo((function(){return[{position:"bottom",getValue:function(e){return e.secondary}}]}),[]);if(0===e.items.length)return t.jsx(v,{title:"No questions to display",description:"There are no questions in this lesson.",loading:e.loading,icon:"lessons"});var s=e.items.map((function(e){if(e.chart){var s={},o=e.choices||[];return o.forEach((function(e){s[e]=0})),e.answers.forEach((function(e){return e.forEach((function(e){e in s&&(s[e]=s[e]?s[e]+1:1)}))})),t.jsx(r.Card,x({withBorder:!0,p:"xl",radius:"md"},{children:t.jsxs(r.Stack,x({spacing:4},{children:[t.jsx(r.Title,x({size:"lg"},{children:e.question})),t.jsxs(r.Text,x({size:"sm"},{children:[e.answers.length," answers"]})),t.jsx("div",x({style:{background:"white",height:"300px",width:"100%",position:"relative"}},{children:t.jsx(d.Chart,{options:{data:[{label:"",data:o.map((function(e){return{primary:$(e,50),secondary:s[e]}}))}],primaryAxis:n,secondaryAxes:i}})}))]}))}),e.question)}return t.jsx(r.Card,x({withBorder:!0,p:"xl",radius:"md"},{children:t.jsxs(r.Stack,x({spacing:4},{children:[t.jsx(r.Title,x({size:"lg"},{children:e.question})),t.jsxs(r.Text,x({size:"sm"},{children:[e.answers.length," answers"]})),t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsx(r.Stack,x({spacing:4},{children:e.answers.map((function(e){var n=e.join("\n");return t.jsx(r.Card,x({p:5,radius:0,bg:"gray.0"},{children:t.jsx(r.Text,{children:n})}),n)}))}))}))]}))}),e.question)}));return t.jsx(r.Stack,x({py:4,spacing:10,sx:{minWidth:700}},{children:s}))}var $=function(e,n){return e.substr(0,n-1)+(e.length>n?"&hellip;":"")},Q=r.createStyles((function(e){var n;return{title:(n={fontSize:34,fontWeight:900},n[e.fn.smallerThan("sm")]={fontSize:24},n),description:{maxWidth:600}}}));function K(e){if(0===e.items.length)return t.jsx(v,{title:"No lessons to display",description:"We don't have any lessons to show you just yet.",loading:e.loading,icon:"lessons"});var n=e.items.map((function(n){return t.jsx("tr",{children:t.jsx("td",{children:t.jsx(r.UnstyledButton,x({sx:function(e){return{display:"block",width:"100%",padding:e.spacing.md,color:"dark"===e.colorScheme?e.colors.dark[0]:e.black,"&:hover":{backgroundColor:"dark"===e.colorScheme?e.colors.dark[8]:e.colors.gray[1]}}},onClick:function(){return e.onClick&&e.onClick(n)}},{children:t.jsx(r.Group,{children:t.jsxs("div",{children:[t.jsx(r.Text,x({size:"sm",weight:500},{children:n.name})),t.jsx(r.Text,x({size:"xs",color:"dimmed"},{children:n.description}))]})})}))})},n.lessonId)}));return t.jsx(r.ScrollArea.Autosize,x({maxHeight:500},{children:t.jsx(r.Table,x({horizontalSpacing:0,verticalSpacing:0,sx:{minWidth:700}},{children:t.jsx("tbody",{children:n})}))}))}var Z=r.createStyles((function(e){var n;return{title:(n={fontSize:34,fontWeight:900},n[e.fn.smallerThan("sm")]={fontSize:24},n),description:{maxWidth:600}}})),ee=r.createEmotionCache({key:"mantine",prepend:!1}),ne=function(e){var n=l.useForm({initialValues:{active:e.account}});return t.jsx(r.Modal,x({centered:!0,opened:e.opened,onClose:function(){return e.onClose&&e.onClose()},size:"sm",title:t.jsx(r.Title,x({size:"h5"},{children:"Accounts"}))},{children:t.jsxs("form",x({onSubmit:n.onSubmit((function(){e.onChange&&e.onChange(n.values.active)}))},{children:[t.jsx(r.Select,x({required:!0,placeholder:"Select an account",defaultValue:e.account,data:e.accounts.map((function(e){return{value:e.accountId,label:e.name}}))},n.getInputProps("active"))),t.jsx(r.Button,x({type:"submit",fullWidth:!0,mt:"xl"},{children:"Switch"}))]}))}))},te=r.createStyles((function(e){return{link:{width:50,height:50,borderRadius:e.radius.md,display:"flex",alignItems:"center",justifyContent:"center",color:"dark"===e.colorScheme?e.colors.dark[0]:e.colors.gray[7],"&:hover":{backgroundColor:"dark"===e.colorScheme?e.colors.dark[5]:e.colors.gray[0]}},active:{"&, &:hover":{backgroundColor:e.fn.variant({variant:"light",color:e.primaryColor}).background,color:e.fn.variant({variant:"light",color:e.primaryColor}).color}}}})),ie=[{icon:i.IconHome2,label:"Home",href:"/home"},{icon:i.IconGauge,label:"Dashboard",href:"/dashboard"},{icon:i.IconCategory2,label:"Classes",href:"/classes"},{icon:i.IconAlbum,label:"Badges",href:"/badges"},{icon:i.IconLambda,label:"Lessons",href:"/lessons"}],se=function(e){var n,i=e.icon,s=e.label,o=e.active,l=e.onClick,a=te(),c=a.classes,d=a.cx;return t.jsx(r.Tooltip,x({label:s,position:"right",transitionDuration:0},{children:t.jsx(r.UnstyledButton,x({onClick:l,className:d(c.link,(n={},n[c.active]=o,n))},{children:t.jsx(i,{stroke:1.5})}))}))},re=function(e){var n=ie.map((function(n){return t.jsx(se,{label:n.label,icon:n.icon,active:n.label===e.active,onClick:function(){return e.navigate(n.href)}},n.label)}));return t.jsxs(r.Navbar,x({width:{base:80},p:"md"},{children:[t.jsx(r.Center,{children:t.jsx(r.Avatar,x({color:"blue",radius:"sm"},{children:t.jsx("div",x({style:{width:15,marginLeft:"auto",marginRight:"auto"}},{children:t.jsx(r.Image,{fit:"contain",src:"https://cdn.localcivics.io/brand/l.png"})}))}))}),t.jsx(r.Navbar.Section,x({grow:!0,mt:50},{children:t.jsx(r.Stack,x({justify:"center",spacing:0},{children:n}))})),t.jsx(r.Navbar.Section,{children:t.jsxs(r.Stack,x({justify:"center",spacing:0},{children:[t.jsx(se,{icon:i.IconSwitchHorizontal,label:"Switch accounts",onClick:e.onSwitchAccounts}),t.jsx(se,{icon:i.IconLogout,label:"Logout",onClick:e.onLogout})]}))})]}))},oe=r.createStyles((function(e){var n,t,i,s,r,o;return{footer:{paddingTop:2*e.spacing.xl,paddingBottom:2*e.spacing.xl,paddingLeft:3*e.spacing.xl,backgroundColor:"dark"===e.colorScheme?e.colors.dark[6]:e.colors.gray[0],borderTop:"1px solid ".concat("dark"===e.colorScheme?e.colors.dark[5]:e.colors.gray[2])},logo:(n={maxWidth:200},n[e.fn.smallerThan("sm")]={display:"flex",flexDirection:"column",alignItems:"center"},n),description:(t={marginTop:5},t[e.fn.smallerThan("sm")]={marginTop:e.spacing.xs,textAlign:"center"},t),inner:(i={display:"flex",justifyContent:"space-between"},i[e.fn.smallerThan("sm")]={flexDirection:"column",alignItems:"center"},i),groups:(s={display:"flex",flexWrap:"wrap"},s[e.fn.smallerThan("sm")]={display:"none"},s),wrapper:{width:160},link:{display:"block",color:"dark"===e.colorScheme?e.colors.dark[1]:e.colors.gray[6],fontSize:e.fontSizes.sm,paddingTop:3,paddingBottom:3,"&:hover":{textDecoration:"underline"}},title:{fontSize:e.fontSizes.md,fontWeight:700,fontFamily:"Greycliff CF, ".concat(e.fontFamily),marginBottom:e.spacing.xs/2,color:"dark"===e.colorScheme?e.white:e.black},afterFooter:(r={display:"flex",justifyContent:"space-between",alignItems:"center",marginTop:e.spacing.xl,paddingTop:e.spacing.xl,paddingBottom:e.spacing.xl,borderTop:"1px solid ".concat("dark"===e.colorScheme?e.colors.dark[4]:e.colors.gray[2])},r[e.fn.smallerThan("sm")]={flexDirection:"column"},r),social:(o={},o[e.fn.smallerThan("sm")]={marginTop:e.spacing.xs},o)}})),le=function(e,n,t){var i=JSON.stringify(n),r=s.useState(!1),o=r[0],l=r[1],a=s.useState(e),c=a[0],d=a[1];return u.useEffect((function(){d(e)}),[e,i]),{opened:o,account:c,accounts:n,setChangeModalOpen:l,onAccountChange:function(e){d(e),l(!1),t(e)}}};Object.defineProperty(e,"showNotification",{enumerable:!0,get:function(){return n.showNotification}}),Object.defineProperty(e,"updateNotification",{enumerable:!0,get:function(){return n.updateNotification}}),e.AdminProvider=function(e){return t.jsx(r.MantineProvider,x({withNormalizeCSS:!0,withGlobalStyles:!0,emotionCache:ee,theme:{loader:"bars"}},{children:t.jsx(n.NotificationsProvider,x({limit:e.notificationLimit||5},{children:t.jsx(c.ModalsProvider,{children:e.children})}))}))},e.App=function(e){var n=oe().classes,s=le(e.account,e.accounts,e.onAccountChange);return t.jsxs(r.AppShell,x({padding:"xs",navbar:t.jsx(re,{active:e.navbar.props.active,navigate:e.navbar.props.navigate,onLogout:e.navbar.props.onLogout,onSwitchAccounts:function(){return s.setChangeModalOpen(!0)}}),footer:t.jsx(t.Fragment,{children:!s.opened&&t.jsxs("footer",x({className:n.footer},{children:[t.jsxs(r.Container,x({className:n.inner},{children:[t.jsxs("div",x({className:n.logo},{children:[t.jsxs(r.Group,x({spacing:"xs"},{children:[t.jsx("div",x({style:{width:15}},{children:t.jsx(r.Image,{fit:"contain",src:"https://cdn.localcivics.io/brand/l.png"})})),t.jsx(r.Title,x({color:"dimmed",size:"h5"},{children:"Local Civics"}))]})),t.jsx(r.Text,x({size:"xs",color:"dimmed",className:n.description},{children:"We connect students to powerful civic learning experiences."}))]})),t.jsx("div",x({className:n.groups},{children:t.jsxs("div",x({className:n.wrapper},{children:[t.jsx(r.Text,x({className:n.link,component:"a",href:"https://www.localcivics.io",target:"_blank"},{children:"About"})),t.jsx(r.Text,x({className:n.link,component:"a",href:"https://www.localcivics.io/terms-of-service",target:"_blank"},{children:"Terms"})),t.jsx(r.Text,x({className:n.link,component:"a",href:"https://www.localcivics.io/privacy-policy",target:"_blank"},{children:"Privacy"})),t.jsx(r.Text,x({className:n.link,component:"a",href:"https://localcivics.notion.site/Help-Center-b52300f587b64fc0a61f512686e7626d",target:"_blank"},{children:"Help Center"}))]}))}))]})),t.jsxs(r.Container,x({className:n.afterFooter},{children:[t.jsxs(r.Text,x({color:"dimmed",size:"sm"},{children:["© ",(new Date).getFullYear()," Local Civics. All rights reserved."]})),t.jsxs(r.Group,x({spacing:0,className:n.social,position:"right",noWrap:!0},{children:[t.jsx(r.ActionIcon,x({component:"a",target:"_blank",href:"https://www.instagram.com/localcivics/",size:"lg"},{children:t.jsx(i.IconBrandInstagram,{size:18,stroke:1.5})})),t.jsx(r.ActionIcon,x({component:"a",target:"_blank",href:"https://www.linkedin.com/company/localcivics",size:"lg"},{children:t.jsx(i.IconBrandLinkedin,{size:18,stroke:1.5})})),t.jsx(r.ActionIcon,x({component:"a",target:"_blank",href:"https://www.facebook.com/localcivics/",size:"lg"},{children:t.jsx(i.IconBrandFacebook,{size:18,stroke:1.5})}))]}))]}))]}))}),styles:function(e){return{main:{backgroundColor:"dark"===e.colorScheme?e.colors.dark[8]:e.colors.gray[0]}}}},{children:[t.jsxs("div",x({style:{position:"relative"}},{children:[(e.loading||s.opened)&&t.jsx(r.Center,x({style:{height:400}},{children:t.jsx(r.Loader,{})})),!e.loading&&!s.opened&&e.page]})),t.jsx(ne,{opened:s.opened,account:s.account,accounts:s.accounts,onChange:s.onAccountChange,onClose:function(){return s.setChangeModalOpen(!1)}})]}))},e.Badge=function(e){var n=C().classes,o=s.useState("lessons"),l=o[0],a=o[1],c=e.students.length,d=c>0?e.students.filter((function(e){return e.isComplete})).length/c:0;return t.jsx(r.Container,x({size:"lg",py:"xl"},{children:t.jsxs(r.Stack,x({spacing:"md"},{children:[t.jsx(r.Grid,{children:t.jsxs(r.Grid.Col,x({sm:"auto"},{children:[t.jsx(r.Badge,x({variant:"filled",leftSection:t.jsx(r.ActionIcon,x({onClick:e.onBackClick,color:"blue",size:"xs",radius:"xl",variant:"filled"},{children:t.jsx(i.IconArrowLeft,{size:14})})),size:"lg"},{children:"Badges"})),t.jsxs(r.Group,{children:[t.jsxs(r.Stack,x({spacing:0},{children:[t.jsx(r.Title,x({order:2,className:n.title,mt:"md"},{children:e.displayName||"Badge"})),t.jsx(r.Text,x({color:"dimmed",className:n.description,mt:"sm"},{children:e.description||"No description"}))]})),t.jsx(r.Stack,x({ml:"auto"},{children:t.jsx(r.Button,x({variant:"gradient",onClick:e.onPreviewClick},{children:"Preview"}))}))]})]}))}),t.jsx("div",{children:t.jsxs("div",x({style:{position:"relative"}},{children:[t.jsx(r.LoadingOverlay,{visible:e.loading,overlayBlur:2}),t.jsxs(r.Stack,{children:[t.jsx(p,{data:[{title:"BADGE COMPLETION",value:d,unit:"%"}]}),t.jsx(r.Select,{clearable:!0,clearButtonLabel:"Clear class selection",size:"sm",placeholder:"Select a class",nothingFound:"No options",value:e.classId,onChange:e.onClassChange,icon:t.jsx(i.IconCategory2,{}),data:e.classes.map((function(e){return{value:e.classId,label:e.name}}))}),t.jsxs(r.Stack,x({spacing:0},{children:[t.jsx(j,{value:l,data:[{label:"By lesson",value:"lessons"},{label:"By student",value:"students"}],onChange:a}),"lessons"===l&&t.jsx(y,{loading:e.loading,items:e.lessons,onClick:e.onLessonClick}),"students"===l&&t.jsx(b,{loading:e.loading,items:e.students,onClick:e.onUserClick})]}))]})]}))})]}))}))},e.Badges=function(e){var n=k().classes;return t.jsx(r.Container,x({size:"lg",py:"xl"},{children:t.jsxs(r.Stack,x({spacing:"md"},{children:[t.jsx(r.Grid,{children:t.jsxs(r.Grid.Col,x({sm:"auto"},{children:[t.jsx(r.Badge,x({variant:"filled",size:"lg"},{children:"Badges"})),t.jsx(r.Title,x({order:2,className:n.title,mt:"md"},{children:"Badges and micro-credentials"})),t.jsx(r.Text,x({color:"dimmed",className:n.description,mt:"sm"},{children:"Project-sized skills acquisition and standards alignment."}))]}))}),t.jsx(r.Autocomplete,{placeholder:"Search for a badge that fits your needs",data:e.badges.map((function(e){return e.name})),onChange:e.onAutocompleteChange}),t.jsxs("div",x({style:{position:"relative"}},{children:[t.jsx(r.LoadingOverlay,{visible:e.loading,overlayBlur:2}),t.jsx(S,{loading:e.loading,items:e.badges,onClick:e.onBadgeClick})]}))]}))}))},e.Class=function(e){var n=P().classes,o=l.useForm({initialValues:{classId:"",studentId:"",email:"",givenName:"",familyName:"",avatar:"",role:"",readonly:!1,lastActivity:null,hasAccount:!1,lessonsCompleted:0,badgesEarned:0},validate:{email:function(n){return/^\S+@\S+$/.test(n)&&0===e.students.filter((function(e){return e.email===n})).length?null:"Invalid email"}}}),a=s.useState(!1),c=a[0],d=a[1];return t.jsxs(t.Fragment,{children:[t.jsx(r.Drawer,x({opened:c,onClose:function(){return d(!1)},title:t.jsx(r.Title,x({size:"h5"},{children:"Add students"})),padding:"xl",size:"xl"},{children:t.jsxs(r.Stack,x({spacing:"md"},{children:[t.jsx(D,x({},e,{close:function(){return d(!1)}})),t.jsx(r.Divider,{label:"or",labelPosition:"center",my:"md",variant:"dashed"}),t.jsx("form",x({onSubmit:o.onSubmit((function(){var n=o.values;o.reset(),d(!1),e.onCreateStudents&&e.onCreateStudents([n])}))},{children:t.jsxs(r.Stack,{children:[t.jsx(r.TextInput,x({withAsterisk:!0,label:"Email",placeholder:"Email"},o.getInputProps("email"))),t.jsxs(r.Group,x({grow:!0},{children:[t.jsx(r.TextInput,x({label:"Given name",placeholder:"Given name"},o.getInputProps("givenName"))),t.jsx(r.TextInput,x({label:"Family name",placeholder:"Family name"},o.getInputProps("familyName")))]})),t.jsx(r.Button,x({type:"submit",fullWidth:!0,mt:"md"},{children:"Submit"}))]})}))]}))})),t.jsx(r.Container,x({size:"lg",py:"xl"},{children:t.jsxs(r.Stack,x({spacing:"md"},{children:[t.jsxs(r.Grid,{children:[t.jsxs(r.Grid.Col,x({sm:"auto"},{children:[t.jsx(r.Badge,x({variant:"filled",leftSection:t.jsx(r.ActionIcon,x({onClick:e.onBackClick,color:"blue",size:"xs",radius:"xl",variant:"filled"},{children:t.jsx(i.IconArrowLeft,{size:14})})),size:"lg"},{children:"Classes"})),t.jsx(r.Title,x({order:2,className:n.title,mt:"md"},{children:e.displayName||"Class"})),t.jsx(r.Text,x({color:"dimmed",className:n.description,mt:"sm"},{children:e.description||"No description"}))]})),t.jsx(r.Grid.Col,x({sm:"content"},{children:!e.loading&&t.jsx(r.Button,x({onClick:function(){return d(!0)},leftIcon:t.jsx(i.IconPlaylistAdd,{size:14})},{children:"Add students"}))}))]}),t.jsxs("div",x({style:{position:"relative"}},{children:[t.jsx(r.LoadingOverlay,{visible:e.loading,overlayBlur:2}),t.jsxs(r.Stack,x({spacing:"sm"},{children:[t.jsx(p,{data:[{title:"# OF STUDENTS",value:e.students.length},{title:"ACCOUNT CREATION",value:e.percentageOfAccountsCreated,unit:"%"},{title:"BADGE COMPLETION",value:e.percentageOfBadgesEarned,unit:"%"},{title:"LESSON COMPLETION",value:e.percentageOfLessonsCompleted,unit:"%"}]}),t.jsx(L,{loading:e.loading,items:e.students,onDelete:e.onDeleteStudent,onViewProfile:function(n){return e.onStudentClick(n)}})]}))]}))]}))}))]})},e.Classes=function(e){var n=G().classes,o=l.useForm({initialValues:{classId:"",name:"",description:""},validate:{name:function(e){return e.length<=6?"Name should include at least 6 characters":null}}}),a=s.useState(!1),c=a[0],d=a[1];return t.jsxs(t.Fragment,{children:[t.jsx(r.Drawer,x({opened:c,onClose:function(){return d(!1)},title:t.jsxs(r.Group,x({spacing:0},{children:[t.jsx(r.Title,x({size:"h5"},{children:"Create a class"})),t.jsx(r.Tooltip,x({label:"Classes settings cannot be modified once created"},{children:t.jsx(r.ActionIcon,{children:t.jsx(i.IconInfoCircle,{color:"#3b82f6",size:14})})}))]})),padding:"xl",size:"xl"},{children:t.jsxs("form",x({onSubmit:o.onSubmit((function(){var n=o.values;o.reset(),d(!1),e.onCreateClass&&e.onCreateClass(n)}))},{children:[t.jsxs(r.Stack,{children:[t.jsx(r.TextInput,x({withAsterisk:!0,label:"Name",placeholder:"Class name"},o.getInputProps("name"))),t.jsx(r.TextInput,x({label:"Description",placeholder:"A class for my first period English students"},o.getInputProps("description")))]}),t.jsx(r.Button,x({type:"submit",fullWidth:!0,mt:"md"},{children:"Submit"}))]}))})),t.jsx(r.Container,x({size:"lg",py:"xl"},{children:t.jsxs(r.Stack,x({spacing:"md"},{children:[t.jsxs(r.Grid,{children:[t.jsxs(r.Grid.Col,x({sm:"auto"},{children:[t.jsx(r.Badge,x({variant:"filled",size:"lg"},{children:"Classes"})),t.jsx(r.Title,x({order:2,className:n.title,mt:"md"},{children:"Organize students into classes"})),t.jsx(r.Text,x({color:"dimmed",className:n.description,mt:"sm"},{children:"A class can be for a specific period of time, grade, team, or other cohorts."}))]})),t.jsx(r.Grid.Col,x({sm:"content"},{children:!e.loading&&t.jsx(r.Button,x({onClick:function(){return d(!0)},leftIcon:t.jsx(i.IconPlaylistAdd,{size:14})},{children:"Create class"}))}))]}),t.jsxs("div",x({style:{position:"relative"}},{children:[t.jsx(r.LoadingOverlay,{visible:e.loading,overlayBlur:2}),t.jsxs(r.Stack,x({spacing:"sm"},{children:[t.jsx(p,{data:[{title:"# OF CLASSES",value:e.classes.length}]}),t.jsx(W,{loading:e.loading,items:e.classes,onDeleteClass:e.onDeleteClass,onClick:e.onClassClick})]}))]}))]}))}))]})},e.Dashboard=function(e){var n=s.useState("students"),o=n[0],l=n[1];return t.jsx(r.Container,x({size:"lg",py:"xl"},{children:t.jsxs(r.Stack,{children:[t.jsxs(r.Stack,x({spacing:0},{children:[t.jsx(r.Title,x({size:"h3"},{children:"Dashboard"})),t.jsx(r.Text,x({color:"dimmed",size:"sm",mt:"md"},{children:"Fast-track learning for your students."}))]})),t.jsx(r.Stack,{children:t.jsxs("div",x({style:{position:"relative"}},{children:[t.jsx(r.LoadingOverlay,{visible:e.loading,overlayBlur:2}),t.jsxs(r.Stack,x({spacing:"sm"},{children:[t.jsx(p,{data:[{title:"# OF STUDENTS",value:e.students.length},{title:"ACCOUNT CREATION",value:e.percentageOfAccountsCreated,unit:"%"},{title:"BADGE COMPLETION",value:e.percentageOfBadgesEarned,unit:"%"},{title:"LESSON COMPLETION",value:e.percentageOfLessonsCompleted,unit:"%"}]}),t.jsx(r.Select,{clearable:!0,clearButtonLabel:"Clear class selection",size:"sm",placeholder:"Select a class",nothingFound:"No options",value:e.classId,onChange:e.onClassChange,icon:t.jsx(i.IconCategory2,{}),data:e.classes.map((function(e){return{value:e.classId,label:e.name}}))}),t.jsxs(r.Stack,x({spacing:0},{children:[t.jsx(j,{value:o,data:[{label:"My students",value:"students"},{label:"Impact statements",value:"impact"},{label:"Reflections",value:"reflections"},{label:"Badges",value:"badges"},{label:"Lessons",value:"lessons"}],onChange:l}),"impact"===o&&t.jsx(A,{loading:e.loading,items:e.impacts}),"reflections"===o&&t.jsx(I,{loading:e.loading,items:e.reflections}),"badges"===o&&t.jsx(B,{loading:e.loading,items:e.badges,onClick:e.onBadgeClick}),"lessons"===o&&t.jsx(O,{loading:e.loading,items:e.lessons,onClick:e.onLessonClick}),"students"===o&&t.jsx(N,{loading:e.loading,items:e.students,onViewProfile:e.onViewStudentProfile})]}))]}))]}))})]})}))},e.Home=function(e){return t.jsx(r.Container,x({size:"lg"},{children:t.jsxs(r.Stack,x({spacing:"lg"},{children:[t.jsxs(r.Grid,x({gutter:"md"},{children:[t.jsx(r.Grid.Col,x({md:6},{children:t.jsx(M,{variant:"compact",name:e.name,impactStatement:e.impactStatement})})),t.jsx(r.Grid.Col,x({md:6},{children:t.jsx(_,{title:e.organization.name,description:e.organization.description,image:e.organization.image,action:{label:"Visit website",link:e.organization.website}})}))]})),t.jsxs(r.Grid,x({gutter:"md"},{children:[t.jsx(r.Grid.Col,{children:t.jsx(U,{title:"Dashboard",description:"Track class performance across core areas of focus.",onClick:e.onDashboardClick})}),t.jsx(r.Grid.Col,{children:t.jsx(U,{title:"Classes",description:"Organize students into classes.",onClick:e.onClassesClick})}),t.jsx(r.Grid.Col,{children:t.jsx(U,{title:"Lessons",description:"Explore units of instruction and/or see corresponding class progress.",onClick:e.onLessonsClick})}),t.jsx(r.Grid.Col,{children:t.jsx(U,{title:"Badges",description:"Project-sized skills acquisition and standards alignment.",onClick:e.onBadgesClick})})]}))]}))}))},e.Lesson=function(e){var n=Q().classes,o=s.useState("question"),l=o[0],a=o[1],c=e.students.length,d=c>0?e.students.filter((function(e){return e.isComplete})).length/c:0;return t.jsx(r.Container,x({size:"lg",py:"xl"},{children:t.jsxs(r.Stack,x({spacing:"md"},{children:[t.jsx(r.Grid,{children:t.jsxs(r.Grid.Col,x({sm:"auto"},{children:[t.jsx(r.Badge,x({variant:"filled",leftSection:t.jsx(r.ActionIcon,x({onClick:e.onBackClick,color:"blue",size:"xs",radius:"xl",variant:"filled"},{children:t.jsx(i.IconArrowLeft,{size:14})})),size:"lg"},{children:"Lessons"})),t.jsxs(r.Group,{children:[t.jsxs(r.Stack,x({spacing:0},{children:[t.jsx(r.Title,x({order:2,className:n.title,mt:"md"},{children:e.displayName||"Lesson"})),t.jsx(r.Text,x({color:"dimmed",className:n.description,mt:"sm"},{children:e.description||"No description"}))]})),t.jsx(r.Stack,x({ml:"auto"},{children:t.jsx(r.Button,x({variant:"gradient",onClick:e.onPreviewClick},{children:"Preview"}))}))]})]}))}),t.jsx("div",{children:t.jsxs("div",x({style:{position:"relative"}},{children:[t.jsx(r.LoadingOverlay,{visible:e.loading,overlayBlur:2}),t.jsxs(r.Stack,{children:[t.jsx(p,{data:[{title:"LESSON COMPLETION",value:d,unit:"%"}]}),t.jsx(r.Select,{clearable:!0,clearButtonLabel:"Clear class selection",size:"sm",placeholder:"Select a class",nothingFound:"No options",value:e.classId,onChange:e.onClassChange,icon:t.jsx(i.IconCategory2,{}),data:e.classes.map((function(e){return{value:e.classId,label:e.name}}))}),t.jsxs(r.Stack,x({spacing:0},{children:[t.jsx(j,{value:l,data:[{label:"By question",value:"question"},{label:"By reflection",value:"reflections"},{label:"By student",value:"students"}],onChange:a}),"question"===l&&t.jsx(X,{loading:e.loading,items:e.questions}),"reflections"===l&&t.jsx(Y,{loading:e.loading,items:e.reflections}),"students"===l&&t.jsx(J,{loading:e.loading,items:e.students,onClick:e.onUserClick})]}))]})]}))})]}))}))},e.Lessons=function(e){var n=Z().classes;return t.jsx(r.Container,x({size:"lg",py:"xl"},{children:t.jsxs(r.Stack,x({spacing:"md"},{children:[t.jsx(r.Grid,{children:t.jsxs(r.Grid.Col,x({sm:"auto"},{children:[t.jsx(r.Badge,x({variant:"filled",size:"lg"},{children:"Lessons"})),t.jsx(r.Title,x({order:2,className:n.title,mt:"md"},{children:"Lessons"})),t.jsx(r.Text,x({color:"dimmed",className:n.description,mt:"sm"},{children:"Explore units of instruction and/or see corresponding class progress."}))]}))}),t.jsx(r.Autocomplete,{placeholder:"Search for a lesson that fits your needs",data:e.lessons.map((function(e){return e.name})),onChange:e.onAutocompleteChange}),t.jsxs("div",x({style:{position:"relative"}},{children:[t.jsx(r.LoadingOverlay,{visible:e.loading,overlayBlur:2}),t.jsx(K,{loading:e.loading,items:e.lessons,onClick:e.onLessonClick})]}))]}))}))},e.Navbar=re,e.Student=function(e){var n=s.useState("badges"),o=n[0],l=n[1],a=e.badges.length,c=a>0?e.badges.filter((function(e){return e.isComplete})).length/a:0;return t.jsx(r.Container,x({size:"lg",py:"xl"},{children:t.jsxs(r.Stack,x({spacing:"md"},{children:[t.jsx(r.Grid,x({gutter:"md"},{children:t.jsxs(r.Grid.Col,x({sm:"auto"},{children:[t.jsx(r.Badge,x({variant:"filled",leftSection:t.jsx(r.ActionIcon,x({onClick:e.onBackClick,color:"blue",size:"xs",radius:"xl",variant:"filled"},{children:t.jsx(i.IconArrowLeft,{size:14})})),size:"lg"},{children:"Students"})),t.jsx(M,{variant:"compact",name:e.name,impactStatement:e.impactStatement})]}))})),t.jsxs("div",x({style:{position:"relative"}},{children:[t.jsx(r.LoadingOverlay,{visible:e.loading,overlayBlur:2}),t.jsxs(r.Stack,x({spacing:"lg"},{children:[t.jsx(p,{data:[{title:"PROBLEMS SOLVED",value:e.numberOfProblemsSolved},{title:"LESSON COMPLETION",value:e.percentageOfLessonsCompleted,unit:"%"},{title:"BADGE COMPLETION",value:c,unit:"%"}]}),t.jsxs(r.Stack,x({spacing:0},{children:[t.jsx(j,{value:o,data:[{label:"My badges",value:"badges"},{label:"My answers",value:"answers"},{label:"My reflections",value:"reflections"}],onChange:l}),"badges"===o&&t.jsx(H,{loading:e.loading,items:e.badges,onClick:e.onBadgeClick}),"answers"===o&&t.jsx(R,{loading:e.loading,items:e.answers,onClick:e.onAnswerClick}),"reflections"===o&&t.jsx(F,{loading:e.loading,items:e.reflections,onClick:e.onReflectionClick})]}))]}))]}))]}))}))},e.SwitchAccount=ne,Object.defineProperty(e,"__esModule",{value:!0})}));
1
+ 'use strict';
2
+
3
+ var notifications = require('@mantine/notifications');
4
+ var icons = require('@tabler/icons');
5
+ var React = require('react');
6
+ var core = require('@mantine/core');
7
+ var dropzone = require('@mantine/dropzone');
8
+ var form = require('@mantine/form');
9
+ var papa = require('papaparse');
10
+ var modals = require('@mantine/modals');
11
+ var reactCharts = require('react-charts');
12
+
13
+ function _interopNamespaceDefault(e) {
14
+ var n = Object.create(null);
15
+ if (e) {
16
+ Object.keys(e).forEach(function (k) {
17
+ if (k !== 'default') {
18
+ var d = Object.getOwnPropertyDescriptor(e, k);
19
+ Object.defineProperty(n, k, d.get ? d : {
20
+ enumerable: true,
21
+ get: function () { return e[k]; }
22
+ });
23
+ }
24
+ });
25
+ }
26
+ n.default = e;
27
+ return Object.freeze(n);
28
+ }
29
+
30
+ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
31
+ var papa__namespace = /*#__PURE__*/_interopNamespaceDefault(papa);
32
+
33
+ const useStyles$c = core.createStyles((theme) => ({
34
+ root: {
35
+ display: "flex",
36
+ backgroundImage: `linear-gradient(-60deg, ${theme.colors[theme.primaryColor][4]} 0%, ${theme.colors[theme.primaryColor][7]} 100%)`,
37
+ padding: theme.spacing.xl * 1.5,
38
+ borderRadius: theme.radius.md,
39
+ [theme.fn.smallerThan("sm")]: {
40
+ flexDirection: "column"
41
+ }
42
+ },
43
+ title: {
44
+ color: theme.white,
45
+ textTransform: "uppercase",
46
+ fontWeight: 700,
47
+ fontSize: theme.fontSizes.sm
48
+ },
49
+ count: {
50
+ color: theme.white,
51
+ fontSize: 32,
52
+ lineHeight: 1,
53
+ fontWeight: 700,
54
+ marginBottom: theme.spacing.md,
55
+ fontFamily: `Greycliff CF, ${theme.fontFamily}`
56
+ },
57
+ description: {
58
+ color: theme.colors[theme.primaryColor][0],
59
+ fontSize: theme.fontSizes.sm,
60
+ marginTop: 5
61
+ },
62
+ stat: {
63
+ flex: 1,
64
+ "& + &": {
65
+ paddingLeft: theme.spacing.xl,
66
+ marginLeft: theme.spacing.xl,
67
+ borderLeft: `1px solid ${theme.colors[theme.primaryColor][3]}`,
68
+ [theme.fn.smallerThan("sm")]: {
69
+ paddingLeft: 0,
70
+ marginLeft: 0,
71
+ borderLeft: 0,
72
+ paddingTop: theme.spacing.xl,
73
+ marginTop: theme.spacing.xl,
74
+ borderTop: `1px solid ${theme.colors[theme.primaryColor][3]}`
75
+ }
76
+ }
77
+ }
78
+ }));
79
+ const StatsGroup = ({ data }) => {
80
+ const { classes } = useStyles$c();
81
+ const stats = data.map((stat) => {
82
+ const value = (() => {
83
+ if (stat.unit === "%") {
84
+ return Math.round((stat.value + Number.EPSILON) * 100);
85
+ }
86
+ return stat.value;
87
+ })();
88
+ return /* @__PURE__ */ React__namespace.createElement("div", { key: stat.title, className: classes.stat }, /* @__PURE__ */ React__namespace.createElement(core.Text, { className: classes.count }, value.toLocaleString(), stat.unit), /* @__PURE__ */ React__namespace.createElement(core.Text, { className: classes.title }, stat.title));
89
+ });
90
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: classes.root }, stats);
91
+ };
92
+
93
+ const Tabs = (props) => {
94
+ var _a;
95
+ const tabs = (_a = props.data) == null ? void 0 : _a.map((item) => /* @__PURE__ */ React__namespace.createElement(core.Tabs.Tab, { key: item.value, value: item.value }, item.label || item.value));
96
+ return /* @__PURE__ */ React__namespace.createElement(core.Tabs, { value: props.value, onTabChange: props.onChange }, /* @__PURE__ */ React__namespace.createElement(core.Tabs.List, null, tabs));
97
+ };
98
+
99
+ const useStyles$b = core.createStyles((theme) => ({
100
+ wrapper: {
101
+ display: "flex",
102
+ alignItems: "center",
103
+ padding: theme.spacing.xl * 2,
104
+ borderRadius: theme.radius.md,
105
+ backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.white,
106
+ border: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.colors.gray[3]}`,
107
+ [`@media (max-width: ${theme.breakpoints.sm}px)`]: {
108
+ flexDirection: "column-reverse",
109
+ padding: theme.spacing.xl
110
+ }
111
+ },
112
+ image: {
113
+ maxWidth: "40%",
114
+ [`@media (max-width: ${theme.breakpoints.sm}px)`]: {
115
+ maxWidth: "100%"
116
+ }
117
+ },
118
+ body: {
119
+ paddingRight: theme.spacing.xl * 4,
120
+ [`@media (max-width: ${theme.breakpoints.sm}px)`]: {
121
+ paddingRight: 0,
122
+ marginTop: theme.spacing.xl
123
+ }
124
+ },
125
+ title: {
126
+ color: theme.colorScheme === "dark" ? theme.white : theme.black,
127
+ fontFamily: `Greycliff CF, ${theme.fontFamily}`,
128
+ lineHeight: 1,
129
+ marginBottom: theme.spacing.md
130
+ },
131
+ controls: {
132
+ display: "flex",
133
+ marginTop: theme.spacing.xl
134
+ },
135
+ inputWrapper: {
136
+ width: "100%",
137
+ flex: "1"
138
+ },
139
+ input: {
140
+ borderTopRightRadius: 0,
141
+ borderBottomRightRadius: 0,
142
+ borderRight: 0
143
+ },
144
+ control: {
145
+ borderTopLeftRadius: 0,
146
+ borderBottomLeftRadius: 0
147
+ }
148
+ }));
149
+ const PlaceholderBanner = (props) => {
150
+ const { classes } = useStyles$b();
151
+ const title = props.title || "Nothing to display";
152
+ const description = props.description || "We don't have anything to show you here just yet. Add data, check back later, or adjust your search.";
153
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React__namespace.createElement("div", { className: classes.body }, /* @__PURE__ */ React__namespace.createElement(core.Title, { className: classes.title }, props.loading ? "Loading..." : title), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", color: "dimmed" }, props.loading ? "Hold on, we're loading your data." : description)), /* @__PURE__ */ React__namespace.createElement(core.Image, { src: `https://cdn.localcivics.io/illustrations/${props.icon}.svg`, className: classes.image }));
154
+ };
155
+
156
+ function Table$f(props) {
157
+ if (props.items.length === 0) {
158
+ return /* @__PURE__ */ React__namespace.createElement(
159
+ PlaceholderBanner,
160
+ {
161
+ title: "No badges to display",
162
+ description: "There has not been any badge progress just yet.",
163
+ loading: props.loading,
164
+ icon: "badges"
165
+ }
166
+ );
167
+ }
168
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.name }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick && props.onClick(row) }, /* @__PURE__ */ React__namespace.createElement(core.Group, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(core.Avatar, { size: 40, src: row.avatar, radius: 40 }), /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xs", color: "dimmed" }, row.email))))), /* @__PURE__ */ React__namespace.createElement("td", null, !!row.isComplete && /* @__PURE__ */ React__namespace.createElement(core.Badge, { variant: "filled" }, "Complete"), !row.isComplete && /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "red", variant: "filled" }, "Incomplete"))));
169
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Student Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Badge Status"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
170
+ }
171
+
172
+ function Table$e(props) {
173
+ if (props.items.length === 0) {
174
+ return /* @__PURE__ */ React__namespace.createElement(
175
+ PlaceholderBanner,
176
+ {
177
+ title: "No lessons to display",
178
+ description: "There are not lessons in badge.",
179
+ loading: props.loading,
180
+ icon: "badges"
181
+ }
182
+ );
183
+ }
184
+ const rows = props.items.map((row) => {
185
+ const percentageCompletion = Math.round((row.percentageCompletion + Number.EPSILON) * 100);
186
+ return /* @__PURE__ */ React__namespace.createElement("tr", { key: row.lessonName }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick && props.onClick(row) }, row.lessonName)), /* @__PURE__ */ React__namespace.createElement("td", null, percentageCompletion, "%"));
187
+ });
188
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Lesson Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Lesson Completion"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
189
+ }
190
+
191
+ const useStyles$a = core.createStyles((theme) => ({
192
+ title: {
193
+ fontSize: 34,
194
+ fontWeight: 900,
195
+ [theme.fn.smallerThan("sm")]: {
196
+ fontSize: 24
197
+ }
198
+ },
199
+ description: {
200
+ maxWidth: 600
201
+ }
202
+ }));
203
+ const Badge = (props) => {
204
+ const { classes } = useStyles$a();
205
+ const [tab, setTab] = React.useState("lessons");
206
+ const numberOfStudents = props.students.length;
207
+ const percentageOfBadgesEarned = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length / numberOfStudents : 0;
208
+ return /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid, null, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "auto" }, /* @__PURE__ */ React__namespace.createElement(
209
+ core.Badge,
210
+ {
211
+ variant: "filled",
212
+ leftSection: /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { onClick: props.onBackClick, color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React__namespace.createElement(icons.IconArrowLeft, { size: 14 })),
213
+ size: "lg"
214
+ },
215
+ "Badges"
216
+ ), /* @__PURE__ */ React__namespace.createElement(core.Group, null, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "Badge"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), /* @__PURE__ */ React__namespace.createElement(core.Stack, { ml: "auto" }, /* @__PURE__ */ React__namespace.createElement(
217
+ core.Button,
218
+ {
219
+ variant: "gradient",
220
+ onClick: props.onPreviewClick
221
+ },
222
+ "Preview"
223
+ ))))), /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(core.Stack, null, /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
224
+ {
225
+ title: "BADGE COMPLETION",
226
+ value: percentageOfBadgesEarned,
227
+ unit: "%"
228
+ }
229
+ ] }), /* @__PURE__ */ React__namespace.createElement(
230
+ core.Select,
231
+ {
232
+ clearable: true,
233
+ clearButtonLabel: "Clear class selection",
234
+ size: "sm",
235
+ placeholder: "Select a class",
236
+ nothingFound: "No options",
237
+ value: props.classId,
238
+ onChange: props.onClassChange,
239
+ icon: /* @__PURE__ */ React__namespace.createElement(icons.IconCategory2, null),
240
+ data: props.classes.map((g) => {
241
+ return { value: g.classId, label: g.name };
242
+ })
243
+ }
244
+ ), /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
245
+ Tabs,
246
+ {
247
+ value: tab,
248
+ data: [
249
+ { label: "By lesson", value: "lessons" },
250
+ { label: "By student", value: "students" }
251
+ ],
252
+ onChange: setTab
253
+ }
254
+ ), tab === "lessons" && /* @__PURE__ */ React__namespace.createElement(
255
+ Table$e,
256
+ {
257
+ loading: props.loading,
258
+ items: props.lessons,
259
+ onClick: props.onLessonClick
260
+ }
261
+ ), tab === "students" && /* @__PURE__ */ React__namespace.createElement(
262
+ Table$f,
263
+ {
264
+ loading: props.loading,
265
+ items: props.students,
266
+ onClick: props.onUserClick
267
+ }
268
+ )))))));
269
+ };
270
+
271
+ function Table$d(props) {
272
+ if (props.items.length === 0) {
273
+ return /* @__PURE__ */ React__namespace.createElement(
274
+ PlaceholderBanner,
275
+ {
276
+ title: "No badges to display",
277
+ description: "We don't have any badges to show you just yet.",
278
+ loading: props.loading,
279
+ icon: "badges"
280
+ }
281
+ );
282
+ }
283
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.badgeId }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(
284
+ core.UnstyledButton,
285
+ {
286
+ sx: (theme) => ({
287
+ display: "block",
288
+ width: "100%",
289
+ padding: theme.spacing.md,
290
+ color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
291
+ "&:hover": {
292
+ backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.colors.gray[1]
293
+ }
294
+ }),
295
+ onClick: () => props.onClick && props.onClick(row)
296
+ },
297
+ /* @__PURE__ */ React__namespace.createElement(core.Group, null, /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xs", color: "dimmed" }, row.description)))
298
+ ))));
299
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { horizontalSpacing: 0, verticalSpacing: 0, sx: { minWidth: 700 } }, /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
300
+ }
301
+
302
+ const useStyles$9 = core.createStyles((theme) => ({
303
+ title: {
304
+ fontSize: 34,
305
+ fontWeight: 900,
306
+ [theme.fn.smallerThan("sm")]: {
307
+ fontSize: 24
308
+ }
309
+ },
310
+ description: {
311
+ maxWidth: 600
312
+ }
313
+ }));
314
+ const Badges = (props) => {
315
+ const { classes } = useStyles$9();
316
+ return /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid, null, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "auto" }, /* @__PURE__ */ React__namespace.createElement(core.Badge, { variant: "filled", size: "lg" }, "Badges"), /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, "Badges and micro-credentials"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Project-sized skills acquisition and standards alignment."))), /* @__PURE__ */ React__namespace.createElement(
317
+ core.Autocomplete,
318
+ {
319
+ placeholder: "Search for a badge that fits your needs",
320
+ data: props.badges.map((item) => item.name),
321
+ onChange: props.onAutocompleteChange
322
+ }
323
+ ), /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(
324
+ Table$d,
325
+ {
326
+ loading: props.loading,
327
+ items: props.badges,
328
+ onClick: props.onBadgeClick
329
+ }
330
+ ))));
331
+ };
332
+
333
+ function Table$c(props) {
334
+ if (props.items.length === 0) {
335
+ return /* @__PURE__ */ React__namespace.createElement(
336
+ PlaceholderBanner,
337
+ {
338
+ title: "No students to display",
339
+ description: "You don't have any students yet, add them and revisit.",
340
+ loading: props.loading,
341
+ icon: "groups"
342
+ }
343
+ );
344
+ }
345
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.studentName }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onViewProfile(row) }, row.studentName)), /* @__PURE__ */ React__namespace.createElement("td", null, row.className)));
346
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Student Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Class Name"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
347
+ }
348
+
349
+ const units = [
350
+ { unit: "year", ms: 31536e6 },
351
+ { unit: "month", ms: 2628e6 },
352
+ { unit: "day", ms: 864e5 },
353
+ { unit: "hour", ms: 36e5 },
354
+ { unit: "minute", ms: 6e4 },
355
+ { unit: "second", ms: 1e3 }
356
+ ];
357
+ const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
358
+ function relativeTimeFromDates(relative, pivot = new Date()) {
359
+ if (!relative)
360
+ return "";
361
+ const elapsed = relative.getTime() - pivot.getTime();
362
+ return relativeTimeFromElapsed(elapsed);
363
+ }
364
+ function relativeTimeFromElapsed(elapsed) {
365
+ for (const { unit, ms } of units) {
366
+ if (Math.abs(elapsed) >= ms || unit === "second") {
367
+ return rtf.format(Math.round(elapsed / ms), unit);
368
+ }
369
+ }
370
+ return "";
371
+ }
372
+
373
+ function Table$b(props) {
374
+ if (props.items.length === 0) {
375
+ return /* @__PURE__ */ React__namespace.createElement(
376
+ PlaceholderBanner,
377
+ {
378
+ title: "No reflections to display",
379
+ description: "There has not been any lesson progress just yet.",
380
+ loading: props.loading,
381
+ icon: "lessons"
382
+ }
383
+ );
384
+ }
385
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.studentName + row.lessonName }, /* @__PURE__ */ React__namespace.createElement("td", null, row.studentName), /* @__PURE__ */ React__namespace.createElement("td", null, row.lessonName), /* @__PURE__ */ React__namespace.createElement("td", null, row.reflection), /* @__PURE__ */ React__namespace.createElement("td", null, relativeTimeFromDates(new Date(row.updatedAt)))));
386
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Student Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Lesson Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Reflection"), /* @__PURE__ */ React__namespace.createElement("th", null, "Updated At"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
387
+ }
388
+
389
+ function Table$a(props) {
390
+ if (props.items.length === 0) {
391
+ return /* @__PURE__ */ React__namespace.createElement(
392
+ PlaceholderBanner,
393
+ {
394
+ title: "No impact statements to display",
395
+ description: "There are no students with impact statements yet.",
396
+ loading: props.loading,
397
+ icon: "kindergarten"
398
+ }
399
+ );
400
+ }
401
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.studentName }, /* @__PURE__ */ React__namespace.createElement("td", null, row.studentName), /* @__PURE__ */ React__namespace.createElement("td", null, row.impactStatement)));
402
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Student Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Impact Statement"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
403
+ }
404
+
405
+ function Table$9(props) {
406
+ if (props.items.length === 0) {
407
+ return /* @__PURE__ */ React__namespace.createElement(
408
+ PlaceholderBanner,
409
+ {
410
+ title: "No badges to display",
411
+ description: "We don't have any badges to show you just yet.",
412
+ loading: props.loading,
413
+ icon: "badges"
414
+ }
415
+ );
416
+ }
417
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.badgeId }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick && props.onClick(row) }, row.name)), /* @__PURE__ */ React__namespace.createElement("td", null, row.description), /* @__PURE__ */ React__namespace.createElement("td", null, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")));
418
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Badge Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Description"), /* @__PURE__ */ React__namespace.createElement("th", null, "Completion"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
419
+ }
420
+
421
+ function Table$8(props) {
422
+ if (props.items.length === 0) {
423
+ return /* @__PURE__ */ React__namespace.createElement(
424
+ PlaceholderBanner,
425
+ {
426
+ title: "No lessons to display",
427
+ description: "We don't have any lessons to show you just yet.",
428
+ loading: props.loading,
429
+ icon: "lessons"
430
+ }
431
+ );
432
+ }
433
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.lessonId }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick && props.onClick(row) }, row.name)), /* @__PURE__ */ React__namespace.createElement("td", null, row.description), /* @__PURE__ */ React__namespace.createElement("td", null, Math.round((row.percentageCompletion + Number.EPSILON) * 100), "%")));
434
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Lesson Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Description"), /* @__PURE__ */ React__namespace.createElement("th", null, "Completion"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
435
+ }
436
+
437
+ const Dashboard = (props) => {
438
+ const [tab, setTab] = React.useState("students");
439
+ return /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, null, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { size: "h3" }, "Dashboard"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", size: "sm", mt: "md" }, "Fast-track learning for your students.")), /* @__PURE__ */ React__namespace.createElement(core.Stack, null, /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
440
+ {
441
+ title: "# OF STUDENTS",
442
+ value: props.students.length
443
+ },
444
+ {
445
+ title: "ACCOUNT CREATION",
446
+ value: props.percentageOfAccountsCreated,
447
+ unit: "%"
448
+ },
449
+ {
450
+ title: "BADGE COMPLETION",
451
+ value: props.percentageOfBadgesEarned,
452
+ unit: "%"
453
+ },
454
+ {
455
+ title: "LESSON COMPLETION",
456
+ value: props.percentageOfLessonsCompleted,
457
+ unit: "%"
458
+ }
459
+ ] }), /* @__PURE__ */ React__namespace.createElement(
460
+ core.Select,
461
+ {
462
+ clearable: true,
463
+ clearButtonLabel: "Clear class selection",
464
+ size: "sm",
465
+ placeholder: "Select a class",
466
+ nothingFound: "No options",
467
+ value: props.classId,
468
+ onChange: props.onClassChange,
469
+ icon: /* @__PURE__ */ React__namespace.createElement(icons.IconCategory2, null),
470
+ data: props.classes.map((g) => {
471
+ return { value: g.classId, label: g.name };
472
+ })
473
+ }
474
+ ), /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
475
+ Tabs,
476
+ {
477
+ value: tab,
478
+ data: [
479
+ { label: "My students", value: "students" },
480
+ { label: "Impact statements", value: "impact" },
481
+ { label: "Reflections", value: "reflections" },
482
+ { label: "Badges", value: "badges" },
483
+ { label: "Lessons", value: "lessons" }
484
+ ],
485
+ onChange: setTab
486
+ }
487
+ ), tab === "impact" && /* @__PURE__ */ React__namespace.createElement(
488
+ Table$a,
489
+ {
490
+ loading: props.loading,
491
+ items: props.impacts
492
+ }
493
+ ), tab === "reflections" && /* @__PURE__ */ React__namespace.createElement(
494
+ Table$b,
495
+ {
496
+ loading: props.loading,
497
+ items: props.reflections
498
+ }
499
+ ), tab === "badges" && /* @__PURE__ */ React__namespace.createElement(
500
+ Table$9,
501
+ {
502
+ loading: props.loading,
503
+ items: props.badges,
504
+ onClick: props.onBadgeClick
505
+ }
506
+ ), tab === "lessons" && /* @__PURE__ */ React__namespace.createElement(
507
+ Table$8,
508
+ {
509
+ loading: props.loading,
510
+ items: props.lessons,
511
+ onClick: props.onLessonClick
512
+ }
513
+ ), tab === "students" && /* @__PURE__ */ React__namespace.createElement(
514
+ Table$c,
515
+ {
516
+ loading: props.loading,
517
+ items: props.students,
518
+ onViewProfile: props.onViewStudentProfile
519
+ }
520
+ )))))));
521
+ };
522
+
523
+ function Table$7(props) {
524
+ if (props.items.length === 0) {
525
+ return /* @__PURE__ */ React__namespace.createElement(
526
+ PlaceholderBanner,
527
+ {
528
+ title: "No students to display",
529
+ description: "You have not rostered any students yet.",
530
+ loading: props.loading,
531
+ icon: "groups"
532
+ }
533
+ );
534
+ }
535
+ const openDeleteModal = (student) => modals.openConfirmModal({
536
+ title: `Delete "${student.givenName && student.familyName ? `${student.givenName} ${student.familyName}` : student.email}"?`,
537
+ centered: true,
538
+ children: /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm" }, "Are you sure you want to delete this person? This action is destructive and you will have to contact support to restore your data."),
539
+ labels: { confirm: "Delete", cancel: "No don't delete them" },
540
+ confirmProps: { color: "red" },
541
+ onConfirm: () => props.onDelete && props.onDelete(student)
542
+ });
543
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.email }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onViewProfile && props.onViewProfile(row) }, /* @__PURE__ */ React__namespace.createElement(core.Group, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(core.Avatar, { size: 40, src: row.avatar, radius: 40 }), /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", weight: 500 }, row.givenName && row.familyName ? `${row.givenName} ${row.familyName}` : row.email), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xs", color: "dimmed" }, row.email))))), /* @__PURE__ */ React__namespace.createElement("td", null, row.badgesEarned), /* @__PURE__ */ React__namespace.createElement("td", null, row.lessonsCompleted), /* @__PURE__ */ React__namespace.createElement("td", null, row.hasAccount && /* @__PURE__ */ React__namespace.createElement(icons.IconCheck, { color: "green" })), /* @__PURE__ */ React__namespace.createElement("td", null, row.lastActivity ? relativeTimeFromDates(row.lastActivity) : ""), /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0, position: "right" }, !row.readonly && !!props.onDelete && /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { color: "red" }, /* @__PURE__ */ React__namespace.createElement(icons.IconTrash, { onClick: () => openDeleteModal(row), size: 16, stroke: 1.5 }))))));
544
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea, null, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: 20, sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Student Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Badges Earned"), /* @__PURE__ */ React__namespace.createElement("th", null, "Lessons Completed"), /* @__PURE__ */ React__namespace.createElement("th", null, "Account Created?"), /* @__PURE__ */ React__namespace.createElement("th", null, "Last Active"), /* @__PURE__ */ React__namespace.createElement("th", null))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
545
+ }
546
+
547
+ var __defProp$3 = Object.defineProperty;
548
+ var __defProps = Object.defineProperties;
549
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
550
+ var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
551
+ var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
552
+ var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
553
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
554
+ var __spreadValues$3 = (a, b) => {
555
+ for (var prop in b || (b = {}))
556
+ if (__hasOwnProp$3.call(b, prop))
557
+ __defNormalProp$3(a, prop, b[prop]);
558
+ if (__getOwnPropSymbols$3)
559
+ for (var prop of __getOwnPropSymbols$3(b)) {
560
+ if (__propIsEnum$3.call(b, prop))
561
+ __defNormalProp$3(a, prop, b[prop]);
562
+ }
563
+ return a;
564
+ };
565
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
566
+ const useStyles$8 = core.createStyles((theme) => ({
567
+ title: {
568
+ fontSize: 34,
569
+ fontWeight: 900,
570
+ [theme.fn.smallerThan("sm")]: {
571
+ fontSize: 24
572
+ }
573
+ },
574
+ description: {
575
+ maxWidth: 600
576
+ },
577
+ wrapper: {
578
+ position: "relative",
579
+ marginBottom: 30
580
+ },
581
+ dropzone: {
582
+ borderWidth: 1,
583
+ paddingBottom: 50
584
+ },
585
+ icon: {
586
+ color: theme.colorScheme === "dark" ? theme.colors.dark[3] : theme.colors.gray[4]
587
+ },
588
+ control: {
589
+ position: "absolute",
590
+ width: 250,
591
+ left: "calc(50% - 125px)",
592
+ bottom: -20
593
+ }
594
+ }));
595
+ const Class = (props) => {
596
+ const { classes } = useStyles$8();
597
+ const form$1 = form.useForm({
598
+ initialValues: {
599
+ classId: "",
600
+ studentId: "",
601
+ email: "",
602
+ givenName: "",
603
+ familyName: "",
604
+ avatar: "",
605
+ role: "",
606
+ readonly: false,
607
+ lastActivity: null,
608
+ hasAccount: false,
609
+ lessonsCompleted: 0,
610
+ badgesEarned: 0
611
+ },
612
+ validate: {
613
+ email: (value) => /^\S+@\S+$/.test(value) && props.students.filter((u) => u.email === value).length === 0 ? null : "Invalid email"
614
+ }
615
+ });
616
+ const [opened, setOpened] = React.useState(false);
617
+ return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(
618
+ core.Drawer,
619
+ {
620
+ opened,
621
+ onClose: () => setOpened(false),
622
+ title: /* @__PURE__ */ React__namespace.createElement(core.Title, { size: "h5" }, "Add students"),
623
+ padding: "xl",
624
+ size: "xl"
625
+ },
626
+ /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(DropzoneButton, __spreadProps(__spreadValues$3({}, props), { close: () => setOpened(false) })), /* @__PURE__ */ React__namespace.createElement(core.Divider, { label: "or", labelPosition: "center", my: "md", variant: "dashed" }), /* @__PURE__ */ React__namespace.createElement("form", { onSubmit: form$1.onSubmit(() => {
627
+ const values = form$1.values;
628
+ form$1.reset();
629
+ setOpened(false);
630
+ props.onCreateStudents && props.onCreateStudents([values]);
631
+ }) }, /* @__PURE__ */ React__namespace.createElement(core.Stack, null, /* @__PURE__ */ React__namespace.createElement(
632
+ core.TextInput,
633
+ __spreadValues$3({
634
+ withAsterisk: true,
635
+ label: "Email",
636
+ placeholder: "Email"
637
+ }, form$1.getInputProps("email"))
638
+ ), /* @__PURE__ */ React__namespace.createElement(core.Group, { grow: true }, /* @__PURE__ */ React__namespace.createElement(
639
+ core.TextInput,
640
+ __spreadValues$3({
641
+ label: "Given name",
642
+ placeholder: "Given name"
643
+ }, form$1.getInputProps("givenName"))
644
+ ), /* @__PURE__ */ React__namespace.createElement(
645
+ core.TextInput,
646
+ __spreadValues$3({
647
+ label: "Family name",
648
+ placeholder: "Family name"
649
+ }, form$1.getInputProps("familyName"))
650
+ )), /* @__PURE__ */ React__namespace.createElement(core.Button, { type: "submit", fullWidth: true, mt: "md" }, "Submit"))))
651
+ ), /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid, null, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "auto" }, /* @__PURE__ */ React__namespace.createElement(
652
+ core.Badge,
653
+ {
654
+ variant: "filled",
655
+ leftSection: /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { onClick: props.onBackClick, color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React__namespace.createElement(icons.IconArrowLeft, { size: 14 })),
656
+ size: "lg"
657
+ },
658
+ "Classes"
659
+ ), /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "Class"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "content" }, !props.loading && /* @__PURE__ */ React__namespace.createElement(
660
+ core.Button,
661
+ {
662
+ onClick: () => setOpened(true),
663
+ leftIcon: /* @__PURE__ */ React__namespace.createElement(icons.IconPlaylistAdd, { size: 14 })
664
+ },
665
+ "Add students"
666
+ ))), /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
667
+ {
668
+ title: "# OF STUDENTS",
669
+ value: props.students.length
670
+ },
671
+ {
672
+ title: "ACCOUNT CREATION",
673
+ value: props.percentageOfAccountsCreated,
674
+ unit: "%"
675
+ },
676
+ {
677
+ title: "BADGE COMPLETION",
678
+ value: props.percentageOfBadgesEarned,
679
+ unit: "%"
680
+ },
681
+ {
682
+ title: "LESSON COMPLETION",
683
+ value: props.percentageOfLessonsCompleted,
684
+ unit: "%"
685
+ }
686
+ ] }), /* @__PURE__ */ React__namespace.createElement(
687
+ Table$7,
688
+ {
689
+ loading: props.loading,
690
+ items: props.students,
691
+ onDelete: props.onDeleteStudent,
692
+ onViewProfile: (student) => props.onStudentClick(student)
693
+ }
694
+ ))))));
695
+ };
696
+ const DropzoneButton = (props) => {
697
+ const { classes, theme } = useStyles$8();
698
+ const openRef = React__namespace.useRef(null);
699
+ const [loading, setLoading] = React__namespace.useState(false);
700
+ const onDrop = React__namespace.useCallback((acceptedFiles) => {
701
+ setLoading(true);
702
+ acceptedFiles.forEach((file) => {
703
+ papa__namespace.parse(file, {
704
+ download: true,
705
+ header: true,
706
+ dynamicTyping: true,
707
+ skipEmptyLines: true,
708
+ worker: true,
709
+ complete: function(results) {
710
+ const data = results.data.filter((v) => /^\S+@\S+$/.test(v.email) && props.students.filter((u) => u.email === v.email).length === 0);
711
+ data.length > 0 && props.onCreateStudents && props.onCreateStudents(data);
712
+ setLoading(false);
713
+ props.close();
714
+ }
715
+ });
716
+ });
717
+ }, []);
718
+ return /* @__PURE__ */ React__namespace.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React__namespace.createElement(
719
+ dropzone.Dropzone,
720
+ {
721
+ loading,
722
+ openRef,
723
+ onDrop,
724
+ className: classes.dropzone,
725
+ radius: "md",
726
+ accept: [dropzone.MIME_TYPES.csv],
727
+ maxSize: 5 * 1024 ** 2
728
+ },
729
+ /* @__PURE__ */ React__namespace.createElement("div", { style: { pointerEvents: "none" } }, /* @__PURE__ */ React__namespace.createElement(core.Group, { position: "center" }, /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Accept, null, /* @__PURE__ */ React__namespace.createElement(icons.IconDownload, { size: 50, color: theme.colors[theme.primaryColor][6], stroke: 1.5 })), /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Reject, null, /* @__PURE__ */ React__namespace.createElement(icons.IconX, { size: 50, color: theme.colors.red[6], stroke: 1.5 })), /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Idle, null, /* @__PURE__ */ React__namespace.createElement(
730
+ icons.IconCloudUpload,
731
+ {
732
+ size: 50,
733
+ color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
734
+ stroke: 1.5
735
+ }
736
+ ))), /* @__PURE__ */ React__namespace.createElement(core.Text, { align: "center", weight: 700, size: "lg", mt: "xl" }, /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Accept, null, "Drop files here"), /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Reject, null, "Csv file less than 5mb"), /* @__PURE__ */ React__namespace.createElement(dropzone.Dropzone.Idle, null, "Upload multiple")), /* @__PURE__ */ React__namespace.createElement(core.Text, { align: "center", size: "sm", mt: "xs", color: "dimmed" }, "Drag'n'drop files here to upload. We can accept only ", /* @__PURE__ */ React__namespace.createElement("i", null, ".csv"), " files that are less than 5mb in size."))
737
+ ), /* @__PURE__ */ React__namespace.createElement(core.Button, { className: classes.control, size: "md", radius: "xl", onClick: () => {
738
+ var _a;
739
+ return (_a = openRef.current) == null ? void 0 : _a.call(openRef);
740
+ } }, "Select file"));
741
+ };
742
+
743
+ function Table$6(props) {
744
+ if (props.items.length === 0) {
745
+ return /* @__PURE__ */ React__namespace.createElement(
746
+ PlaceholderBanner,
747
+ {
748
+ title: "No classes to display",
749
+ description: "You don't have any classes yet. Try creating one first...",
750
+ loading: props.loading,
751
+ icon: "groups"
752
+ }
753
+ );
754
+ }
755
+ const openDeleteModal = (group) => modals.openConfirmModal({
756
+ title: `Delete "${group.name}"?`,
757
+ centered: true,
758
+ children: /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm" }, "Are you sure you want to delete this class? This action is destructive and you will have to contact support to restore your data."),
759
+ labels: { confirm: "Delete class", cancel: "No don't delete it" },
760
+ confirmProps: { color: "red" },
761
+ onConfirm: () => props.onDeleteClass(group)
762
+ });
763
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.classId }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick(row) }, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: 14 }, row.name))), /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: 14 }, row.description)), /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.Group, { noWrap: true, spacing: 0, position: "right" }, /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { color: "red" }, /* @__PURE__ */ React__namespace.createElement(icons.IconTrash, { onClick: () => openDeleteModal(row), size: 16, stroke: 1.5 }))))));
764
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 300 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: 20, sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Class Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Description"), /* @__PURE__ */ React__namespace.createElement("th", null))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
765
+ }
766
+
767
+ var __defProp$2 = Object.defineProperty;
768
+ var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
769
+ var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
770
+ var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
771
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
772
+ var __spreadValues$2 = (a, b) => {
773
+ for (var prop in b || (b = {}))
774
+ if (__hasOwnProp$2.call(b, prop))
775
+ __defNormalProp$2(a, prop, b[prop]);
776
+ if (__getOwnPropSymbols$2)
777
+ for (var prop of __getOwnPropSymbols$2(b)) {
778
+ if (__propIsEnum$2.call(b, prop))
779
+ __defNormalProp$2(a, prop, b[prop]);
780
+ }
781
+ return a;
782
+ };
783
+ const useStyles$7 = core.createStyles((theme) => ({
784
+ title: {
785
+ fontSize: 34,
786
+ fontWeight: 900,
787
+ [theme.fn.smallerThan("sm")]: {
788
+ fontSize: 24
789
+ }
790
+ },
791
+ description: {
792
+ maxWidth: 600
793
+ }
794
+ }));
795
+ const Classes = (props) => {
796
+ const { classes } = useStyles$7();
797
+ const form$1 = form.useForm({
798
+ initialValues: {
799
+ classId: "",
800
+ name: "",
801
+ description: ""
802
+ },
803
+ validate: {
804
+ name: (val) => val.length <= 6 ? "Name should include at least 6 characters" : null
805
+ }
806
+ });
807
+ const [opened, setOpened] = React.useState(false);
808
+ return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(
809
+ core.Drawer,
810
+ {
811
+ opened,
812
+ onClose: () => setOpened(false),
813
+ title: /* @__PURE__ */ React__namespace.createElement(core.Group, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { size: "h5" }, "Create a class"), /* @__PURE__ */ React__namespace.createElement(core.Tooltip, { label: "Classes settings cannot be modified once created" }, /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, null, /* @__PURE__ */ React__namespace.createElement(icons.IconInfoCircle, { color: "#3b82f6", size: 14 })))),
814
+ padding: "xl",
815
+ size: "xl"
816
+ },
817
+ /* @__PURE__ */ React__namespace.createElement("form", { onSubmit: form$1.onSubmit(() => {
818
+ const values = form$1.values;
819
+ form$1.reset();
820
+ setOpened(false);
821
+ props.onCreateClass && props.onCreateClass(values);
822
+ }) }, /* @__PURE__ */ React__namespace.createElement(core.Stack, null, /* @__PURE__ */ React__namespace.createElement(
823
+ core.TextInput,
824
+ __spreadValues$2({
825
+ withAsterisk: true,
826
+ label: "Name",
827
+ placeholder: "Class name"
828
+ }, form$1.getInputProps("name"))
829
+ ), /* @__PURE__ */ React__namespace.createElement(
830
+ core.TextInput,
831
+ __spreadValues$2({
832
+ label: "Description",
833
+ placeholder: "A class for my first period English students"
834
+ }, form$1.getInputProps("description"))
835
+ )), /* @__PURE__ */ React__namespace.createElement(core.Button, { type: "submit", fullWidth: true, mt: "md" }, "Submit"))
836
+ ), /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid, null, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "auto" }, /* @__PURE__ */ React__namespace.createElement(core.Badge, { variant: "filled", size: "lg" }, "Classes"), /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, "Organize students into classes"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, "A class can be for a specific period of time, grade, team, or other cohorts.")), /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "content" }, !props.loading && /* @__PURE__ */ React__namespace.createElement(
837
+ core.Button,
838
+ {
839
+ onClick: () => setOpened(true),
840
+ leftIcon: /* @__PURE__ */ React__namespace.createElement(icons.IconPlaylistAdd, { size: 14 })
841
+ },
842
+ "Create class"
843
+ ))), /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
844
+ {
845
+ title: "# OF CLASSES",
846
+ value: props.classes.length
847
+ }
848
+ ] }), /* @__PURE__ */ React__namespace.createElement(
849
+ Table$6,
850
+ {
851
+ loading: props.loading,
852
+ items: props.classes,
853
+ onDeleteClass: props.onDeleteClass,
854
+ onClick: props.onClassClick
855
+ }
856
+ ))))));
857
+ };
858
+
859
+ const useStyles$6 = core.createStyles((theme) => ({
860
+ title: {
861
+ fontSize: 34,
862
+ fontWeight: 900,
863
+ marginTop: 16,
864
+ [theme.fn.smallerThan("sm")]: {
865
+ fontSize: 24
866
+ }
867
+ },
868
+ description: {
869
+ maxWidth: 600
870
+ }
871
+ }));
872
+ const UserInfo = (props) => {
873
+ const { classes } = useStyles$6();
874
+ return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(core.Title, { className: classes.title }, props.name), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "xs" }, props.impactStatement));
875
+ };
876
+
877
+ function Table$5(props) {
878
+ if (props.items.length === 0) {
879
+ return /* @__PURE__ */ React__namespace.createElement(
880
+ PlaceholderBanner,
881
+ {
882
+ title: "No badges to display",
883
+ description: "There has not been any badge progress just yet.",
884
+ loading: props.loading,
885
+ icon: "badges"
886
+ }
887
+ );
888
+ }
889
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.badgeName }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick(row) }, row.badgeName)), /* @__PURE__ */ React__namespace.createElement("td", null, !!row.isComplete && /* @__PURE__ */ React__namespace.createElement(core.Badge, { variant: "filled" }, "Complete"), !row.isComplete && /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "red", variant: "filled" }, "Incomplete"))));
890
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Badge Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Status"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
891
+ }
892
+
893
+ function Table$4(props) {
894
+ if (props.items.length === 0) {
895
+ return /* @__PURE__ */ React__namespace.createElement(
896
+ PlaceholderBanner,
897
+ {
898
+ title: "No answers to display",
899
+ description: "There has not been any lesson progress just yet.",
900
+ loading: props.loading,
901
+ icon: "lessons"
902
+ }
903
+ );
904
+ }
905
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.questionName }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick(row) }, row.lessonName)), /* @__PURE__ */ React__namespace.createElement("td", null, row.questionName), /* @__PURE__ */ React__namespace.createElement("td", null, row.answer.join(","))));
906
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Lesson Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Question"), /* @__PURE__ */ React__namespace.createElement("th", null, "Answer"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
907
+ }
908
+
909
+ function Table$3(props) {
910
+ if (props.items.length === 0) {
911
+ return /* @__PURE__ */ React__namespace.createElement(
912
+ PlaceholderBanner,
913
+ {
914
+ title: "No reflections to display",
915
+ description: "There has not been any lesson progress just yet.",
916
+ loading: props.loading,
917
+ icon: "lessons"
918
+ }
919
+ );
920
+ }
921
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.lessonName }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick(row) }, row.lessonName)), /* @__PURE__ */ React__namespace.createElement("td", null, row.reflection), /* @__PURE__ */ React__namespace.createElement("td", null, row.rating.toLocaleString())));
922
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Lesson Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Reflection"), /* @__PURE__ */ React__namespace.createElement("th", null, "Rating"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
923
+ }
924
+
925
+ const Student = (props) => {
926
+ const [tab, setTab] = React.useState("badges");
927
+ const numberOfBadges = props.badges.length;
928
+ const percentageOfBadgesEarned = numberOfBadges > 0 ? props.badges.filter((b) => b.isComplete).length / numberOfBadges : 0;
929
+ return /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid, { gutter: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "auto" }, /* @__PURE__ */ React__namespace.createElement(
930
+ core.Badge,
931
+ {
932
+ variant: "filled",
933
+ leftSection: /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { onClick: props.onBackClick, color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React__namespace.createElement(icons.IconArrowLeft, { size: 14 })),
934
+ size: "lg"
935
+ },
936
+ "Students"
937
+ ), /* @__PURE__ */ React__namespace.createElement(
938
+ UserInfo,
939
+ {
940
+ variant: "compact",
941
+ name: props.name,
942
+ impactStatement: props.impactStatement
943
+ }
944
+ ))), /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "lg" }, /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
945
+ {
946
+ title: "PROBLEMS SOLVED",
947
+ value: props.numberOfProblemsSolved
948
+ },
949
+ {
950
+ title: "LESSON COMPLETION",
951
+ value: props.percentageOfLessonsCompleted,
952
+ unit: "%"
953
+ },
954
+ {
955
+ title: "BADGE COMPLETION",
956
+ value: percentageOfBadgesEarned,
957
+ unit: "%"
958
+ }
959
+ ] }), /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
960
+ Tabs,
961
+ {
962
+ value: tab,
963
+ data: [
964
+ { label: "My badges", value: "badges" },
965
+ { label: "My answers", value: "answers" },
966
+ { label: "My reflections", value: "reflections" }
967
+ ],
968
+ onChange: setTab
969
+ }
970
+ ), tab === "badges" && /* @__PURE__ */ React__namespace.createElement(
971
+ Table$5,
972
+ {
973
+ loading: props.loading,
974
+ items: props.badges,
975
+ onClick: props.onBadgeClick
976
+ }
977
+ ), tab === "answers" && /* @__PURE__ */ React__namespace.createElement(
978
+ Table$4,
979
+ {
980
+ loading: props.loading,
981
+ items: props.answers,
982
+ onClick: props.onAnswerClick
983
+ }
984
+ ), tab === "reflections" && /* @__PURE__ */ React__namespace.createElement(
985
+ Table$3,
986
+ {
987
+ loading: props.loading,
988
+ items: props.reflections,
989
+ onClick: props.onReflectionClick
990
+ }
991
+ ))))));
992
+ };
993
+
994
+ const useStyles$5 = core.createStyles((theme, props) => {
995
+ const from = props.from || "blue";
996
+ const to = props.to || "green";
997
+ return {
998
+ card: {
999
+ position: "relative",
1000
+ cursor: "pointer",
1001
+ overflow: "hidden",
1002
+ transition: "transform 150ms ease, box-shadow 100ms ease",
1003
+ padding: theme.spacing.xl,
1004
+ paddingLeft: theme.spacing.xl * 2,
1005
+ "&:hover": {
1006
+ boxShadow: theme.shadows.md,
1007
+ transform: "scale(1.02)"
1008
+ },
1009
+ "&::before": {
1010
+ content: '""',
1011
+ position: "absolute",
1012
+ top: 0,
1013
+ bottom: 0,
1014
+ left: 0,
1015
+ width: 6,
1016
+ backgroundImage: theme.fn.linearGradient(0, theme.colors[from][6], theme.colors[to][6])
1017
+ }
1018
+ }
1019
+ };
1020
+ });
1021
+ function CardGradient(props) {
1022
+ const { classes } = useStyles$5(props);
1023
+ const from = props.from || "blue";
1024
+ const to = props.to || "green";
1025
+ const icon = props.icon || /* @__PURE__ */ React__namespace.createElement(icons.IconColorSwatch, { size: 28, stroke: 1.5 });
1026
+ return /* @__PURE__ */ React__namespace.createElement(core.Paper, { withBorder: true, radius: "md", className: classes.card, onClick: props.onClick }, /* @__PURE__ */ React__namespace.createElement(
1027
+ core.ThemeIcon,
1028
+ {
1029
+ size: "xl",
1030
+ radius: "md",
1031
+ variant: "gradient",
1032
+ gradient: { deg: 0, from, to }
1033
+ },
1034
+ icon
1035
+ ), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xl", weight: 500, mt: "md" }, props.title), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", mt: "sm", color: "dimmed" }, props.description));
1036
+ }
1037
+
1038
+ var __defProp$1 = Object.defineProperty;
1039
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
1040
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
1041
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
1042
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1043
+ var __spreadValues$1 = (a, b) => {
1044
+ for (var prop in b || (b = {}))
1045
+ if (__hasOwnProp$1.call(b, prop))
1046
+ __defNormalProp$1(a, prop, b[prop]);
1047
+ if (__getOwnPropSymbols$1)
1048
+ for (var prop of __getOwnPropSymbols$1(b)) {
1049
+ if (__propIsEnum$1.call(b, prop))
1050
+ __defNormalProp$1(a, prop, b[prop]);
1051
+ }
1052
+ return a;
1053
+ };
1054
+ var __objRest = (source, exclude) => {
1055
+ var target = {};
1056
+ for (var prop in source)
1057
+ if (__hasOwnProp$1.call(source, prop) && exclude.indexOf(prop) < 0)
1058
+ target[prop] = source[prop];
1059
+ if (source != null && __getOwnPropSymbols$1)
1060
+ for (var prop of __getOwnPropSymbols$1(source)) {
1061
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$1.call(source, prop))
1062
+ target[prop] = source[prop];
1063
+ }
1064
+ return target;
1065
+ };
1066
+ const useStyles$4 = core.createStyles((theme) => ({
1067
+ card: {
1068
+ height: 240,
1069
+ backgroundSize: "cover",
1070
+ backgroundPosition: "center"
1071
+ },
1072
+ content: {
1073
+ position: "absolute",
1074
+ padding: theme.spacing.xl,
1075
+ zIndex: 1,
1076
+ top: 0,
1077
+ bottom: 0,
1078
+ right: 0,
1079
+ left: 0
1080
+ },
1081
+ action: {
1082
+ position: "absolute",
1083
+ bottom: theme.spacing.xl,
1084
+ right: theme.spacing.xl
1085
+ },
1086
+ title: {
1087
+ color: theme.white,
1088
+ marginBottom: theme.spacing.xs / 2
1089
+ },
1090
+ description: {
1091
+ color: theme.white,
1092
+ maxWidth: 220
1093
+ }
1094
+ }));
1095
+ const TenantBanner = (_a) => {
1096
+ var _b = _a, {
1097
+ title,
1098
+ description,
1099
+ image,
1100
+ action,
1101
+ style,
1102
+ className
1103
+ } = _b, others = __objRest(_b, [
1104
+ "title",
1105
+ "description",
1106
+ "image",
1107
+ "action",
1108
+ "style",
1109
+ "className"
1110
+ ]);
1111
+ const { classes, cx, theme } = useStyles$4();
1112
+ return /* @__PURE__ */ React__namespace.createElement(
1113
+ core.Card,
1114
+ __spreadValues$1({
1115
+ radius: "md",
1116
+ style: __spreadValues$1({ backgroundImage: `url(${image})` }, style),
1117
+ className: cx(classes.card, className)
1118
+ }, others),
1119
+ /* @__PURE__ */ React__namespace.createElement(
1120
+ core.Overlay,
1121
+ {
1122
+ gradient: `linear-gradient(105deg, ${theme.black} 20%, #312f2f 50%, ${theme.colors.gray[4]} 100%)`,
1123
+ opacity: 0.55,
1124
+ zIndex: 0
1125
+ }
1126
+ ),
1127
+ /* @__PURE__ */ React__namespace.createElement("div", { className: classes.content }, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "lg", weight: 700, className: classes.title }, title), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", className: classes.description }, description), /* @__PURE__ */ React__namespace.createElement(
1128
+ core.Button,
1129
+ {
1130
+ className: classes.action,
1131
+ variant: "white",
1132
+ color: "dark",
1133
+ component: "a",
1134
+ size: "xs",
1135
+ href: action.link,
1136
+ target: "_blank"
1137
+ },
1138
+ action.label
1139
+ ))
1140
+ );
1141
+ };
1142
+
1143
+ const Home = (props) => {
1144
+ return /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "lg" }, /* @__PURE__ */ React__namespace.createElement(core.Grid, { gutter: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { md: 6 }, /* @__PURE__ */ React__namespace.createElement(
1145
+ UserInfo,
1146
+ {
1147
+ variant: "compact",
1148
+ name: props.name,
1149
+ impactStatement: props.impactStatement
1150
+ }
1151
+ )), /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { md: 6 }, /* @__PURE__ */ React__namespace.createElement(
1152
+ TenantBanner,
1153
+ {
1154
+ title: props.organization.name,
1155
+ description: props.organization.description,
1156
+ image: props.organization.image,
1157
+ action: {
1158
+ label: "Visit website",
1159
+ link: props.organization.website
1160
+ }
1161
+ }
1162
+ ))), /* @__PURE__ */ React__namespace.createElement(core.Grid, { gutter: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, null, /* @__PURE__ */ React__namespace.createElement(
1163
+ CardGradient,
1164
+ {
1165
+ title: "Dashboard",
1166
+ description: "Track class performance across core areas of focus.",
1167
+ onClick: props.onDashboardClick
1168
+ }
1169
+ )), /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, null, /* @__PURE__ */ React__namespace.createElement(
1170
+ CardGradient,
1171
+ {
1172
+ title: "Classes",
1173
+ description: "Organize students into classes.",
1174
+ onClick: props.onClassesClick
1175
+ }
1176
+ )), /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, null, /* @__PURE__ */ React__namespace.createElement(
1177
+ CardGradient,
1178
+ {
1179
+ title: "Lessons",
1180
+ description: "Explore units of instruction and/or see corresponding class progress.",
1181
+ onClick: props.onLessonsClick
1182
+ }
1183
+ )), /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, null, /* @__PURE__ */ React__namespace.createElement(
1184
+ CardGradient,
1185
+ {
1186
+ title: "Badges",
1187
+ description: "Project-sized skills acquisition and standards alignment.",
1188
+ onClick: props.onBadgesClick
1189
+ }
1190
+ )))));
1191
+ };
1192
+
1193
+ function Table$2(props) {
1194
+ if (props.items.length === 0) {
1195
+ return /* @__PURE__ */ React__namespace.createElement(
1196
+ PlaceholderBanner,
1197
+ {
1198
+ title: "No reflections to display",
1199
+ description: "There has not been any lesson progress just yet.",
1200
+ loading: props.loading,
1201
+ icon: "lessons"
1202
+ }
1203
+ );
1204
+ }
1205
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.studentName }, /* @__PURE__ */ React__namespace.createElement("td", null, row.studentName), /* @__PURE__ */ React__namespace.createElement("td", null, row.reflection), /* @__PURE__ */ React__namespace.createElement("td", null, row.rating.toLocaleString())));
1206
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Student Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Reflection"), /* @__PURE__ */ React__namespace.createElement("th", null, "Rating"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
1207
+ }
1208
+
1209
+ function Table$1(props) {
1210
+ if (props.items.length === 0) {
1211
+ return /* @__PURE__ */ React__namespace.createElement(
1212
+ PlaceholderBanner,
1213
+ {
1214
+ title: "No students to display",
1215
+ description: "You don't have any student data yet for this lesson",
1216
+ loading: props.loading,
1217
+ icon: "lessons"
1218
+ }
1219
+ );
1220
+ }
1221
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.name }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick: () => props.onClick && props.onClick(row) }, /* @__PURE__ */ React__namespace.createElement(core.Group, { spacing: "sm" }, /* @__PURE__ */ React__namespace.createElement(core.Avatar, { size: 40, src: row.avatar, radius: 40 }), /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xs", color: "dimmed" }, row.email))))), /* @__PURE__ */ React__namespace.createElement("td", null, !!row.isComplete && /* @__PURE__ */ React__namespace.createElement(core.Badge, { variant: "filled" }, "Complete"), !row.isComplete && !row.isStarted && /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "red", variant: "filled" }, "Not started"), !row.isComplete && !!row.isStarted && /* @__PURE__ */ React__namespace.createElement(core.Badge, { color: "violet", variant: "filled" }, "In progress"))));
1222
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { verticalSpacing: "sm", sx: { minWidth: 700 }, highlightOnHover: true, striped: true }, /* @__PURE__ */ React__namespace.createElement("thead", null, /* @__PURE__ */ React__namespace.createElement("tr", null, /* @__PURE__ */ React__namespace.createElement("th", null, "Lesson Name"), /* @__PURE__ */ React__namespace.createElement("th", null, "Status"))), /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
1223
+ }
1224
+
1225
+ function Stack(props) {
1226
+ const primaryAxis = React__namespace.useMemo(
1227
+ () => ({
1228
+ position: "left",
1229
+ getValue: (datum) => datum.primary
1230
+ }),
1231
+ []
1232
+ );
1233
+ const secondaryAxes = React__namespace.useMemo(
1234
+ () => [
1235
+ {
1236
+ position: "bottom",
1237
+ getValue: (datum) => datum.secondary
1238
+ }
1239
+ ],
1240
+ []
1241
+ );
1242
+ if (props.items.length === 0) {
1243
+ return /* @__PURE__ */ React__namespace.createElement(
1244
+ PlaceholderBanner,
1245
+ {
1246
+ title: "No questions to display",
1247
+ description: "There are no questions in this lesson.",
1248
+ loading: props.loading,
1249
+ icon: "lessons"
1250
+ }
1251
+ );
1252
+ }
1253
+ const rows = props.items.map((row) => {
1254
+ if (row.chart) {
1255
+ const labelMap = {};
1256
+ const choices = row.choices || [];
1257
+ choices.forEach((c) => {
1258
+ labelMap[c] = 0;
1259
+ });
1260
+ row.answers.forEach((a) => a.forEach((r) => {
1261
+ if (r in labelMap) {
1262
+ labelMap[r] = labelMap[r] ? labelMap[r] + 1 : 1;
1263
+ }
1264
+ }));
1265
+ return /* @__PURE__ */ React__namespace.createElement(core.Card, { key: row.question, withBorder: true, p: "xl", radius: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 4 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { size: "lg" }, row.question), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm" }, row.answers.length, " answers"), /* @__PURE__ */ React__namespace.createElement("div", { style: { background: "white", height: "300px", width: "100%", position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(
1266
+ reactCharts.Chart,
1267
+ {
1268
+ options: {
1269
+ data: [{
1270
+ label: "",
1271
+ data: choices.map((k) => {
1272
+ return {
1273
+ primary: truncateWithEllipses(k, 50),
1274
+ secondary: labelMap[k]
1275
+ };
1276
+ })
1277
+ }],
1278
+ primaryAxis,
1279
+ secondaryAxes
1280
+ }
1281
+ }
1282
+ ))));
1283
+ }
1284
+ return /* @__PURE__ */ React__namespace.createElement(core.Card, { key: row.question, withBorder: true, p: "xl", radius: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 4 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { size: "lg" }, row.question), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm" }, row.answers.length, " answers"), /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 4 }, row.answers.map((a) => {
1285
+ const answerText = a.join("\n");
1286
+ return /* @__PURE__ */ React__namespace.createElement(core.Card, { key: answerText, p: 5, radius: 0, bg: "gray.0" }, /* @__PURE__ */ React__namespace.createElement(core.Text, null, answerText));
1287
+ })))));
1288
+ });
1289
+ return /* @__PURE__ */ React__namespace.createElement(core.Stack, { py: 4, spacing: 10, sx: { minWidth: 700 } }, rows);
1290
+ }
1291
+ const truncateWithEllipses = (text, max) => text.substr(0, max - 1) + (text.length > max ? "&hellip;" : "");
1292
+
1293
+ const useStyles$3 = core.createStyles((theme) => ({
1294
+ title: {
1295
+ fontSize: 34,
1296
+ fontWeight: 900,
1297
+ [theme.fn.smallerThan("sm")]: {
1298
+ fontSize: 24
1299
+ }
1300
+ },
1301
+ description: {
1302
+ maxWidth: 600
1303
+ }
1304
+ }));
1305
+ const Lesson = (props) => {
1306
+ const { classes } = useStyles$3();
1307
+ const [tab, setTab] = React.useState("question");
1308
+ const numberOfStudents = props.students.length;
1309
+ const percentageOfLessonsCompleted = numberOfStudents > 0 ? props.students.filter((u) => u.isComplete).length / numberOfStudents : 0;
1310
+ return /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid, null, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "auto" }, /* @__PURE__ */ React__namespace.createElement(
1311
+ core.Badge,
1312
+ {
1313
+ variant: "filled",
1314
+ leftSection: /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { onClick: props.onBackClick, color: "blue", size: "xs", radius: "xl", variant: "filled" }, /* @__PURE__ */ React__namespace.createElement(icons.IconArrowLeft, { size: 14 })),
1315
+ size: "lg"
1316
+ },
1317
+ "Lessons"
1318
+ ), /* @__PURE__ */ React__namespace.createElement(core.Group, null, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, props.displayName || "Lesson"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, props.description || "No description")), /* @__PURE__ */ React__namespace.createElement(core.Stack, { ml: "auto" }, /* @__PURE__ */ React__namespace.createElement(
1319
+ core.Button,
1320
+ {
1321
+ variant: "gradient",
1322
+ onClick: props.onPreviewClick
1323
+ },
1324
+ "Preview"
1325
+ ))))), /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(core.Stack, null, /* @__PURE__ */ React__namespace.createElement(StatsGroup, { data: [
1326
+ {
1327
+ title: "LESSON COMPLETION",
1328
+ value: percentageOfLessonsCompleted,
1329
+ unit: "%"
1330
+ }
1331
+ ] }), /* @__PURE__ */ React__namespace.createElement(
1332
+ core.Select,
1333
+ {
1334
+ clearable: true,
1335
+ clearButtonLabel: "Clear class selection",
1336
+ size: "sm",
1337
+ placeholder: "Select a class",
1338
+ nothingFound: "No options",
1339
+ value: props.classId,
1340
+ onChange: props.onClassChange,
1341
+ icon: /* @__PURE__ */ React__namespace.createElement(icons.IconCategory2, null),
1342
+ data: props.classes.map((g) => {
1343
+ return { value: g.classId, label: g.name };
1344
+ })
1345
+ }
1346
+ ), /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
1347
+ Tabs,
1348
+ {
1349
+ value: tab,
1350
+ data: [
1351
+ { label: "By question", value: "question" },
1352
+ { label: "By reflection", value: "reflections" },
1353
+ { label: "By student", value: "students" }
1354
+ ],
1355
+ onChange: setTab
1356
+ }
1357
+ ), tab === "question" && /* @__PURE__ */ React__namespace.createElement(
1358
+ Stack,
1359
+ {
1360
+ loading: props.loading,
1361
+ items: props.questions
1362
+ }
1363
+ ), tab === "reflections" && /* @__PURE__ */ React__namespace.createElement(
1364
+ Table$2,
1365
+ {
1366
+ loading: props.loading,
1367
+ items: props.reflections
1368
+ }
1369
+ ), tab === "students" && /* @__PURE__ */ React__namespace.createElement(
1370
+ Table$1,
1371
+ {
1372
+ loading: props.loading,
1373
+ items: props.students,
1374
+ onClick: props.onUserClick
1375
+ }
1376
+ )))))));
1377
+ };
1378
+
1379
+ function Table(props) {
1380
+ if (props.items.length === 0) {
1381
+ return /* @__PURE__ */ React__namespace.createElement(
1382
+ PlaceholderBanner,
1383
+ {
1384
+ title: "No lessons to display",
1385
+ description: "We don't have any lessons to show you just yet.",
1386
+ loading: props.loading,
1387
+ icon: "lessons"
1388
+ }
1389
+ );
1390
+ }
1391
+ const rows = props.items.map((row) => /* @__PURE__ */ React__namespace.createElement("tr", { key: row.lessonId }, /* @__PURE__ */ React__namespace.createElement("td", null, /* @__PURE__ */ React__namespace.createElement(
1392
+ core.UnstyledButton,
1393
+ {
1394
+ sx: (theme) => ({
1395
+ display: "block",
1396
+ width: "100%",
1397
+ padding: theme.spacing.md,
1398
+ color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.black,
1399
+ "&:hover": {
1400
+ backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.colors.gray[1]
1401
+ }
1402
+ }),
1403
+ onClick: () => props.onClick && props.onClick(row)
1404
+ },
1405
+ /* @__PURE__ */ React__namespace.createElement(core.Group, null, /* @__PURE__ */ React__namespace.createElement("div", null, /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "sm", weight: 500 }, row.name), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xs", color: "dimmed" }, row.description)))
1406
+ ))));
1407
+ return /* @__PURE__ */ React__namespace.createElement(core.ScrollArea.Autosize, { maxHeight: 500 }, /* @__PURE__ */ React__namespace.createElement(core.Table, { horizontalSpacing: 0, verticalSpacing: 0, sx: { minWidth: 700 } }, /* @__PURE__ */ React__namespace.createElement("tbody", null, rows)));
1408
+ }
1409
+
1410
+ const useStyles$2 = core.createStyles((theme) => ({
1411
+ title: {
1412
+ fontSize: 34,
1413
+ fontWeight: 900,
1414
+ [theme.fn.smallerThan("sm")]: {
1415
+ fontSize: 24
1416
+ }
1417
+ },
1418
+ description: {
1419
+ maxWidth: 600
1420
+ }
1421
+ }));
1422
+ const Lessons = (props) => {
1423
+ const { classes } = useStyles$2();
1424
+ return /* @__PURE__ */ React__namespace.createElement(core.Container, { size: "lg", py: "xl" }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { spacing: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Grid, null, /* @__PURE__ */ React__namespace.createElement(core.Grid.Col, { sm: "auto" }, /* @__PURE__ */ React__namespace.createElement(core.Badge, { variant: "filled", size: "lg" }, "Lessons"), /* @__PURE__ */ React__namespace.createElement(core.Title, { order: 2, className: classes.title, mt: "md" }, "Lessons"), /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", className: classes.description, mt: "sm" }, "Explore units of instruction and/or see corresponding class progress."))), /* @__PURE__ */ React__namespace.createElement(
1425
+ core.Autocomplete,
1426
+ {
1427
+ placeholder: "Search for a lesson that fits your needs",
1428
+ data: props.lessons.map((item) => item.name),
1429
+ onChange: props.onAutocompleteChange
1430
+ }
1431
+ ), /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__namespace.createElement(core.LoadingOverlay, { visible: props.loading, overlayBlur: 2 }), /* @__PURE__ */ React__namespace.createElement(
1432
+ Table,
1433
+ {
1434
+ loading: props.loading,
1435
+ items: props.lessons,
1436
+ onClick: props.onLessonClick
1437
+ }
1438
+ ))));
1439
+ };
1440
+
1441
+ const mycCache = core.createEmotionCache({
1442
+ key: "mantine",
1443
+ prepend: false
1444
+ });
1445
+ const AdminProvider = (props) => {
1446
+ return /* @__PURE__ */ React__namespace.createElement(core.MantineProvider, { withNormalizeCSS: true, withGlobalStyles: true, emotionCache: mycCache, theme: { loader: "bars" } }, /* @__PURE__ */ React__namespace.createElement(notifications.NotificationsProvider, { limit: props.notificationLimit || 5 }, /* @__PURE__ */ React__namespace.createElement(modals.ModalsProvider, null, props.children)));
1447
+ };
1448
+
1449
+ var __defProp = Object.defineProperty;
1450
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
1451
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
1452
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
1453
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1454
+ var __spreadValues = (a, b) => {
1455
+ for (var prop in b || (b = {}))
1456
+ if (__hasOwnProp.call(b, prop))
1457
+ __defNormalProp(a, prop, b[prop]);
1458
+ if (__getOwnPropSymbols)
1459
+ for (var prop of __getOwnPropSymbols(b)) {
1460
+ if (__propIsEnum.call(b, prop))
1461
+ __defNormalProp(a, prop, b[prop]);
1462
+ }
1463
+ return a;
1464
+ };
1465
+ const SwitchAccount = (props) => {
1466
+ const form$1 = form.useForm({
1467
+ initialValues: {
1468
+ active: props.account
1469
+ }
1470
+ });
1471
+ return /* @__PURE__ */ React__namespace.createElement(
1472
+ core.Modal,
1473
+ {
1474
+ centered: true,
1475
+ opened: props.opened,
1476
+ onClose: () => props.onClose && props.onClose(),
1477
+ size: "sm",
1478
+ title: /* @__PURE__ */ React__namespace.createElement(core.Title, { size: "h5" }, "Accounts")
1479
+ },
1480
+ /* @__PURE__ */ React__namespace.createElement("form", { onSubmit: form$1.onSubmit(() => {
1481
+ props.onChange && props.onChange(form$1.values.active);
1482
+ }) }, /* @__PURE__ */ React__namespace.createElement(
1483
+ core.Select,
1484
+ __spreadValues({
1485
+ required: true,
1486
+ placeholder: "Select an account",
1487
+ defaultValue: props.account,
1488
+ data: props.accounts.map((a) => {
1489
+ return { value: a.accountId, label: a.name };
1490
+ })
1491
+ }, form$1.getInputProps("active"))
1492
+ ), /* @__PURE__ */ React__namespace.createElement(core.Button, { type: "submit", fullWidth: true, mt: "xl" }, "Switch"))
1493
+ );
1494
+ };
1495
+
1496
+ const useStyles$1 = core.createStyles((theme) => ({
1497
+ link: {
1498
+ width: 50,
1499
+ height: 50,
1500
+ borderRadius: theme.radius.md,
1501
+ display: "flex",
1502
+ alignItems: "center",
1503
+ justifyContent: "center",
1504
+ color: theme.colorScheme === "dark" ? theme.colors.dark[0] : theme.colors.gray[7],
1505
+ "&:hover": {
1506
+ backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[5] : theme.colors.gray[0]
1507
+ }
1508
+ },
1509
+ active: {
1510
+ "&, &:hover": {
1511
+ backgroundColor: theme.fn.variant({ variant: "light", color: theme.primaryColor }).background,
1512
+ color: theme.fn.variant({ variant: "light", color: theme.primaryColor }).color
1513
+ }
1514
+ }
1515
+ }));
1516
+ const data = [
1517
+ { icon: icons.IconHome2, label: "Home", href: "/home" },
1518
+ { icon: icons.IconGauge, label: "Dashboard", href: "/dashboard" },
1519
+ { icon: icons.IconCategory2, label: "Classes", href: "/classes" },
1520
+ { icon: icons.IconAlbum, label: "Badges", href: "/badges" },
1521
+ { icon: icons.IconLambda, label: "Lessons", href: "/lessons" }
1522
+ ];
1523
+ const NavbarLink = ({ icon: Icon, label, active, onClick }) => {
1524
+ const { classes, cx } = useStyles$1();
1525
+ return /* @__PURE__ */ React__namespace.createElement(core.Tooltip, { label, position: "right", transitionDuration: 0 }, /* @__PURE__ */ React__namespace.createElement(core.UnstyledButton, { onClick, className: cx(classes.link, { [classes.active]: active }) }, /* @__PURE__ */ React__namespace.createElement(Icon, { stroke: 1.5 })));
1526
+ };
1527
+ const Navbar = (props) => {
1528
+ const links = data.map((link) => /* @__PURE__ */ React__namespace.createElement(
1529
+ NavbarLink,
1530
+ {
1531
+ key: link.label,
1532
+ label: link.label,
1533
+ icon: link.icon,
1534
+ active: link.label === props.active,
1535
+ onClick: () => props.navigate(link.href)
1536
+ }
1537
+ ));
1538
+ return /* @__PURE__ */ React__namespace.createElement(core.Navbar, { width: { base: 80 }, p: "md" }, /* @__PURE__ */ React__namespace.createElement(core.Center, null, /* @__PURE__ */ React__namespace.createElement(core.Avatar, { color: "blue", radius: "sm" }, /* @__PURE__ */ React__namespace.createElement("div", { style: { width: 15, marginLeft: "auto", marginRight: "auto" } }, /* @__PURE__ */ React__namespace.createElement(core.Image, { fit: "contain", src: "https://cdn.localcivics.io/brand/l.png" })))), /* @__PURE__ */ React__namespace.createElement(core.Navbar.Section, { grow: true, mt: 50 }, /* @__PURE__ */ React__namespace.createElement(core.Stack, { justify: "center", spacing: 0 }, links)), /* @__PURE__ */ React__namespace.createElement(core.Navbar.Section, null, /* @__PURE__ */ React__namespace.createElement(core.Stack, { justify: "center", spacing: 0 }, /* @__PURE__ */ React__namespace.createElement(
1539
+ NavbarLink,
1540
+ {
1541
+ icon: icons.IconSwitchHorizontal,
1542
+ label: "Switch accounts",
1543
+ onClick: props.onSwitchAccounts
1544
+ }
1545
+ ), /* @__PURE__ */ React__namespace.createElement(
1546
+ NavbarLink,
1547
+ {
1548
+ icon: icons.IconLogout,
1549
+ label: "Logout",
1550
+ onClick: props.onLogout
1551
+ }
1552
+ ))));
1553
+ };
1554
+
1555
+ const useStyles = core.createStyles((theme) => ({
1556
+ footer: {
1557
+ paddingTop: theme.spacing.xl * 2,
1558
+ paddingBottom: theme.spacing.xl * 2,
1559
+ paddingLeft: theme.spacing.xl * 3,
1560
+ backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[0],
1561
+ borderTop: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[5] : theme.colors.gray[2]}`
1562
+ },
1563
+ logo: {
1564
+ maxWidth: 200,
1565
+ [theme.fn.smallerThan("sm")]: {
1566
+ display: "flex",
1567
+ flexDirection: "column",
1568
+ alignItems: "center"
1569
+ }
1570
+ },
1571
+ description: {
1572
+ marginTop: 5,
1573
+ [theme.fn.smallerThan("sm")]: {
1574
+ marginTop: theme.spacing.xs,
1575
+ textAlign: "center"
1576
+ }
1577
+ },
1578
+ inner: {
1579
+ display: "flex",
1580
+ justifyContent: "space-between",
1581
+ [theme.fn.smallerThan("sm")]: {
1582
+ flexDirection: "column",
1583
+ alignItems: "center"
1584
+ }
1585
+ },
1586
+ groups: {
1587
+ display: "flex",
1588
+ flexWrap: "wrap",
1589
+ [theme.fn.smallerThan("sm")]: {
1590
+ display: "none"
1591
+ }
1592
+ },
1593
+ wrapper: {
1594
+ width: 160
1595
+ },
1596
+ link: {
1597
+ display: "block",
1598
+ color: theme.colorScheme === "dark" ? theme.colors.dark[1] : theme.colors.gray[6],
1599
+ fontSize: theme.fontSizes.sm,
1600
+ paddingTop: 3,
1601
+ paddingBottom: 3,
1602
+ "&:hover": {
1603
+ textDecoration: "underline"
1604
+ }
1605
+ },
1606
+ title: {
1607
+ fontSize: theme.fontSizes.md,
1608
+ fontWeight: 700,
1609
+ fontFamily: `Greycliff CF, ${theme.fontFamily}`,
1610
+ marginBottom: theme.spacing.xs / 2,
1611
+ color: theme.colorScheme === "dark" ? theme.white : theme.black
1612
+ },
1613
+ afterFooter: {
1614
+ display: "flex",
1615
+ justifyContent: "space-between",
1616
+ alignItems: "center",
1617
+ marginTop: theme.spacing.xl,
1618
+ paddingTop: theme.spacing.xl,
1619
+ paddingBottom: theme.spacing.xl,
1620
+ borderTop: `1px solid ${theme.colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[2]}`,
1621
+ [theme.fn.smallerThan("sm")]: {
1622
+ flexDirection: "column"
1623
+ }
1624
+ },
1625
+ social: {
1626
+ [theme.fn.smallerThan("sm")]: {
1627
+ marginTop: theme.spacing.xs
1628
+ }
1629
+ }
1630
+ }));
1631
+ const App = (props) => {
1632
+ const { classes } = useStyles();
1633
+ const account = useAccount(props.account, props.accounts, props.onAccountChange);
1634
+ return /* @__PURE__ */ React__namespace.createElement(
1635
+ core.AppShell,
1636
+ {
1637
+ padding: "xs",
1638
+ navbar: /* @__PURE__ */ React__namespace.createElement(
1639
+ Navbar,
1640
+ {
1641
+ active: props.navbar.props.active,
1642
+ navigate: props.navbar.props.navigate,
1643
+ onLogout: props.navbar.props.onLogout,
1644
+ onSwitchAccounts: () => account.setChangeModalOpen(true)
1645
+ }
1646
+ ),
1647
+ footer: /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, !account.opened && /* @__PURE__ */ React__namespace.createElement("footer", { className: classes.footer }, /* @__PURE__ */ React__namespace.createElement(core.Container, { className: classes.inner }, /* @__PURE__ */ React__namespace.createElement("div", { className: classes.logo }, /* @__PURE__ */ React__namespace.createElement(core.Group, { spacing: "xs" }, /* @__PURE__ */ React__namespace.createElement("div", { style: { width: 15 } }, /* @__PURE__ */ React__namespace.createElement(core.Image, { fit: "contain", src: "https://cdn.localcivics.io/brand/l.png" })), /* @__PURE__ */ React__namespace.createElement(core.Title, { color: "dimmed", size: "h5" }, "Local Civics")), /* @__PURE__ */ React__namespace.createElement(core.Text, { size: "xs", color: "dimmed", className: classes.description }, "We connect students to powerful civic learning experiences.")), /* @__PURE__ */ React__namespace.createElement("div", { className: classes.groups }, /* @__PURE__ */ React__namespace.createElement("div", { className: classes.wrapper }, /* @__PURE__ */ React__namespace.createElement(
1648
+ core.Text,
1649
+ {
1650
+ className: classes.link,
1651
+ component: "a",
1652
+ href: "https://www.localcivics.io",
1653
+ target: "_blank"
1654
+ },
1655
+ "About"
1656
+ ), /* @__PURE__ */ React__namespace.createElement(
1657
+ core.Text,
1658
+ {
1659
+ className: classes.link,
1660
+ component: "a",
1661
+ href: "https://www.localcivics.io/terms-of-service",
1662
+ target: "_blank"
1663
+ },
1664
+ "Terms"
1665
+ ), /* @__PURE__ */ React__namespace.createElement(
1666
+ core.Text,
1667
+ {
1668
+ className: classes.link,
1669
+ component: "a",
1670
+ href: "https://www.localcivics.io/privacy-policy",
1671
+ target: "_blank"
1672
+ },
1673
+ "Privacy"
1674
+ ), /* @__PURE__ */ React__namespace.createElement(
1675
+ core.Text,
1676
+ {
1677
+ className: classes.link,
1678
+ component: "a",
1679
+ href: "https://localcivics.notion.site/Help-Center-b52300f587b64fc0a61f512686e7626d",
1680
+ target: "_blank"
1681
+ },
1682
+ "Help Center"
1683
+ )))), /* @__PURE__ */ React__namespace.createElement(core.Container, { className: classes.afterFooter }, /* @__PURE__ */ React__namespace.createElement(core.Text, { color: "dimmed", size: "sm" }, "\xA9 ", new Date().getFullYear(), " Local Civics. All rights reserved."), /* @__PURE__ */ React__namespace.createElement(core.Group, { spacing: 0, className: classes.social, position: "right", noWrap: true }, /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { component: "a", target: "_blank", href: "https://www.instagram.com/localcivics/", size: "lg" }, /* @__PURE__ */ React__namespace.createElement(icons.IconBrandInstagram, { size: 18, stroke: 1.5 })), /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { component: "a", target: "_blank", href: "https://www.linkedin.com/company/localcivics", size: "lg" }, /* @__PURE__ */ React__namespace.createElement(icons.IconBrandLinkedin, { size: 18, stroke: 1.5 })), /* @__PURE__ */ React__namespace.createElement(core.ActionIcon, { component: "a", target: "_blank", href: "https://www.facebook.com/localcivics/", size: "lg" }, /* @__PURE__ */ React__namespace.createElement(icons.IconBrandFacebook, { size: 18, stroke: 1.5 })))))),
1684
+ styles: (theme) => ({
1685
+ main: { backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[8] : theme.colors.gray[0] }
1686
+ })
1687
+ },
1688
+ /* @__PURE__ */ React__namespace.createElement("div", { style: { position: "relative" } }, (props.loading || account.opened) && /* @__PURE__ */ React__namespace.createElement(core.Center, { style: { height: 400 } }, /* @__PURE__ */ React__namespace.createElement(core.Loader, null)), !props.loading && !account.opened && props.page),
1689
+ /* @__PURE__ */ React__namespace.createElement(
1690
+ SwitchAccount,
1691
+ {
1692
+ opened: account.opened,
1693
+ account: account.account,
1694
+ accounts: account.accounts,
1695
+ onChange: account.onAccountChange,
1696
+ onClose: () => account.setChangeModalOpen(false)
1697
+ }
1698
+ )
1699
+ );
1700
+ };
1701
+ const useAccount = (account, accounts, onAccountChange) => {
1702
+ const accountsKey = JSON.stringify(accounts);
1703
+ const [changeModalOpen, setChangeModalOpen] = React.useState(false);
1704
+ const [active, setActive] = React.useState(account);
1705
+ React__namespace.useEffect(() => {
1706
+ setActive(account);
1707
+ }, [account, accountsKey]);
1708
+ return {
1709
+ opened: changeModalOpen,
1710
+ account: active,
1711
+ accounts,
1712
+ setChangeModalOpen,
1713
+ onAccountChange: (account2) => {
1714
+ setActive(account2);
1715
+ setChangeModalOpen(false);
1716
+ onAccountChange(account2);
1717
+ }
1718
+ };
1719
+ };
1720
+
1721
+ Object.defineProperty(exports, 'showNotification', {
1722
+ enumerable: true,
1723
+ get: function () { return notifications.showNotification; }
1724
+ });
1725
+ Object.defineProperty(exports, 'updateNotification', {
1726
+ enumerable: true,
1727
+ get: function () { return notifications.updateNotification; }
1728
+ });
1729
+ exports.AdminProvider = AdminProvider;
1730
+ exports.App = App;
1731
+ exports.Badge = Badge;
1732
+ exports.Badges = Badges;
1733
+ exports.Class = Class;
1734
+ exports.Classes = Classes;
1735
+ exports.Dashboard = Dashboard;
1736
+ exports.Home = Home;
1737
+ exports.Lesson = Lesson;
1738
+ exports.Lessons = Lessons;
1739
+ exports.Navbar = Navbar;
1740
+ exports.Student = Student;
1741
+ exports.SwitchAccount = SwitchAccount;
1742
+ //# sourceMappingURL=index.js.map