@vue-skuilder/platform-ui 0.1.34 → 0.1.36

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 (114) hide show
  1. package/dist/assets/{About-BpqIdlZQ.js → About-eVevEMqh.js} +2 -2
  2. package/dist/assets/{About-BpqIdlZQ.js.map → About-eVevEMqh.js.map} +1 -1
  3. package/dist/assets/AdminDashboard-C_oJ8NGZ.js +2 -0
  4. package/dist/assets/{AdminDashboard-BObO6egG.js.map → AdminDashboard-C_oJ8NGZ.js.map} +1 -1
  5. package/dist/assets/{ClassroomCtrlPanel-lgN6cdTd.js → ClassroomCtrlPanel-DanEeAZ0.js} +2 -2
  6. package/dist/assets/{ClassroomCtrlPanel-lgN6cdTd.js.map → ClassroomCtrlPanel-DanEeAZ0.js.map} +1 -1
  7. package/dist/assets/{Classrooms-BWoQ4i1_.js → Classrooms-OrG6VOnx.js} +2 -2
  8. package/dist/assets/{Classrooms-BWoQ4i1_.js.map → Classrooms-OrG6VOnx.js.map} +1 -1
  9. package/dist/assets/{CourseRouter-CODD0Qm5.js → CourseRouter-CK8Xh2h2.js} +3 -3
  10. package/dist/assets/{CourseRouter-CODD0Qm5.js.map → CourseRouter-CK8Xh2h2.js.map} +1 -1
  11. package/dist/assets/CourseWare-BTFRjgBR-D750E7i0.css +1 -0
  12. package/dist/assets/CourseWare-BTFRjgBR-OzjKW1B2.js +3 -0
  13. package/dist/assets/CourseWare-BTFRjgBR-OzjKW1B2.js.map +1 -0
  14. package/dist/assets/{Courses-ClDdLQUO.js → Courses-DB0JFz1Q.js} +2 -2
  15. package/dist/assets/{Courses-ClDdLQUO.js.map → Courses-DB0JFz1Q.js.map} +1 -1
  16. package/dist/assets/EloModeration-BmU0CqZt.js +2 -0
  17. package/dist/assets/{EloModeration-B6LM11G_.js.map → EloModeration-BmU0CqZt.js.map} +1 -1
  18. package/dist/assets/{JoinCode-DgPD_OFL.js → JoinCode-KoSLXpUy.js} +2 -2
  19. package/dist/assets/{JoinCode-DgPD_OFL.js.map → JoinCode-KoSLXpUy.js.map} +1 -1
  20. package/dist/assets/{MarkdownRenderer-DoVbFpA6-BIbDxYC4.js → MarkdownRenderer-DoVbFpA6-CvaBjTS8.js} +2 -2
  21. package/dist/assets/{MarkdownRenderer-DoVbFpA6-BIbDxYC4.js.map → MarkdownRenderer-DoVbFpA6-CvaBjTS8.js.map} +1 -1
  22. package/dist/assets/MarkdownRenderer-DoVbFpA6-DZdbKtns.js +1 -0
  23. package/dist/assets/{NewCourseDialog-DhwvBT3y.js → NewCourseDialog-BXxQ1cvK.js} +2 -2
  24. package/dist/assets/{NewCourseDialog-DhwvBT3y.js.map → NewCourseDialog-BXxQ1cvK.js.map} +1 -1
  25. package/dist/assets/{ReleaseNotes-DtwDIIfH.js → ReleaseNotes-CERYwZro.js} +2 -2
  26. package/dist/assets/{ReleaseNotes-DtwDIIfH.js.map → ReleaseNotes-CERYwZro.js.map} +1 -1
  27. package/dist/assets/{RequestPasswordReset-DBv0XCIk.js → RequestPasswordReset-Bc4FHaYS.js} +2 -2
  28. package/dist/assets/{RequestPasswordReset-DBv0XCIk.js.map → RequestPasswordReset-Bc4FHaYS.js.map} +1 -1
  29. package/dist/assets/{ResetPassword-BtBplqsQ.js → ResetPassword-CeR_bmOz.js} +2 -2
  30. package/dist/assets/{ResetPassword-BtBplqsQ.js.map → ResetPassword-CeR_bmOz.js.map} +1 -1
  31. package/dist/assets/Study-voro05GB.js +2 -0
  32. package/dist/assets/{Study-D9W1DKes.js.map → Study-voro05GB.js.map} +1 -1
  33. package/dist/assets/TagInformation-1urKQaI-.js +2 -0
  34. package/dist/assets/{TagInformation-DgUkKxoU.js.map → TagInformation-1urKQaI-.js.map} +1 -1
  35. package/dist/assets/{User-DorFkRx_.js → User-26Hebdw-.js} +2 -2
  36. package/dist/assets/{User-DorFkRx_.js.map → User-26Hebdw-.js.map} +1 -1
  37. package/dist/assets/{UserStats-ck9Oh4qt.js → UserStats-DbWUnAPD.js} +2 -2
  38. package/dist/assets/{UserStats-ck9Oh4qt.js.map → UserStats-DbWUnAPD.js.map} +1 -1
  39. package/dist/assets/{VerifyEmail-BYt5xfhm.js → VerifyEmail-uix17ueS.js} +2 -2
  40. package/dist/assets/{VerifyEmail-BYt5xfhm.js.map → VerifyEmail-uix17ueS.js.map} +1 -1
  41. package/dist/assets/chess-BbHATAzk-BhFAwbgX.js +7 -0
  42. package/dist/assets/chess-BbHATAzk-BhFAwbgX.js.map +1 -0
  43. package/dist/assets/chess-BbHATAzk-DB7z_kWx.css +1 -0
  44. package/dist/assets/chess-X1bmWmh3-C7B3mHa1.js +1 -0
  45. package/dist/assets/common-ui.es-C18SEA_L.js +1 -0
  46. package/dist/assets/{common-ui.es-BrXWBn7p.js → common-ui.es-p3cgaI_b.js} +5 -5
  47. package/dist/assets/{common-ui.es-BrXWBn7p.js.map → common-ui.es-p3cgaI_b.js.map} +1 -1
  48. package/dist/assets/dist-CszlUrrD.js +1 -0
  49. package/dist/assets/dist-D2Tzeiyw.js +1 -0
  50. package/dist/assets/{dist-CzLl7g6t.js → dist-DA7EuQY2.js} +34 -12
  51. package/dist/assets/dist-DA7EuQY2.js.map +1 -0
  52. package/dist/assets/dist-DCY40cJ7.js +18 -0
  53. package/dist/assets/dist-DCY40cJ7.js.map +1 -0
  54. package/dist/assets/{dist-CrcJCHFk.js → dist-leWgtXBf.js} +2 -2
  55. package/dist/assets/dist-leWgtXBf.js.map +1 -0
  56. package/dist/assets/edit-ui.es-BIV0deYk.js +36 -0
  57. package/dist/assets/{edit-ui.es-C9MhXwkt.js.map → edit-ui.es-BIV0deYk.js.map} +1 -1
  58. package/dist/assets/edit-ui.es-BLMFpJm1.js +1 -0
  59. package/dist/assets/french-Dk7YG8Td-YK4jNZUN.js +2 -0
  60. package/dist/assets/french-Dk7YG8Td-YK4jNZUN.js.map +1 -0
  61. package/dist/assets/french-evUMlbbq-BbJDdRqK.js +1 -0
  62. package/dist/assets/index-B-cSF0fq.js +4 -0
  63. package/dist/assets/index-B-cSF0fq.js.map +1 -0
  64. package/dist/assets/{index-C8gy3Ea0.css → index-CmEEzdUX.css} +1 -1
  65. package/dist/assets/math-B4HbgYf6-CLJIZTjv.js +34 -0
  66. package/dist/assets/math-B4HbgYf6-CLJIZTjv.js.map +1 -0
  67. package/dist/assets/math-B4HbgYf6-CZyvKZtp.css +1 -0
  68. package/dist/assets/math-DYni7rRl-C6a4BDoN.js +1 -0
  69. package/dist/assets/piano-BN5Btq91-Cdn8kuW5.js +1 -0
  70. package/dist/assets/piano-DF1g6yaX-AR14jqWm.js +2 -0
  71. package/dist/assets/piano-DF1g6yaX-AR14jqWm.js.map +1 -0
  72. package/dist/assets/piano-DF1g6yaX-BLvDAgl1.css +1 -0
  73. package/dist/assets/pitch-CgGJFkZ1-DYkp_AV0.js +2 -0
  74. package/dist/assets/pitch-CgGJFkZ1-DYkp_AV0.js.map +1 -0
  75. package/dist/assets/pitch-Dn0iNqiS-CJ_97iB4.js +1 -0
  76. package/dist/assets/{server-Db_WegNj.js → server-Bq50faqp.js} +2 -2
  77. package/dist/assets/{server-Db_WegNj.js.map → server-Bq50faqp.js.map} +1 -1
  78. package/dist/assets/sightsing-BFQ7HRig-BNrrORP_.js +133 -0
  79. package/dist/assets/sightsing-BFQ7HRig-BNrrORP_.js.map +1 -0
  80. package/dist/assets/sightsing-BFQ7HRig-DkUGf5Yf.css +1 -0
  81. package/dist/assets/sightsing-CJX3k0Fd-l4fhB1Aj.js +1 -0
  82. package/dist/assets/typing-BevtfWlp-B7ZMUAQJ.css +1 -0
  83. package/dist/assets/typing-BevtfWlp-Cl6jtRmX.js +2 -0
  84. package/dist/assets/typing-BevtfWlp-Cl6jtRmX.js.map +1 -0
  85. package/dist/assets/typing-k-ojjO7G-CHgxm7Rx.js +1 -0
  86. package/dist/assets/word-work-BOnRlZgd-CGV2xRx9.js +2 -0
  87. package/dist/assets/word-work-BOnRlZgd-CGV2xRx9.js.map +1 -0
  88. package/dist/assets/word-work-Dd6tIKrt-BjF3-3lq.js +1 -0
  89. package/dist/index.html +6 -6
  90. package/dist/sw.js +1 -1
  91. package/dist/sw.js.map +1 -1
  92. package/package.json +7 -7
  93. package/src/dev/Playtest.vue +254 -0
  94. package/src/main.ts +13 -2
  95. package/src/router.ts +17 -17
  96. package/dist/assets/AdminDashboard-BObO6egG.js +0 -2
  97. package/dist/assets/DataInputFormTester-ywHjm2yC.js +0 -2
  98. package/dist/assets/DataInputFormTester-ywHjm2yC.js.map +0 -1
  99. package/dist/assets/EloModeration-B6LM11G_.js +0 -2
  100. package/dist/assets/MarkdownRenderer-DoVbFpA6-CQGwEJFh.js +0 -1
  101. package/dist/assets/Study-D9W1DKes.js +0 -2
  102. package/dist/assets/TagInformation-DgUkKxoU.js +0 -2
  103. package/dist/assets/common-ui.es-DKUQOgQx.js +0 -1
  104. package/dist/assets/dist-5cG6aSxW.js +0 -1
  105. package/dist/assets/dist-CrcJCHFk.js.map +0 -1
  106. package/dist/assets/dist-CzLl7g6t.js.map +0 -1
  107. package/dist/assets/dist-D5-LrzD6.js +0 -186
  108. package/dist/assets/dist-D5-LrzD6.js.map +0 -1
  109. package/dist/assets/dist-y6_rrqhr.js +0 -1
  110. package/dist/assets/edit-ui.es-C9MhXwkt.js +0 -36
  111. package/dist/assets/edit-ui.es-DT9CMaNG.js +0 -1
  112. package/dist/assets/index-DUZItsH-.js +0 -4
  113. package/dist/assets/index-DUZItsH-.js.map +0 -1
  114. package/src/dev/DataInputFormTester.vue +0 -117
@@ -0,0 +1 @@
1
+ canvas[data-v-f91502f8]{margin-left:auto;margin-right:auto;padding:10px;display:block}img[data-v-f91502f8]{max-width:100%;max-height:60vh;margin-left:auto;margin-right:auto;padding:10px;display:block}
@@ -0,0 +1,3 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/common-ui.es-C18SEA_L.js","assets/dist-leWgtXBf.js","assets/chunk-D6hFPZc3.js","assets/common-ui.es-p3cgaI_b.js","assets/dist-DA7EuQY2.js","assets/vue.runtime.esm-bundler-C3q8JS9f.js","assets/MarkdownRenderer-DoVbFpA6-CvaBjTS8.js","assets/common-ui-BY2Ut5jf.css"])))=>i.map(i=>d[i]);
2
+ import{a as e}from"./chunk-D6hFPZc3.js";import{$ as t,B as n,C as r,H as i,K as a,S as o,T as s,Vt as c,W as l,Z as u,_ as d,b as f,f as p,g as m,lt as h,v as g,w as _,y as v,z as y}from"./vue.runtime.esm-bundler-C3q8JS9f.js";import{H as b,m as x,w as S}from"./common-ui.es-p3cgaI_b.js";import{S as C,n as w,y as T}from"./dist-leWgtXBf.js";import{C as E,S as D,_ as O,d as k,o as A,x as j}from"./MarkdownRenderer-DoVbFpA6-CvaBjTS8.js";var M=Object.create,N=Object.defineProperty,__name=(e,t)=>N(e,`name`,{value:t,configurable:!0}),P=Object.getOwnPropertyDescriptor,F=Object.getOwnPropertyNames,I=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty,__commonJSMin=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),__copyProps=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=F(t),a=0,o=i.length,s;a<o;a++)s=i[a],!L.call(e,s)&&s!==n&&N(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=P(t,s))||r.enumerable});return e},__toESM=(e,t,n)=>(n=e==null?{}:M(I(e)),__copyProps(t||!e||!e.__esModule?N(n,`default`,{value:e,enumerable:!0}):n,e)),R=(t=>typeof e<`u`?e:typeof Proxy<`u`?new Proxy(t,{get:(t,n)=>(typeof e<`u`?e:t)[n]}):t)(function(t){if(typeof e<`u`)return e.apply(this,arguments);throw Error('Calling `require` for "'+t+"\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.")}),z=[{name:w.Blanks,fields:[{name:`Input`,type:C.MARKDOWN},{name:`Uploads`,type:C.MEDIA_UPLOADS}]}],B;function randomInt(e,t){return Math.floor(Math.random()*(t-e+1))+e}function shuffle(e){let t=[...e];for(let e=t.length-1;e>0;e--){let n=Math.floor(Math.random()*(e+1));[t[e],t[n]]=[t[n],t[e]]}return t}function cos(e){return Math.cos(toRadians(e))}function sin(e){return Math.sin(toRadians(e))}function toRadians(e){return e/360*2*Math.PI}function gradeSpellingAttempt(e,t){let n=Array(t.length).fill(`_`),r=e.split(``);console.log(e,t),console.log(`Attempt char codes:`,e.split(``).map(e=>e.charCodeAt(0))),console.log(`Answer char codes:`,t.split(``).map(e=>e.charCodeAt(0)));for(let e=0;e<t.length;e++)e<r.length&&r[e]===t[e]&&(n[e]=r[e],r[e]=``);for(let e=t.length-1;e>=0;e--)if(n[e]===`_`){let i=r.findIndex(n=>n===t[e]);i!==-1&&(n[e]=t[e],r[i]=``)}return console.log(n.join(` `)),n.join(` `)}var V=s({name:`FillInView`,components:{MarkdownRenderer:_(()=>b(()=>import(`./common-ui.es-C18SEA_L.js`).then(e=>e.MarkdownRenderer),__vite__mapDeps([0,1,2,3,4,5,6,7]))),RadioMultipleChoice:S,AudioAutoPlayer:E},props:{data:{type:Array,required:!0},modifyDifficulty:{type:Number,required:!1,default:0}},setup(e,{emit:t}){let r=D(e,t,`FillInView`),i=j(r);i.question.value=new J(e.data);let a=h(),o=m(()=>{if(!i.question.value)throw r.logger.error(`Question not initialized`),Error(`Question not initialized`);return i.question.value});y(()=>{try{i.question.value||(i.question.value=new J(e.data)),i.question.value.options&&(a.value=shuffle(getTruncatedList()))}catch(e){r.logger.error(`Failed to initialize question:`,e)}}),n(()=>{i.question.value=void 0});let s=m(()=>a.value??[]),c=m(()=>!!e.data[0][`image-1`]),l=m(()=>{if(!c.value)return[``];let t=[],n=1;for(;e.data[0][`image-${n}`];)t.push(URL.createObjectURL(e.data[0][`image-${n}`])),n++;return t}),d=m(()=>!!e.data[0][`audio-1`]),f=m(()=>o.value?.mdText||``),p=m(()=>{if(!d.value)return[``];let t=[],n=1;for(;e.data[0][`audio-${n}`];)t.push(URL.createObjectURL(e.data[0][`audio-${n}`])),n++;return t}),g=m(()=>{if(o.value.answers)return o.value.answers[Math.floor(o.value.answers.length*Math.random())];throw Error(`No answers provided`)}),_=m(()=>{let e=g.value;if(console.log(`Prior answers: ${i.priorAnswers.value}`),e&&i.priorAnswers.value[0]?.[0]&&i.priorAnswers.value[0][1]===`UserInputString`)return gradeSpellingAttempt(i.priorAnswers.value[0][0],e);if(console.log(`found no UserInputString`),g.value){let e=``;for(let t=0;t<g.value.length;t++)e+=`_ `;return e}return``}),v=m(()=>!!(o.value.answers&&o.value.answers.length>0)),getTruncatedList=()=>{if(!o.value?.options)return;if(o.value.options.length<=6)return o.value.options;let t=[];t.push(o.value.answers[Math.floor(Math.random()*o.value.answers.length)]);let n=shuffle(o.value.options.filter(e=>o.value.answers?.indexOf(e)===-1));return e.modifyDifficulty&&(console.log(`Modifying difficulty: ${e.modifyDifficulty}`),n=e.modifyDifficulty<-200?n.slice(0,1):e.modifyDifficulty<-150?n.slice(0,2):e.modifyDifficulty<-100?n.slice(0,3):e.modifyDifficulty<-50?n.slice(0,4):n.slice(0,5)),t.push(...n.slice(0,5)),t},handleNext=()=>{i.submitAnswer(``)};return u(()=>e.data,e=>{try{i.question.value=new J(e),i.question.value?.options&&(a.value=shuffle(getTruncatedList()))}catch(e){r.logger.error(`Failed to initialize/update question:`,e)}},{deep:!0}),{...r,...i,question:o,truncatedOptions:s,hasImage:c,imageURLs:l,hasAudio:d,audioURL:p,obscuredAnswer:_,someAnswer:g,isQuestion:v,handleNext,markdownText:f}}}),H=__name((e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},`default`),U={"data-viewable":`FillInView`},W=[`src`],G={key:4,class:`text-center text-h6`},K={key:5,class:`text-center text-h6`};function _sfc_render(e,n,s,u,m,h){let _=a(`audio-auto-player`),y=a(`markdown-renderer`),b=a(`radio-multiple-choice`),x=a(`v-spacer`),S=a(`v-btn`),C=a(`v-card-actions`);return i(),f(`div`,U,[e.hasAudio?(i(),g(_,{key:0,src:e.audioURL},null,8,[`src`])):v(``,!0),e.hasImage?(i(!0),f(p,{key:1},l(e.imageURLs,(e,t)=>(i(),f(`img`,{key:t,src:e},null,8,W))),128)):v(``,!0),e.markdownText?(i(),g(y,{key:2,md:e.markdownText},null,8,[`md`])):v(``,!0),e.question?.options?(i(),g(b,{key:3,"choice-list":e.truncatedOptions},null,8,[`choice-list`])):e.priorAttempts==1?(i(),f(`div`,G,[d(`span`,null,c(e.obscuredAnswer),1)])):e.priorAttempts==2?(i(),f(`div`,K,[d(`span`,null,c(e.someAnswer),1)])):v(``,!0),e.isQuestion?v(``,!0):(i(),g(C,{key:6},{default:t(()=>[r(x),r(S,{color:`primary`,autofocus:`autofocus`,onClick:e.handleNext},{default:t(()=>n[0]||(n[0]=[o(` Next `)])),_:1},8,[`onClick`])]),_:1}))])}var q=H(V,[[`render`,_sfc_render],[`__scopeId`,`data-v-f91502f8`]]);function splitText(e,t,n){let r=e.split(t),i=r[0],a=r[1].split(n);return{left:i,middle:a[0],right:a[1]}}var J=(B=class BlanksCard extends x{splitTextToken(e){if(A(e)){let t=splitText(e.text,`{{`,`}}`),n=splitText(e.raw,`{{`,`}}`),r=[];return n.left.length>0&&r.push({type:`text`,raw:n.left,text:t.left}),n.middle.length>0&&r.push({type:`text`,raw:`{{`+n.middle+`}}`,text:`{{`+t.middle+`}}`}),n.right.length>0&&r.push({type:`text`,raw:n.right,text:t.right}),r}else return[e]}optionsFromString(e){if(!e.startsWith(`{{`)||!e.endsWith(`}}`))throw Error(`string ${e} is not fill-in text - must look like "{{someText}}"`);e=e.substring(2,e.length-2);let t=e.split(`||`);if(t.length>1){let e=t[0].split(`|`).map(e=>e.trim()),n=t[1].split(`|`).map(e=>e.trim()).filter(t=>!e.includes(t));return n.push(e[randomInt(0,e.length-1)]),{answers:e,options:shuffle(n)}}else return{answers:[e.trim()],options:null}}constructor(e){var _super=(...e)=>(super(...e),T(this,`mdText`,``),T(this,`answers`,null),T(this,`options`,null),this);_super(e),this.mdText=e[0].Input,this.mdText===void 0&&(this.mdText=``);let t=O(this.mdText,`{{`,`}}`),n=[];for(let e=0;e<t.length;e++){let r=t[e],i=r.trim();if(i.startsWith(`{{`)&&i.endsWith(`}}`))if(k(i.slice(2,-2).trim()))n.push(r);else try{let e=this.optionsFromString(r);this.answers=e.answers,this.options=e.options,this.options?.length?n.push(`{{ || }}`):n.push(`{{ }}`)}catch{n.push(r)}else n.push(r)}this.mdText=n.join(``)}isCorrect(e){if(console.log(`answers:${this.answers}\nuser answer: ${JSON.stringify(e)}`),typeof e==`string`){if(this.answers)return this.answers.includes(e);if(e===``)return!0;throw Error(`Question has no configured answers!`)}else if(Array.isArray(e)){if(this.answers)return e.every(e=>this.answers.includes(e));throw Error(`Question has no configured answers!`)}else return this.isCorrectRadio(e)}dataShapes(){return BlanksCard.dataShapes}views(){return BlanksCard.views}isCorrectRadio(e){return this.answers?this.answers.includes(e.choiceList[e.selection]):!1}},T(B,`dataShapes`,z),T(B,`views`,[q]),B),CourseWare=class{get questions(){return this.questionList}get allViews(){let e=[];return this.questionList.forEach(t=>{t.views.forEach(t=>{e.push(t)})}),e}get allViewsMap(){let e={};return this.allViews.forEach(t=>{if(t.name)e[t.name]=t;else throw Error(`View has no name`)}),e}constructor(e,t){T(this,`name`,void 0),T(this,`questionList`,void 0),this.name=e,this.questionList=t,this.questionList=this.questionList.concat(this.getBaseQTypes())}getQuestion(e){let t=e.replace(/^_/,``).replace(/\d+$/,``),n=this.questionList.map(e=>e.name),r=this.questionList.find(n=>{let r=n.name.replace(/^_/,``).replace(/\d+$/,``);return n.name===e||r===t});if(r)return r.name!==e&&console.debug(`[CourseWare.getQuestion] stripped-exact: "${e}" → "${r.name}" (registered: ${n.join(`, `)})`),r;let i=this.questionList.filter(n=>{let r=n.name.replace(/^_/,``).replace(/\d+$/,``);return n.name.includes(t)||e.includes(r)});if(i.length===0){console.warn(`[CourseWare.getQuestion] NO MATCH: "${e}" (base: "${t}") not found in [${n.join(`, `)}]`);return}i.sort((t,n)=>Math.abs(t.name.length-e.length)-Math.abs(n.name.length-e.length));let a=i[0];return console.warn(`[CourseWare.getQuestion] FUZZY: "${e}" → "${a.name}" (candidates: ${i.map(e=>e.name).join(`, `)}; registered: ${n.join(`, `)})`),a}getBaseQTypes(){return[J]}};export{gradeSpellingAttempt as a,sin as c,__toESM as d,R as f,cos as i,__commonJSMin as l,CourseWare as n,randomInt as o,z as p,J as r,shuffle as s,H as t,__name as u};
3
+ //# sourceMappingURL=CourseWare-BTFRjgBR-OzjKW1B2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":"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","names":["e","t","d","u","C","x","O","D","h","r","p","y","_","m","o","i","a","n","g","s","v","b","l","c","S","w","E","T"],"ignoreList":[],"sources":["../../../courseware/dist/shapes-BQUVJdp5.js","../../../courseware/dist/CourseWare-BTFRjgBR.js"],"sourcesContent":["import { DataShapeName as e, FieldType as t } from \"@vue-skuilder/common\";\n//#region \\0rolldown/runtime.js\nvar n = Object.create, r = Object.defineProperty, __name = (e, t) => r(e, \"name\", {\n\tvalue: t,\n\tconfigurable: !0\n}), i = Object.getOwnPropertyDescriptor, a = Object.getOwnPropertyNames, o = Object.getPrototypeOf, s = Object.prototype.hasOwnProperty, __commonJSMin = (e, t) => () => (t || e((t = { exports: {} }).exports, t), t.exports), __copyProps = (e, t, n, o) => {\n\tif (t && typeof t == \"object\" || typeof t == \"function\") for (var c = a(t), l = 0, u = c.length, d; l < u; l++) d = c[l], !s.call(e, d) && d !== n && r(e, d, {\n\t\tget: ((e) => t[e]).bind(null, d),\n\t\tenumerable: !(o = i(t, d)) || o.enumerable\n\t});\n\treturn e;\n}, __toESM = (e, t, i) => (i = e == null ? {} : n(o(e)), __copyProps(t || !e || !e.__esModule ? r(i, \"default\", {\n\tvalue: e,\n\tenumerable: !0\n}) : i, e)), c = /* @__PURE__ */ ((e) => typeof require < \"u\" ? require : typeof Proxy < \"u\" ? new Proxy(e, { get: (e, t) => (typeof require < \"u\" ? require : e)[t] }) : e)(function(e) {\n\tif (typeof require < \"u\") return require.apply(this, arguments);\n\tthrow Error(\"Calling `require` for \\\"\" + e + \"\\\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.\");\n}), l = [{\n\tname: e.Blanks,\n\tfields: [{\n\t\tname: \"Input\",\n\t\ttype: t.MARKDOWN\n\t}, {\n\t\tname: \"Uploads\",\n\t\ttype: t.MEDIA_UPLOADS\n\t}]\n}];\n//#endregion\nexport { __toESM as a, c as i, __commonJSMin as n, __name as r, l as t };\n\n//# sourceMappingURL=shapes-BQUVJdp5.js.map","import { r as e, t } from \"./shapes-BQUVJdp5.js\";\nimport { Fragment as n, computed as r, createBlock as i, createCommentVNode as a, createElementBlock as o, createElementVNode as s, createTextVNode as c, createVNode as l, defineAsyncComponent as u, defineComponent as d, onMounted as f, onUnmounted as p, openBlock as m, ref as h, renderList as g, resolveComponent as _, toDisplayString as v, watch as y, withCtx as b } from \"vue\";\nimport { AudioAutoPlayer as x, Question as S, RadioMultipleChoice as C, containsComponent as w, isInlineComponent as T, splitByDelimiters as E, useQuestionView as D, useViewable as O } from \"@vue-skuilder/common-ui\";\nimport \"@vue-skuilder/common\";\nimport './assets/CourseWare.css';//#region src/math/utility/index.ts\nfunction randomInt(e, t) {\n\treturn Math.floor(Math.random() * (t - e + 1)) + e;\n}\nfunction shuffle(e) {\n\tlet t = [...e];\n\tfor (let e = t.length - 1; e > 0; e--) {\n\t\tlet n = Math.floor(Math.random() * (e + 1));\n\t\t[t[e], t[n]] = [t[n], t[e]];\n\t}\n\treturn t;\n}\nfunction cos(e) {\n\treturn Math.cos(toRadians(e));\n}\nfunction sin(e) {\n\treturn Math.sin(toRadians(e));\n}\nfunction toRadians(e) {\n\treturn e / 360 * 2 * Math.PI;\n}\n//#endregion\n//#region src/default/questions/fillIn/blanksCorrection.ts\nfunction gradeSpellingAttempt(e, t) {\n\tlet n = Array(t.length).fill(\"_\"), r = e.split(\"\");\n\tconsole.log(e, t), console.log(\"Attempt char codes:\", e.split(\"\").map((e) => e.charCodeAt(0))), console.log(\"Answer char codes:\", t.split(\"\").map((e) => e.charCodeAt(0)));\n\tfor (let e = 0; e < t.length; e++) e < r.length && r[e] === t[e] && (n[e] = r[e], r[e] = \"\");\n\tfor (let e = t.length - 1; e >= 0; e--) if (n[e] === \"_\") {\n\t\tlet i = r.findIndex((n) => n === t[e]);\n\t\ti !== -1 && (n[e] = t[e], r[i] = \"\");\n\t}\n\treturn console.log(n.join(\" \")), n.join(\" \");\n}\n//#endregion\n//#region src/default/questions/fillIn/fillIn.vue?vue&type=script&lang.ts\nvar k = d({\n\tname: \"FillInView\",\n\tcomponents: {\n\t\tMarkdownRenderer: u(() => import(\"@vue-skuilder/common-ui\").then((e) => e.MarkdownRenderer)),\n\t\tRadioMultipleChoice: C,\n\t\tAudioAutoPlayer: x\n\t},\n\tprops: {\n\t\tdata: {\n\t\t\ttype: Array,\n\t\t\trequired: !0\n\t\t},\n\t\tmodifyDifficulty: {\n\t\t\ttype: Number,\n\t\t\trequired: !1,\n\t\t\tdefault: 0\n\t\t}\n\t},\n\tsetup(e, { emit: t }) {\n\t\tlet n = O(e, t, \"FillInView\"), i = D(n);\n\t\ti.question.value = new I(e.data);\n\t\tlet a = h(), o = r(() => {\n\t\t\tif (!i.question.value) throw n.logger.error(\"Question not initialized\"), Error(\"Question not initialized\");\n\t\t\treturn i.question.value;\n\t\t});\n\t\tf(() => {\n\t\t\ttry {\n\t\t\t\ti.question.value || (i.question.value = new I(e.data)), i.question.value.options && (a.value = shuffle(getTruncatedList()));\n\t\t\t} catch (e) {\n\t\t\t\tn.logger.error(\"Failed to initialize question:\", e);\n\t\t\t}\n\t\t}), p(() => {\n\t\t\ti.question.value = void 0;\n\t\t});\n\t\tlet s = r(() => a.value ?? []), c = r(() => !!e.data[0][\"image-1\"]), l = r(() => {\n\t\t\tif (!c.value) return [\"\"];\n\t\t\tlet t = [], n = 1;\n\t\t\tfor (; e.data[0][`image-${n}`];) t.push(URL.createObjectURL(e.data[0][`image-${n}`])), n++;\n\t\t\treturn t;\n\t\t}), u = r(() => !!e.data[0][\"audio-1\"]), d = r(() => o.value?.mdText || \"\"), m = r(() => {\n\t\t\tif (!u.value) return [\"\"];\n\t\t\tlet t = [], n = 1;\n\t\t\tfor (; e.data[0][`audio-${n}`];) t.push(URL.createObjectURL(e.data[0][`audio-${n}`])), n++;\n\t\t\treturn t;\n\t\t}), g = r(() => {\n\t\t\tif (o.value.answers) return o.value.answers[Math.floor(o.value.answers.length * Math.random())];\n\t\t\tthrow Error(\"No answers provided\");\n\t\t}), _ = r(() => {\n\t\t\tlet e = g.value;\n\t\t\tif (console.log(`Prior answers: ${i.priorAnswers.value}`), e && i.priorAnswers.value[0]?.[0] && i.priorAnswers.value[0][1] === \"UserInputString\") return gradeSpellingAttempt(i.priorAnswers.value[0][0], e);\n\t\t\tif (console.log(\"found no UserInputString\"), g.value) {\n\t\t\t\tlet e = \"\";\n\t\t\t\tfor (let t = 0; t < g.value.length; t++) e += \"_ \";\n\t\t\t\treturn e;\n\t\t\t}\n\t\t\treturn \"\";\n\t\t}), v = r(() => !!(o.value.answers && o.value.answers.length > 0)), getTruncatedList = () => {\n\t\t\tif (!o.value?.options) return;\n\t\t\tif (o.value.options.length <= 6) return o.value.options;\n\t\t\tlet t = [];\n\t\t\tt.push(o.value.answers[Math.floor(Math.random() * o.value.answers.length)]);\n\t\t\tlet n = shuffle(o.value.options.filter((e) => o.value.answers?.indexOf(e) === -1));\n\t\t\treturn e.modifyDifficulty && (console.log(`Modifying difficulty: ${e.modifyDifficulty}`), n = e.modifyDifficulty < -200 ? n.slice(0, 1) : e.modifyDifficulty < -150 ? n.slice(0, 2) : e.modifyDifficulty < -100 ? n.slice(0, 3) : e.modifyDifficulty < -50 ? n.slice(0, 4) : n.slice(0, 5)), t.push(...n.slice(0, 5)), t;\n\t\t}, handleNext = () => {\n\t\t\ti.submitAnswer(\"\");\n\t\t};\n\t\treturn y(() => e.data, (e) => {\n\t\t\ttry {\n\t\t\t\ti.question.value = new I(e), i.question.value?.options && (a.value = shuffle(getTruncatedList()));\n\t\t\t} catch (e) {\n\t\t\t\tn.logger.error(\"Failed to initialize/update question:\", e);\n\t\t\t}\n\t\t}, { deep: !0 }), {\n\t\t\t...n,\n\t\t\t...i,\n\t\t\tquestion: o,\n\t\t\ttruncatedOptions: s,\n\t\t\thasImage: c,\n\t\t\timageURLs: l,\n\t\t\thasAudio: u,\n\t\t\taudioURL: m,\n\t\t\tobscuredAnswer: _,\n\t\t\tsomeAnswer: g,\n\t\t\tisQuestion: v,\n\t\t\thandleNext,\n\t\t\tmarkdownText: d\n\t\t};\n\t}\n}), A = /* @__PURE__ */ e((e, t) => {\n\tlet n = e.__vccOpts || e;\n\tfor (let [e, r] of t) n[e] = r;\n\treturn n;\n}, \"default\"), j = { \"data-viewable\": \"FillInView\" }, M = [\"src\"], N = {\n\tkey: 4,\n\tclass: \"text-center text-h6\"\n}, P = {\n\tkey: 5,\n\tclass: \"text-center text-h6\"\n};\nfunction _sfc_render(e, t, r, u, d, f) {\n\tlet p = _(\"audio-auto-player\"), h = _(\"markdown-renderer\"), y = _(\"radio-multiple-choice\"), x = _(\"v-spacer\"), S = _(\"v-btn\"), C = _(\"v-card-actions\");\n\treturn m(), o(\"div\", j, [\n\t\te.hasAudio ? (m(), i(p, {\n\t\t\tkey: 0,\n\t\t\tsrc: e.audioURL\n\t\t}, null, 8, [\"src\"])) : a(\"\", !0),\n\t\te.hasImage ? (m(!0), o(n, { key: 1 }, g(e.imageURLs, (e, t) => (m(), o(\"img\", {\n\t\t\tkey: t,\n\t\t\tsrc: e\n\t\t}, null, 8, M))), 128)) : a(\"\", !0),\n\t\te.markdownText ? (m(), i(h, {\n\t\t\tkey: 2,\n\t\t\tmd: e.markdownText\n\t\t}, null, 8, [\"md\"])) : a(\"\", !0),\n\t\te.question?.options ? (m(), i(y, {\n\t\t\tkey: 3,\n\t\t\t\"choice-list\": e.truncatedOptions\n\t\t}, null, 8, [\"choice-list\"])) : e.priorAttempts == 1 ? (m(), o(\"div\", N, [s(\"span\", null, v(e.obscuredAnswer), 1)])) : e.priorAttempts == 2 ? (m(), o(\"div\", P, [s(\"span\", null, v(e.someAnswer), 1)])) : a(\"\", !0),\n\t\te.isQuestion ? a(\"\", !0) : (m(), i(C, { key: 6 }, {\n\t\t\tdefault: b(() => [l(x), l(S, {\n\t\t\t\tcolor: \"primary\",\n\t\t\t\tautofocus: \"autofocus\",\n\t\t\t\tonClick: e.handleNext\n\t\t\t}, {\n\t\t\t\tdefault: b(() => t[0] ||= [c(\" Next \")]),\n\t\t\t\t_: 1\n\t\t\t}, 8, [\"onClick\"])]),\n\t\t\t_: 1\n\t\t}))\n\t]);\n}\nvar F = /* @__PURE__ */ A(k, [[\"render\", _sfc_render], [\"__scopeId\", \"data-v-f91502f8\"]]);\n//#endregion\n//#region src/default/questions/fillIn/index.ts\nfunction splitText(e, t, n) {\n\tlet r = e.split(t), i = r[0], a = r[1].split(n);\n\treturn {\n\t\tleft: i,\n\t\tmiddle: a[0],\n\t\tright: a[1]\n\t};\n}\nvar I = class BlanksCard extends S {\n\tstatic dataShapes = t;\n\tstatic views = [F];\n\tmdText = \"\";\n\tanswers = null;\n\toptions = null;\n\tsplitTextToken(e) {\n\t\tif (w(e)) {\n\t\t\tlet t = splitText(e.text, \"{{\", \"}}\"), n = splitText(e.raw, \"{{\", \"}}\"), r = [];\n\t\t\treturn n.left.length > 0 && r.push({\n\t\t\t\ttype: \"text\",\n\t\t\t\traw: n.left,\n\t\t\t\ttext: t.left\n\t\t\t}), n.middle.length > 0 && r.push({\n\t\t\t\ttype: \"text\",\n\t\t\t\traw: \"{{\" + n.middle + \"}}\",\n\t\t\t\ttext: \"{{\" + t.middle + \"}}\"\n\t\t\t}), n.right.length > 0 && r.push({\n\t\t\t\ttype: \"text\",\n\t\t\t\traw: n.right,\n\t\t\t\ttext: t.right\n\t\t\t}), r;\n\t\t} else return [e];\n\t}\n\toptionsFromString(e) {\n\t\tif (!e.startsWith(\"{{\") || !e.endsWith(\"}}\")) throw Error(`string ${e} is not fill-in text - must look like \"{{someText}}\"`);\n\t\te = e.substring(2, e.length - 2);\n\t\tlet t = e.split(\"||\");\n\t\tif (t.length > 1) {\n\t\t\tlet e = t[0].split(\"|\").map((e) => e.trim()), n = t[1].split(\"|\").map((e) => e.trim()).filter((t) => !e.includes(t));\n\t\t\treturn n.push(e[randomInt(0, e.length - 1)]), {\n\t\t\t\tanswers: e,\n\t\t\t\toptions: shuffle(n)\n\t\t\t};\n\t\t} else return {\n\t\t\tanswers: [e.trim()],\n\t\t\toptions: null\n\t\t};\n\t}\n\tconstructor(e) {\n\t\tsuper(e), this.mdText = e[0].Input, this.mdText === void 0 && (this.mdText = \"\");\n\t\tlet t = E(this.mdText, \"{{\", \"}}\"), n = [];\n\t\tfor (let e = 0; e < t.length; e++) {\n\t\t\tlet r = t[e], i = r.trim();\n\t\t\tif (i.startsWith(\"{{\") && i.endsWith(\"}}\")) if (T(i.slice(2, -2).trim())) n.push(r);\n\t\t\telse try {\n\t\t\t\tlet e = this.optionsFromString(r);\n\t\t\t\tthis.answers = e.answers, this.options = e.options, this.options?.length ? n.push(\"{{ || }}\") : n.push(\"{{ }}\");\n\t\t\t} catch {\n\t\t\t\tn.push(r);\n\t\t\t}\n\t\t\telse n.push(r);\n\t\t}\n\t\tthis.mdText = n.join(\"\");\n\t}\n\tisCorrect(e) {\n\t\tif (console.log(`answers:${this.answers}\\nuser answer: ${JSON.stringify(e)}`), typeof e == \"string\") {\n\t\t\tif (this.answers) return this.answers.includes(e);\n\t\t\tif (e === \"\") return !0;\n\t\t\tthrow Error(\"Question has no configured answers!\");\n\t\t} else if (Array.isArray(e)) {\n\t\t\tif (this.answers) return e.every((e) => this.answers.includes(e));\n\t\t\tthrow Error(\"Question has no configured answers!\");\n\t\t} else return this.isCorrectRadio(e);\n\t}\n\tdataShapes() {\n\t\treturn BlanksCard.dataShapes;\n\t}\n\tviews() {\n\t\treturn BlanksCard.views;\n\t}\n\tisCorrectRadio(e) {\n\t\treturn this.answers ? this.answers.includes(e.choiceList[e.selection]) : !1;\n\t}\n}, CourseWare = class {\n\tget questions() {\n\t\treturn this.questionList;\n\t}\n\tget allViews() {\n\t\tlet e = [];\n\t\treturn this.questionList.forEach((t) => {\n\t\t\tt.views.forEach((t) => {\n\t\t\t\te.push(t);\n\t\t\t});\n\t\t}), e;\n\t}\n\tget allViewsMap() {\n\t\tlet e = {};\n\t\treturn this.allViews.forEach((t) => {\n\t\t\tif (t.name) e[t.name] = t;\n\t\t\telse throw Error(\"View has no name\");\n\t\t}), e;\n\t}\n\tname;\n\tquestionList;\n\tconstructor(e, t) {\n\t\tthis.name = e, this.questionList = t, this.questionList = this.questionList.concat(this.getBaseQTypes());\n\t}\n\tgetQuestion(e) {\n\t\tlet t = e.replace(/^_/, \"\").replace(/\\d+$/, \"\"), n = this.questionList.map((e) => e.name), r = this.questionList.find((n) => {\n\t\t\tlet r = n.name.replace(/^_/, \"\").replace(/\\d+$/, \"\");\n\t\t\treturn n.name === e || r === t;\n\t\t});\n\t\tif (r) return r.name !== e && console.debug(`[CourseWare.getQuestion] stripped-exact: \"${e}\" → \"${r.name}\" (registered: ${n.join(\", \")})`), r;\n\t\tlet i = this.questionList.filter((n) => {\n\t\t\tlet r = n.name.replace(/^_/, \"\").replace(/\\d+$/, \"\");\n\t\t\treturn n.name.includes(t) || e.includes(r);\n\t\t});\n\t\tif (i.length === 0) {\n\t\t\tconsole.warn(`[CourseWare.getQuestion] NO MATCH: \"${e}\" (base: \"${t}\") not found in [${n.join(\", \")}]`);\n\t\t\treturn;\n\t\t}\n\t\ti.sort((t, n) => Math.abs(t.name.length - e.length) - Math.abs(n.name.length - e.length));\n\t\tlet a = i[0];\n\t\treturn console.warn(`[CourseWare.getQuestion] FUZZY: \"${e}\" → \"${a.name}\" (candidates: ${i.map((e) => e.name).join(\", \")}; registered: ${n.join(\", \")})`), a;\n\t}\n\tgetBaseQTypes() {\n\t\treturn [I];\n\t}\n};\n//#endregion\nexport { cos as a, sin as c, gradeSpellingAttempt as i, I as n, randomInt as o, A as r, shuffle as s, CourseWare as t };\n\n//# sourceMappingURL=CourseWare-BTFRjgBR.js.map"],"file":"CourseWare-BTFRjgBR-OzjKW1B2.js"}
@@ -1,3 +1,3 @@
1
- import{i as e}from"./chunk-D6hFPZc3.js";import{$ as t,C as n,H as r,K as i,M as a,S as o,T as s,Vt as c,W as l,Y as u,_ as d,b as f,f as p,v as m,y as h}from"./vue.runtime.esm-bundler-C3q8JS9f.js";import{T as g,v as _}from"./common-ui.es-BrXWBn7p.js";import{T as v,f as y,w as b}from"./dist-CrcJCHFk.js";import"./MarkdownRenderer-DoVbFpA6-BIbDxYC4.js";import{k as x}from"./dist-CzLl7g6t.js";import{t as S}from"./index-DUZItsH-.js";import{t as C}from"./server-Db_WegNj.js";import{t as w}from"./NewCourseDialog-DhwvBT3y.js";var T=s({name:`CourseStubCard`,props:{courseId:{type:String,required:!0}},emits:[`refresh`],data(){return{courseConfig:null,questionCount:0,isPrivate:!1,updatePending:!0,addingCourse:!1}},async created(){try{let e=x().getCourseDB(this.courseId);this.courseConfig=await e.getCourseConfig(),this.isPrivate=!this.courseConfig.public,this.questionCount=(await e.getCourseInfo()).cardCount,this.updatePending=!1}catch(e){console.error(`Error loading course ${this.courseId}: ${e}`)}},methods:{async registerForCourse(){this.addingCourse=!0,y(`Attempting to register for ${this.courseId}.`),await(await g()).registerForCourse(this.courseId),this.$emit(`refresh`)},navigateToInfo(){let e=`/q/${this.courseConfig?.name.replaceAll(` `,`_`)}`;this.$router.push(e)}}});function _sfc_render$1(e,a,s,l,u,f){let p=i(`v-icon`),g=i(`v-card-title`),_=i(`v-card-item`),v=i(`v-card-text`),y=i(`v-btn`),b=i(`v-card-actions`),x=i(`v-card`);return!e.updatePending&&e.courseConfig?(r(),m(x,{key:0,"data-cy":`available-course-card`},{default:t(()=>[n(_,null,{default:t(()=>[n(g,{"data-cy":`course-title`},{default:t(()=>[o(c(e.courseConfig.name)+` `,1),e.isPrivate?(r(),m(p,{key:0,icon:`mdi-eye-off`,class:`ml-2`})):h(``,!0)]),_:1})]),_:1}),n(v,null,{default:t(()=>[o(` Questions: `+c(e.questionCount)+` `,1),d(`p`,null,c(e.courseConfig.description),1)]),_:1}),n(b,null,{default:t(()=>[n(y,{color:`primary`,onClick:e.navigateToInfo},{default:t(()=>a[0]||(a[0]=[o(`More Info`)])),_:1},8,[`onClick`]),n(y,{"data-cy":`register-course-button`,loading:e.addingCourse,color:`primary`,onClick:e.registerForCourse},{default:t(()=>a[1]||(a[1]=[o(` Register `)])),_:1},8,[`loading`,`onClick`])]),_:1})]),_:1})):h(``,!0)}e(_sfc_render$1,`_sfc_render`);var E=s({name:`CoursesView`,components:{NewCourseDialog:w,CourseStubCard:S(T,[[`render`,_sfc_render$1]])},data(){return{existingCourses:[],registeredCourses:[],awaitingCreateCourse:!1,spinnerMap:{},newCourseDialog:!1,user:null,myQuiltsPanel:0,showAllCourses:!1,coursesPerPage:8}},computed:{availableCourses(){let e=this.existingCourses.filter(e=>!this.registeredCourses.includes(e)),t=this.user?.getUsername();return e.filter(e=>t?e.public||e.creator===t||e.admins.indexOf(t)!==-1||e.moderators.indexOf(t)!==-1:!1)},displayedAvailableCourses(){return this.showAllCourses?this.availableCourses:this.availableCourses.slice(0,this.coursesPerPage)},hasMoreCourses(){return this.availableCourses.length>this.coursesPerPage},newCourseAttrs(){return{attrs:{"aria-label":`Create new quilt`},on:{click:()=>this.newCourseDialog=!0}}}},async created(){this.user=await g(),this.refreshData()},methods:{processResponse(){this.newCourseDialog=!1,this.refreshData()},toggleShowMore(){this.showAllCourses=!this.showAllCourses},async refreshData(){console.log(`Pulling user course data...`);try{let e=(await this.user.getCourseRegistrationsDoc()).courses.filter(e=>e.status===`active`||e.status===`maintenance-mode`||e.status===void 0).map(e=>e.courseID);console.log(`userCourseIDs: ${e}`),this.existingCourses=await x().getCoursesDB().getCourseList(),console.log(`existingCourses: \n\t${this.existingCourses.map(e=>e.name).join(`,
1
+ import{i as e}from"./chunk-D6hFPZc3.js";import{$ as t,C as n,H as r,K as i,M as a,S as o,T as s,Vt as c,W as l,Y as u,_ as d,b as f,f as p,v as m,y as h}from"./vue.runtime.esm-bundler-C3q8JS9f.js";import{T as g,v as _}from"./common-ui.es-p3cgaI_b.js";import{T as v,f as y,w as b}from"./dist-leWgtXBf.js";import"./MarkdownRenderer-DoVbFpA6-CvaBjTS8.js";import{k as x}from"./dist-DA7EuQY2.js";import{t as S}from"./index-B-cSF0fq.js";import{t as C}from"./server-Bq50faqp.js";import{t as w}from"./NewCourseDialog-BXxQ1cvK.js";var T=s({name:`CourseStubCard`,props:{courseId:{type:String,required:!0}},emits:[`refresh`],data(){return{courseConfig:null,questionCount:0,isPrivate:!1,updatePending:!0,addingCourse:!1}},async created(){try{let e=x().getCourseDB(this.courseId);this.courseConfig=await e.getCourseConfig(),this.isPrivate=!this.courseConfig.public,this.questionCount=(await e.getCourseInfo()).cardCount,this.updatePending=!1}catch(e){console.error(`Error loading course ${this.courseId}: ${e}`)}},methods:{async registerForCourse(){this.addingCourse=!0,y(`Attempting to register for ${this.courseId}.`),await(await g()).registerForCourse(this.courseId),this.$emit(`refresh`)},navigateToInfo(){let e=`/q/${this.courseConfig?.name.replaceAll(` `,`_`)}`;this.$router.push(e)}}});function _sfc_render$1(e,a,s,l,u,f){let p=i(`v-icon`),g=i(`v-card-title`),_=i(`v-card-item`),v=i(`v-card-text`),y=i(`v-btn`),b=i(`v-card-actions`),x=i(`v-card`);return!e.updatePending&&e.courseConfig?(r(),m(x,{key:0,"data-cy":`available-course-card`},{default:t(()=>[n(_,null,{default:t(()=>[n(g,{"data-cy":`course-title`},{default:t(()=>[o(c(e.courseConfig.name)+` `,1),e.isPrivate?(r(),m(p,{key:0,icon:`mdi-eye-off`,class:`ml-2`})):h(``,!0)]),_:1})]),_:1}),n(v,null,{default:t(()=>[o(` Questions: `+c(e.questionCount)+` `,1),d(`p`,null,c(e.courseConfig.description),1)]),_:1}),n(b,null,{default:t(()=>[n(y,{color:`primary`,onClick:e.navigateToInfo},{default:t(()=>a[0]||(a[0]=[o(`More Info`)])),_:1},8,[`onClick`]),n(y,{"data-cy":`register-course-button`,loading:e.addingCourse,color:`primary`,onClick:e.registerForCourse},{default:t(()=>a[1]||(a[1]=[o(` Register `)])),_:1},8,[`loading`,`onClick`])]),_:1})]),_:1})):h(``,!0)}e(_sfc_render$1,`_sfc_render`);var E=s({name:`CoursesView`,components:{NewCourseDialog:w,CourseStubCard:S(T,[[`render`,_sfc_render$1]])},data(){return{existingCourses:[],registeredCourses:[],awaitingCreateCourse:!1,spinnerMap:{},newCourseDialog:!1,user:null,myQuiltsPanel:0,showAllCourses:!1,coursesPerPage:8}},computed:{availableCourses(){let e=this.existingCourses.filter(e=>!this.registeredCourses.includes(e)),t=this.user?.getUsername();return e.filter(e=>t?e.public||e.creator===t||e.admins.indexOf(t)!==-1||e.moderators.indexOf(t)!==-1:!1)},displayedAvailableCourses(){return this.showAllCourses?this.availableCourses:this.availableCourses.slice(0,this.coursesPerPage)},hasMoreCourses(){return this.availableCourses.length>this.coursesPerPage},newCourseAttrs(){return{attrs:{"aria-label":`Create new quilt`},on:{click:()=>this.newCourseDialog=!0}}}},async created(){this.user=await g(),this.refreshData()},methods:{processResponse(){this.newCourseDialog=!1,this.refreshData()},toggleShowMore(){this.showAllCourses=!this.showAllCourses},async refreshData(){console.log(`Pulling user course data...`);try{let e=(await this.user.getCourseRegistrationsDoc()).courses.filter(e=>e.status===`active`||e.status===`maintenance-mode`||e.status===void 0).map(e=>e.courseID);console.log(`userCourseIDs: ${e}`),this.existingCourses=await x().getCoursesDB().getCourseList(),console.log(`existingCourses: \n\t${this.existingCourses.map(e=>e.name).join(`,
2
2
  `)}`),this.registeredCourses=this.existingCourses.filter(t=>{let n=!1;return e.forEach(e=>{t.courseID===e&&(n=!0)}),n})}catch(e){console.error(`Error refreshing course data:`,e),_({status:v.error,text:`Failed to load courses: ${e||`Database access error`}`})}},async createCourse(){this.awaitingCreateCourse=!0;let e=await C({type:b.CREATE_COURSE,data:{name:`testCourseName`,description:`All of these courses will be the same!`,public:!0,deleted:!1,creator:this.user.getUsername(),admins:[this.user.getUsername()],moderators:[],dataShapes:[],questionTypes:[]},user:this.user.getUsername(),response:null});_({status:e.response,text:`Course ${JSON.stringify(e)} created`}),this.awaitingCreateCourse=!1},async addCourse(e){this.spinnerMap[e]=!0,console.log(`Attempting to register for ${e}.`),await this.user?.registerForCourse(e),delete this.spinnerMap[e],this.refreshData()},async dropCourse(e){this.spinnerMap[e]=!0,console.log(`Attempting to drop ${e}.`),await this.user?.dropCourse(e),delete this.spinnerMap[e],this.refreshData()}}}),D={class:`d-flex align-center justify-space-between`},O={"data-cy":`registered-course`,class:`d-flex align-center`};function _sfc_render(e,s,g,_,v,y){let b=i(`v-btn`),x=i(`v-expansion-panel-title`),S=i(`router-link`),C=i(`v-icon`),w=i(`v-card`),T=i(`v-col`),E=i(`v-row`),k=i(`v-expansion-panel-text`),A=i(`v-expansion-panel`),j=i(`v-expansion-panels`),M=i(`course-stub-card`),N=i(`new-course-dialog`),P=i(`v-dialog`),F=i(`v-container`);return r(),m(F,{fluid:``},{default:t(()=>[n(b,a({color:`primary`,fixed:``,location:`bottom right`,icon:`mdi-plus`,size:`large`,class:`mb-4 mr-4`,"data-cy":`create-course-fab`},e.newCourseAttrs,u(e.newCourseAttrs.on)),null,16),n(E,null,{default:t(()=>[n(T,{cols:`12`},{default:t(()=>[n(j,{modelValue:e.myQuiltsPanel,"onUpdate:modelValue":s[0]||(s[0]=t=>e.myQuiltsPanel=t)},{default:t(()=>[n(A,null,{default:t(()=>[n(x,{"data-cy":`registered-quilts-panel`},{default:t(()=>s[3]||(s[3]=[o(`My Registered Quilts`)])),_:1}),n(k,null,{default:t(()=>[n(E,null,{default:t(()=>[(r(!0),f(p,null,l(e.registeredCourses,i=>(r(),m(T,{key:i.courseID,cols:`12`,sm:`6`,md:`4`,lg:`3`},{default:t(()=>[n(w,{variant:`outlined`,density:`compact`,class:`pa-2`},{default:t(()=>[d(`div`,D,[d(`div`,O,[n(S,{to:`/q/${i.name.replaceAll(` `,`_`)}`,class:`text-subtitle-2`,"data-cy":`registered-course-title`},{default:t(()=>[o(c(i.name),1)]),_:2},1032,[`to`]),i.public?h(``,!0):(r(),m(C,{key:0,size:`x-small`,class:`ml-1`},{default:t(()=>s[4]||(s[4]=[o(`mdi-eye-off`)])),_:1}))]),n(b,{size:`x-small`,variant:`text`,color:`error`,"data-cy":`drop-course-button`,loading:e.spinnerMap[i.courseID]!==void 0,onClick:t=>e.dropCourse(i.courseID)},{default:t(()=>s[5]||(s[5]=[o(` Drop `)])),_:2},1032,[`loading`,`onClick`])])]),_:2},1024)]),_:2},1024))),128))]),_:1})]),_:1})]),_:1})]),_:1},8,[`modelValue`])]),_:1}),n(T,{cols:`12`,class:`mt-4`},{default:t(()=>[s[6]||(s[6]=d(`h2`,{class:`text-h5 mb-3`},`Available Quilts`,-1)),n(E,null,{default:t(()=>[(r(!0),f(p,null,l(e.displayedAvailableCourses,i=>(r(),m(T,{key:i.courseID,cols:`12`,sm:`6`,md:`4`,lg:`3`},{default:t(()=>[n(M,{"data-cy":`available-course-card`,"course-id":i.courseID,onRefresh:e.refreshData},null,8,[`course-id`,`onRefresh`])]),_:2},1024))),128))]),_:1}),e.hasMoreCourses?(r(),m(E,{key:0,justify:`center`,class:`mt-2`},{default:t(()=>[n(b,{variant:`text`,color:`primary`,"data-cy":`courses-show-more-button`,onClick:e.toggleShowMore},{default:t(()=>[o(c(e.showAllCourses?`Show Less`:`Show More`),1)]),_:1},8,[`onClick`])]),_:1})):h(``,!0)]),_:1})]),_:1}),n(P,{modelValue:e.newCourseDialog,"onUpdate:modelValue":s[2]||(s[2]=t=>e.newCourseDialog=t),fullscreen:``,transition:`dialog-bottom-transition`,scrim:!1},{default:t(()=>[n(N,{onCourseEditingComplete:s[1]||(s[1]=t=>e.processResponse())})]),_:1},8,[`modelValue`])]),_:1})}var k=S(E,[[`render`,_sfc_render],[`__scopeId`,`data-v-ba0ad091`]]);export{k as default};
3
- //# sourceMappingURL=Courses-ClDdLQUO.js.map
3
+ //# sourceMappingURL=Courses-DB0JFz1Q.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Courses-ClDdLQUO.js","names":[],"sources":["../../src/components/Courses/CourseStubCard.vue","../../src/components/Courses/CourseStubCard.vue","../../src/views/Courses.vue","../../src/views/Courses.vue"],"sourcesContent":["<template>\n <v-card v-if=\"!updatePending && courseConfig\" data-cy=\"available-course-card\">\n <v-card-item>\n <v-card-title data-cy=\"course-title\">\n {{ courseConfig.name }}\n <v-icon v-if=\"isPrivate\" icon=\"mdi-eye-off\" class=\"ml-2\"></v-icon>\n </v-card-title>\n </v-card-item>\n\n <v-card-text>\n Questions: {{ questionCount }}\n <p>{{ courseConfig.description }}</p>\n </v-card-text>\n\n <v-card-actions>\n <v-btn color=\"primary\" @click=\"navigateToInfo\">More Info</v-btn>\n <v-btn data-cy=\"register-course-button\" :loading=\"addingCourse\" color=\"primary\" @click=\"registerForCourse\">\n Register\n </v-btn>\n </v-card-actions>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { getCurrentUser } from '@vue-skuilder/common-ui';\nimport { CourseConfig, log } from '@vue-skuilder/common';\nimport { getDataLayer } from '@vue-skuilder/db';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'CourseStubCard',\n\n props: {\n courseId: {\n type: String,\n required: true,\n },\n },\n emits: ['refresh'],\n\n data() {\n return {\n courseConfig: null as CourseConfig | null,\n questionCount: 0,\n isPrivate: false,\n updatePending: true,\n addingCourse: false,\n };\n },\n\n async created() {\n try {\n const db = getDataLayer().getCourseDB(this.courseId);\n this.courseConfig = (await db.getCourseConfig())!;\n this.isPrivate = !this.courseConfig.public;\n this.questionCount = (await db.getCourseInfo()).cardCount;\n this.updatePending = false;\n } catch (e) {\n console.error(`Error loading course ${this.courseId}: ${e}`);\n }\n },\n\n methods: {\n async registerForCourse() {\n this.addingCourse = true;\n log(`Attempting to register for ${this.courseId}.`);\n await (await getCurrentUser()).registerForCourse(this.courseId);\n this.$emit('refresh');\n },\n navigateToInfo() {\n const path = `/q/${this.courseConfig?.name.replaceAll(' ', '_')}`;\n this.$router.push(path);\n },\n },\n});\n</script>\n","<template>\n <v-card v-if=\"!updatePending && courseConfig\" data-cy=\"available-course-card\">\n <v-card-item>\n <v-card-title data-cy=\"course-title\">\n {{ courseConfig.name }}\n <v-icon v-if=\"isPrivate\" icon=\"mdi-eye-off\" class=\"ml-2\"></v-icon>\n </v-card-title>\n </v-card-item>\n\n <v-card-text>\n Questions: {{ questionCount }}\n <p>{{ courseConfig.description }}</p>\n </v-card-text>\n\n <v-card-actions>\n <v-btn color=\"primary\" @click=\"navigateToInfo\">More Info</v-btn>\n <v-btn data-cy=\"register-course-button\" :loading=\"addingCourse\" color=\"primary\" @click=\"registerForCourse\">\n Register\n </v-btn>\n </v-card-actions>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { getCurrentUser } from '@vue-skuilder/common-ui';\nimport { CourseConfig, log } from '@vue-skuilder/common';\nimport { getDataLayer } from '@vue-skuilder/db';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'CourseStubCard',\n\n props: {\n courseId: {\n type: String,\n required: true,\n },\n },\n emits: ['refresh'],\n\n data() {\n return {\n courseConfig: null as CourseConfig | null,\n questionCount: 0,\n isPrivate: false,\n updatePending: true,\n addingCourse: false,\n };\n },\n\n async created() {\n try {\n const db = getDataLayer().getCourseDB(this.courseId);\n this.courseConfig = (await db.getCourseConfig())!;\n this.isPrivate = !this.courseConfig.public;\n this.questionCount = (await db.getCourseInfo()).cardCount;\n this.updatePending = false;\n } catch (e) {\n console.error(`Error loading course ${this.courseId}: ${e}`);\n }\n },\n\n methods: {\n async registerForCourse() {\n this.addingCourse = true;\n log(`Attempting to register for ${this.courseId}.`);\n await (await getCurrentUser()).registerForCourse(this.courseId);\n this.$emit('refresh');\n },\n navigateToInfo() {\n const path = `/q/${this.courseConfig?.name.replaceAll(' ', '_')}`;\n this.$router.push(path);\n },\n },\n});\n</script>\n","<template>\n <v-container fluid>\n <!-- Fixed Action Button - Updated position classes -->\n <v-btn\n color=\"primary\"\n fixed\n location=\"bottom right\"\n icon=\"mdi-plus\"\n size=\"large\"\n class=\"mb-4 mr-4\"\n data-cy=\"create-course-fab\"\n v-bind=\"newCourseAttrs\"\n v-on=\"newCourseAttrs.on\"\n />\n\n <!-- Main Content Area -->\n <v-row>\n <!-- My Quilts Panel -->\n <v-col cols=\"12\">\n <v-expansion-panels v-model=\"myQuiltsPanel\">\n <v-expansion-panel>\n <v-expansion-panel-title data-cy=\"registered-quilts-panel\">My Registered Quilts</v-expansion-panel-title>\n <v-expansion-panel-text>\n <v-row>\n <v-col v-for=\"course in registeredCourses\" :key=\"course.courseID\" cols=\"12\" sm=\"6\" md=\"4\" lg=\"3\">\n <v-card variant=\"outlined\" density=\"compact\" class=\"pa-2\">\n <div class=\"d-flex align-center justify-space-between\">\n <div data-cy=\"registered-course\" class=\"d-flex align-center\">\n <router-link\n :to=\"`/q/${course.name.replaceAll(' ', '_')}`\"\n class=\"text-subtitle-2\"\n data-cy=\"registered-course-title\"\n >\n {{ course.name }}\n </router-link>\n <v-icon v-if=\"!course.public\" size=\"x-small\" class=\"ml-1\">mdi-eye-off</v-icon>\n </div>\n <v-btn\n size=\"x-small\"\n variant=\"text\"\n color=\"error\"\n data-cy=\"drop-course-button\"\n :loading=\"spinnerMap[course.courseID] !== undefined\"\n @click=\"dropCourse(course.courseID)\"\n >\n Drop\n </v-btn>\n </div>\n </v-card>\n </v-col>\n </v-row>\n </v-expansion-panel-text>\n </v-expansion-panel>\n </v-expansion-panels>\n </v-col>\n\n <!-- Available Quilts Section -->\n <v-col cols=\"12\" class=\"mt-4\">\n <h2 class=\"text-h5 mb-3\">Available Quilts</h2>\n <v-row>\n <v-col v-for=\"course in displayedAvailableCourses\" :key=\"course.courseID\" cols=\"12\" sm=\"6\" md=\"4\" lg=\"3\">\n <course-stub-card data-cy=\"available-course-card\" :course-id=\"course.courseID\" @refresh=\"refreshData\" />\n </v-col>\n </v-row>\n\n <!-- Show More Button -->\n <v-row v-if=\"hasMoreCourses\" justify=\"center\" class=\"mt-2\">\n <v-btn variant=\"text\" color=\"primary\" data-cy=\"courses-show-more-button\" @click=\"toggleShowMore\">\n {{ showAllCourses ? 'Show Less' : 'Show More' }}\n </v-btn>\n </v-row>\n </v-col>\n </v-row>\n\n <!-- New Course Dialog -->\n <v-dialog v-model=\"newCourseDialog\" fullscreen transition=\"dialog-bottom-transition\" :scrim=\"false\">\n <new-course-dialog @course-editing-complete=\"processResponse()\" />\n </v-dialog>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport NewCourseDialog from '@pui/components/Courses/NewCourseDialog.vue';\nimport CourseStubCard from '@pui/components/Courses/CourseStubCard.vue';\n\nimport serverRequest from '../server';\nimport { ServerRequestType, CourseConfig, Status } from '@vue-skuilder/common';\nimport { alertUser, getCurrentUser } from '@vue-skuilder/common-ui';\nimport { UserDBInterface, getDataLayer } from '@vue-skuilder/db';\n\ntype DBCourseConfig = CourseConfig & {\n courseID: string;\n};\n\nexport default defineComponent({\n name: 'CoursesView',\n\n components: {\n NewCourseDialog,\n CourseStubCard,\n },\n\n data() {\n return {\n existingCourses: [] as DBCourseConfig[],\n registeredCourses: [] as DBCourseConfig[],\n awaitingCreateCourse: false,\n spinnerMap: {} as { [key: string]: boolean },\n newCourseDialog: false,\n user: null as UserDBInterface | null,\n myQuiltsPanel: 0, // Controls expansion panel\n showAllCourses: false,\n coursesPerPage: 8,\n };\n },\n\n computed: {\n availableCourses(): DBCourseConfig[] {\n const availableCourses = this.existingCourses.filter((c) => !this.registeredCourses.includes(c));\n const user = this.user?.getUsername();\n\n const viewableCourses = availableCourses.filter((course) => {\n if (!user) {\n return false;\n }\n const viewable: boolean =\n course.public ||\n course.creator === user ||\n course.admins.indexOf(user) !== -1 ||\n course.moderators.indexOf(user) !== -1;\n\n return viewable;\n });\n\n return viewableCourses;\n },\n displayedAvailableCourses(): DBCourseConfig[] {\n if (this.showAllCourses) {\n return this.availableCourses;\n }\n return this.availableCourses.slice(0, this.coursesPerPage);\n },\n\n hasMoreCourses(): boolean {\n return this.availableCourses.length > this.coursesPerPage;\n },\n\n newCourseAttrs() {\n return {\n attrs: {\n 'aria-label': 'Create new quilt',\n },\n on: {\n click: () => (this.newCourseDialog = true),\n },\n };\n },\n },\n\n async created() {\n this.user = await getCurrentUser();\n this.refreshData();\n },\n\n methods: {\n processResponse(): void {\n this.newCourseDialog = false;\n this.refreshData();\n },\n\n toggleShowMore() {\n this.showAllCourses = !this.showAllCourses;\n },\n\n async refreshData(): Promise<void> {\n console.log(`Pulling user course data...`);\n try {\n const userCourseIDs = (await this.user!.getCourseRegistrationsDoc()).courses\n .filter((c) => {\n return c.status === 'active' || c.status === 'maintenance-mode' || c.status === undefined;\n })\n .map((c) => {\n return c.courseID;\n });\n console.log(`userCourseIDs: ${userCourseIDs}`);\n\n this.existingCourses = (await getDataLayer().getCoursesDB().getCourseList()) as DBCourseConfig[];\n console.log(`existingCourses: \\n\\t${this.existingCourses.map((c) => c.name).join(',\\n\\t')}`);\n\n this.registeredCourses = this.existingCourses.filter((course) => {\n let match: boolean = false;\n userCourseIDs.forEach((id: string) => {\n if (course.courseID === id) {\n match = true;\n }\n });\n return match;\n });\n } catch (e) {\n console.error(`Error refreshing course data:`, e);\n alertUser({\n status: Status.error,\n text: `Failed to load courses: ${e || 'Database access error'}`,\n });\n }\n },\n async createCourse(): Promise<void> {\n this.awaitingCreateCourse = true;\n const resp = await serverRequest({\n type: ServerRequestType.CREATE_COURSE,\n data: {\n name: 'testCourseName',\n description: 'All of these courses will be the same!',\n public: true,\n deleted: false,\n creator: this.user!.getUsername(),\n admins: [this.user!.getUsername()],\n moderators: [],\n dataShapes: [],\n questionTypes: [],\n },\n user: this.user!.getUsername(),\n response: null,\n });\n\n alertUser({\n status: resp.response!,\n text: `Course ${JSON.stringify(resp)} created`,\n });\n this.awaitingCreateCourse = false;\n },\n\n async addCourse(course: string): Promise<void> {\n this.spinnerMap[course] = true;\n console.log(`Attempting to register for ${course}.`);\n await this.user?.registerForCourse(course);\n delete this.spinnerMap[course];\n this.refreshData();\n },\n\n async dropCourse(course: string): Promise<void> {\n this.spinnerMap[course] = true;\n console.log(`Attempting to drop ${course}.`);\n await this.user?.dropCourse(course);\n delete this.spinnerMap[course];\n this.refreshData();\n },\n },\n});\n</script>\n\n<style scoped>\n.component-fade-enter-active,\n.component-fade-leave-active {\n transition: all 0.65s ease;\n}\n.component-fade-enter,\n.component-fade-leave-to {\n opacity: 0;\n}\n.componnent-fade-move {\n transition: transform 1s;\n}\n</style>\n","<template>\n <v-container fluid>\n <!-- Fixed Action Button - Updated position classes -->\n <v-btn\n color=\"primary\"\n fixed\n location=\"bottom right\"\n icon=\"mdi-plus\"\n size=\"large\"\n class=\"mb-4 mr-4\"\n data-cy=\"create-course-fab\"\n v-bind=\"newCourseAttrs\"\n v-on=\"newCourseAttrs.on\"\n />\n\n <!-- Main Content Area -->\n <v-row>\n <!-- My Quilts Panel -->\n <v-col cols=\"12\">\n <v-expansion-panels v-model=\"myQuiltsPanel\">\n <v-expansion-panel>\n <v-expansion-panel-title data-cy=\"registered-quilts-panel\">My Registered Quilts</v-expansion-panel-title>\n <v-expansion-panel-text>\n <v-row>\n <v-col v-for=\"course in registeredCourses\" :key=\"course.courseID\" cols=\"12\" sm=\"6\" md=\"4\" lg=\"3\">\n <v-card variant=\"outlined\" density=\"compact\" class=\"pa-2\">\n <div class=\"d-flex align-center justify-space-between\">\n <div data-cy=\"registered-course\" class=\"d-flex align-center\">\n <router-link\n :to=\"`/q/${course.name.replaceAll(' ', '_')}`\"\n class=\"text-subtitle-2\"\n data-cy=\"registered-course-title\"\n >\n {{ course.name }}\n </router-link>\n <v-icon v-if=\"!course.public\" size=\"x-small\" class=\"ml-1\">mdi-eye-off</v-icon>\n </div>\n <v-btn\n size=\"x-small\"\n variant=\"text\"\n color=\"error\"\n data-cy=\"drop-course-button\"\n :loading=\"spinnerMap[course.courseID] !== undefined\"\n @click=\"dropCourse(course.courseID)\"\n >\n Drop\n </v-btn>\n </div>\n </v-card>\n </v-col>\n </v-row>\n </v-expansion-panel-text>\n </v-expansion-panel>\n </v-expansion-panels>\n </v-col>\n\n <!-- Available Quilts Section -->\n <v-col cols=\"12\" class=\"mt-4\">\n <h2 class=\"text-h5 mb-3\">Available Quilts</h2>\n <v-row>\n <v-col v-for=\"course in displayedAvailableCourses\" :key=\"course.courseID\" cols=\"12\" sm=\"6\" md=\"4\" lg=\"3\">\n <course-stub-card data-cy=\"available-course-card\" :course-id=\"course.courseID\" @refresh=\"refreshData\" />\n </v-col>\n </v-row>\n\n <!-- Show More Button -->\n <v-row v-if=\"hasMoreCourses\" justify=\"center\" class=\"mt-2\">\n <v-btn variant=\"text\" color=\"primary\" data-cy=\"courses-show-more-button\" @click=\"toggleShowMore\">\n {{ showAllCourses ? 'Show Less' : 'Show More' }}\n </v-btn>\n </v-row>\n </v-col>\n </v-row>\n\n <!-- New Course Dialog -->\n <v-dialog v-model=\"newCourseDialog\" fullscreen transition=\"dialog-bottom-transition\" :scrim=\"false\">\n <new-course-dialog @course-editing-complete=\"processResponse()\" />\n </v-dialog>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport NewCourseDialog from '@pui/components/Courses/NewCourseDialog.vue';\nimport CourseStubCard from '@pui/components/Courses/CourseStubCard.vue';\n\nimport serverRequest from '../server';\nimport { ServerRequestType, CourseConfig, Status } from '@vue-skuilder/common';\nimport { alertUser, getCurrentUser } from '@vue-skuilder/common-ui';\nimport { UserDBInterface, getDataLayer } from '@vue-skuilder/db';\n\ntype DBCourseConfig = CourseConfig & {\n courseID: string;\n};\n\nexport default defineComponent({\n name: 'CoursesView',\n\n components: {\n NewCourseDialog,\n CourseStubCard,\n },\n\n data() {\n return {\n existingCourses: [] as DBCourseConfig[],\n registeredCourses: [] as DBCourseConfig[],\n awaitingCreateCourse: false,\n spinnerMap: {} as { [key: string]: boolean },\n newCourseDialog: false,\n user: null as UserDBInterface | null,\n myQuiltsPanel: 0, // Controls expansion panel\n showAllCourses: false,\n coursesPerPage: 8,\n };\n },\n\n computed: {\n availableCourses(): DBCourseConfig[] {\n const availableCourses = this.existingCourses.filter((c) => !this.registeredCourses.includes(c));\n const user = this.user?.getUsername();\n\n const viewableCourses = availableCourses.filter((course) => {\n if (!user) {\n return false;\n }\n const viewable: boolean =\n course.public ||\n course.creator === user ||\n course.admins.indexOf(user) !== -1 ||\n course.moderators.indexOf(user) !== -1;\n\n return viewable;\n });\n\n return viewableCourses;\n },\n displayedAvailableCourses(): DBCourseConfig[] {\n if (this.showAllCourses) {\n return this.availableCourses;\n }\n return this.availableCourses.slice(0, this.coursesPerPage);\n },\n\n hasMoreCourses(): boolean {\n return this.availableCourses.length > this.coursesPerPage;\n },\n\n newCourseAttrs() {\n return {\n attrs: {\n 'aria-label': 'Create new quilt',\n },\n on: {\n click: () => (this.newCourseDialog = true),\n },\n };\n },\n },\n\n async created() {\n this.user = await getCurrentUser();\n this.refreshData();\n },\n\n methods: {\n processResponse(): void {\n this.newCourseDialog = false;\n this.refreshData();\n },\n\n toggleShowMore() {\n this.showAllCourses = !this.showAllCourses;\n },\n\n async refreshData(): Promise<void> {\n console.log(`Pulling user course data...`);\n try {\n const userCourseIDs = (await this.user!.getCourseRegistrationsDoc()).courses\n .filter((c) => {\n return c.status === 'active' || c.status === 'maintenance-mode' || c.status === undefined;\n })\n .map((c) => {\n return c.courseID;\n });\n console.log(`userCourseIDs: ${userCourseIDs}`);\n\n this.existingCourses = (await getDataLayer().getCoursesDB().getCourseList()) as DBCourseConfig[];\n console.log(`existingCourses: \\n\\t${this.existingCourses.map((c) => c.name).join(',\\n\\t')}`);\n\n this.registeredCourses = this.existingCourses.filter((course) => {\n let match: boolean = false;\n userCourseIDs.forEach((id: string) => {\n if (course.courseID === id) {\n match = true;\n }\n });\n return match;\n });\n } catch (e) {\n console.error(`Error refreshing course data:`, e);\n alertUser({\n status: Status.error,\n text: `Failed to load courses: ${e || 'Database access error'}`,\n });\n }\n },\n async createCourse(): Promise<void> {\n this.awaitingCreateCourse = true;\n const resp = await serverRequest({\n type: ServerRequestType.CREATE_COURSE,\n data: {\n name: 'testCourseName',\n description: 'All of these courses will be the same!',\n public: true,\n deleted: false,\n creator: this.user!.getUsername(),\n admins: [this.user!.getUsername()],\n moderators: [],\n dataShapes: [],\n questionTypes: [],\n },\n user: this.user!.getUsername(),\n response: null,\n });\n\n alertUser({\n status: resp.response!,\n text: `Course ${JSON.stringify(resp)} created`,\n });\n this.awaitingCreateCourse = false;\n },\n\n async addCourse(course: string): Promise<void> {\n this.spinnerMap[course] = true;\n console.log(`Attempting to register for ${course}.`);\n await this.user?.registerForCourse(course);\n delete this.spinnerMap[course];\n this.refreshData();\n },\n\n async dropCourse(course: string): Promise<void> {\n this.spinnerMap[course] = true;\n console.log(`Attempting to drop ${course}.`);\n await this.user?.dropCourse(course);\n delete this.spinnerMap[course];\n this.refreshData();\n },\n },\n});\n</script>\n\n<style scoped>\n.component-fade-enter-active,\n.component-fade-leave-active {\n transition: all 0.65s ease;\n}\n.component-fade-enter,\n.component-fade-leave-to {\n opacity: 0;\n}\n.componnent-fade-move {\n transition: transform 1s;\n}\n</style>\n"],"mappings":"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"}
1
+ {"version":3,"file":"Courses-DB0JFz1Q.js","names":[],"sources":["../../src/components/Courses/CourseStubCard.vue","../../src/components/Courses/CourseStubCard.vue","../../src/views/Courses.vue","../../src/views/Courses.vue"],"sourcesContent":["<template>\n <v-card v-if=\"!updatePending && courseConfig\" data-cy=\"available-course-card\">\n <v-card-item>\n <v-card-title data-cy=\"course-title\">\n {{ courseConfig.name }}\n <v-icon v-if=\"isPrivate\" icon=\"mdi-eye-off\" class=\"ml-2\"></v-icon>\n </v-card-title>\n </v-card-item>\n\n <v-card-text>\n Questions: {{ questionCount }}\n <p>{{ courseConfig.description }}</p>\n </v-card-text>\n\n <v-card-actions>\n <v-btn color=\"primary\" @click=\"navigateToInfo\">More Info</v-btn>\n <v-btn data-cy=\"register-course-button\" :loading=\"addingCourse\" color=\"primary\" @click=\"registerForCourse\">\n Register\n </v-btn>\n </v-card-actions>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { getCurrentUser } from '@vue-skuilder/common-ui';\nimport { CourseConfig, log } from '@vue-skuilder/common';\nimport { getDataLayer } from '@vue-skuilder/db';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'CourseStubCard',\n\n props: {\n courseId: {\n type: String,\n required: true,\n },\n },\n emits: ['refresh'],\n\n data() {\n return {\n courseConfig: null as CourseConfig | null,\n questionCount: 0,\n isPrivate: false,\n updatePending: true,\n addingCourse: false,\n };\n },\n\n async created() {\n try {\n const db = getDataLayer().getCourseDB(this.courseId);\n this.courseConfig = (await db.getCourseConfig())!;\n this.isPrivate = !this.courseConfig.public;\n this.questionCount = (await db.getCourseInfo()).cardCount;\n this.updatePending = false;\n } catch (e) {\n console.error(`Error loading course ${this.courseId}: ${e}`);\n }\n },\n\n methods: {\n async registerForCourse() {\n this.addingCourse = true;\n log(`Attempting to register for ${this.courseId}.`);\n await (await getCurrentUser()).registerForCourse(this.courseId);\n this.$emit('refresh');\n },\n navigateToInfo() {\n const path = `/q/${this.courseConfig?.name.replaceAll(' ', '_')}`;\n this.$router.push(path);\n },\n },\n});\n</script>\n","<template>\n <v-card v-if=\"!updatePending && courseConfig\" data-cy=\"available-course-card\">\n <v-card-item>\n <v-card-title data-cy=\"course-title\">\n {{ courseConfig.name }}\n <v-icon v-if=\"isPrivate\" icon=\"mdi-eye-off\" class=\"ml-2\"></v-icon>\n </v-card-title>\n </v-card-item>\n\n <v-card-text>\n Questions: {{ questionCount }}\n <p>{{ courseConfig.description }}</p>\n </v-card-text>\n\n <v-card-actions>\n <v-btn color=\"primary\" @click=\"navigateToInfo\">More Info</v-btn>\n <v-btn data-cy=\"register-course-button\" :loading=\"addingCourse\" color=\"primary\" @click=\"registerForCourse\">\n Register\n </v-btn>\n </v-card-actions>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { getCurrentUser } from '@vue-skuilder/common-ui';\nimport { CourseConfig, log } from '@vue-skuilder/common';\nimport { getDataLayer } from '@vue-skuilder/db';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'CourseStubCard',\n\n props: {\n courseId: {\n type: String,\n required: true,\n },\n },\n emits: ['refresh'],\n\n data() {\n return {\n courseConfig: null as CourseConfig | null,\n questionCount: 0,\n isPrivate: false,\n updatePending: true,\n addingCourse: false,\n };\n },\n\n async created() {\n try {\n const db = getDataLayer().getCourseDB(this.courseId);\n this.courseConfig = (await db.getCourseConfig())!;\n this.isPrivate = !this.courseConfig.public;\n this.questionCount = (await db.getCourseInfo()).cardCount;\n this.updatePending = false;\n } catch (e) {\n console.error(`Error loading course ${this.courseId}: ${e}`);\n }\n },\n\n methods: {\n async registerForCourse() {\n this.addingCourse = true;\n log(`Attempting to register for ${this.courseId}.`);\n await (await getCurrentUser()).registerForCourse(this.courseId);\n this.$emit('refresh');\n },\n navigateToInfo() {\n const path = `/q/${this.courseConfig?.name.replaceAll(' ', '_')}`;\n this.$router.push(path);\n },\n },\n});\n</script>\n","<template>\n <v-container fluid>\n <!-- Fixed Action Button - Updated position classes -->\n <v-btn\n color=\"primary\"\n fixed\n location=\"bottom right\"\n icon=\"mdi-plus\"\n size=\"large\"\n class=\"mb-4 mr-4\"\n data-cy=\"create-course-fab\"\n v-bind=\"newCourseAttrs\"\n v-on=\"newCourseAttrs.on\"\n />\n\n <!-- Main Content Area -->\n <v-row>\n <!-- My Quilts Panel -->\n <v-col cols=\"12\">\n <v-expansion-panels v-model=\"myQuiltsPanel\">\n <v-expansion-panel>\n <v-expansion-panel-title data-cy=\"registered-quilts-panel\">My Registered Quilts</v-expansion-panel-title>\n <v-expansion-panel-text>\n <v-row>\n <v-col v-for=\"course in registeredCourses\" :key=\"course.courseID\" cols=\"12\" sm=\"6\" md=\"4\" lg=\"3\">\n <v-card variant=\"outlined\" density=\"compact\" class=\"pa-2\">\n <div class=\"d-flex align-center justify-space-between\">\n <div data-cy=\"registered-course\" class=\"d-flex align-center\">\n <router-link\n :to=\"`/q/${course.name.replaceAll(' ', '_')}`\"\n class=\"text-subtitle-2\"\n data-cy=\"registered-course-title\"\n >\n {{ course.name }}\n </router-link>\n <v-icon v-if=\"!course.public\" size=\"x-small\" class=\"ml-1\">mdi-eye-off</v-icon>\n </div>\n <v-btn\n size=\"x-small\"\n variant=\"text\"\n color=\"error\"\n data-cy=\"drop-course-button\"\n :loading=\"spinnerMap[course.courseID] !== undefined\"\n @click=\"dropCourse(course.courseID)\"\n >\n Drop\n </v-btn>\n </div>\n </v-card>\n </v-col>\n </v-row>\n </v-expansion-panel-text>\n </v-expansion-panel>\n </v-expansion-panels>\n </v-col>\n\n <!-- Available Quilts Section -->\n <v-col cols=\"12\" class=\"mt-4\">\n <h2 class=\"text-h5 mb-3\">Available Quilts</h2>\n <v-row>\n <v-col v-for=\"course in displayedAvailableCourses\" :key=\"course.courseID\" cols=\"12\" sm=\"6\" md=\"4\" lg=\"3\">\n <course-stub-card data-cy=\"available-course-card\" :course-id=\"course.courseID\" @refresh=\"refreshData\" />\n </v-col>\n </v-row>\n\n <!-- Show More Button -->\n <v-row v-if=\"hasMoreCourses\" justify=\"center\" class=\"mt-2\">\n <v-btn variant=\"text\" color=\"primary\" data-cy=\"courses-show-more-button\" @click=\"toggleShowMore\">\n {{ showAllCourses ? 'Show Less' : 'Show More' }}\n </v-btn>\n </v-row>\n </v-col>\n </v-row>\n\n <!-- New Course Dialog -->\n <v-dialog v-model=\"newCourseDialog\" fullscreen transition=\"dialog-bottom-transition\" :scrim=\"false\">\n <new-course-dialog @course-editing-complete=\"processResponse()\" />\n </v-dialog>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport NewCourseDialog from '@pui/components/Courses/NewCourseDialog.vue';\nimport CourseStubCard from '@pui/components/Courses/CourseStubCard.vue';\n\nimport serverRequest from '../server';\nimport { ServerRequestType, CourseConfig, Status } from '@vue-skuilder/common';\nimport { alertUser, getCurrentUser } from '@vue-skuilder/common-ui';\nimport { UserDBInterface, getDataLayer } from '@vue-skuilder/db';\n\ntype DBCourseConfig = CourseConfig & {\n courseID: string;\n};\n\nexport default defineComponent({\n name: 'CoursesView',\n\n components: {\n NewCourseDialog,\n CourseStubCard,\n },\n\n data() {\n return {\n existingCourses: [] as DBCourseConfig[],\n registeredCourses: [] as DBCourseConfig[],\n awaitingCreateCourse: false,\n spinnerMap: {} as { [key: string]: boolean },\n newCourseDialog: false,\n user: null as UserDBInterface | null,\n myQuiltsPanel: 0, // Controls expansion panel\n showAllCourses: false,\n coursesPerPage: 8,\n };\n },\n\n computed: {\n availableCourses(): DBCourseConfig[] {\n const availableCourses = this.existingCourses.filter((c) => !this.registeredCourses.includes(c));\n const user = this.user?.getUsername();\n\n const viewableCourses = availableCourses.filter((course) => {\n if (!user) {\n return false;\n }\n const viewable: boolean =\n course.public ||\n course.creator === user ||\n course.admins.indexOf(user) !== -1 ||\n course.moderators.indexOf(user) !== -1;\n\n return viewable;\n });\n\n return viewableCourses;\n },\n displayedAvailableCourses(): DBCourseConfig[] {\n if (this.showAllCourses) {\n return this.availableCourses;\n }\n return this.availableCourses.slice(0, this.coursesPerPage);\n },\n\n hasMoreCourses(): boolean {\n return this.availableCourses.length > this.coursesPerPage;\n },\n\n newCourseAttrs() {\n return {\n attrs: {\n 'aria-label': 'Create new quilt',\n },\n on: {\n click: () => (this.newCourseDialog = true),\n },\n };\n },\n },\n\n async created() {\n this.user = await getCurrentUser();\n this.refreshData();\n },\n\n methods: {\n processResponse(): void {\n this.newCourseDialog = false;\n this.refreshData();\n },\n\n toggleShowMore() {\n this.showAllCourses = !this.showAllCourses;\n },\n\n async refreshData(): Promise<void> {\n console.log(`Pulling user course data...`);\n try {\n const userCourseIDs = (await this.user!.getCourseRegistrationsDoc()).courses\n .filter((c) => {\n return c.status === 'active' || c.status === 'maintenance-mode' || c.status === undefined;\n })\n .map((c) => {\n return c.courseID;\n });\n console.log(`userCourseIDs: ${userCourseIDs}`);\n\n this.existingCourses = (await getDataLayer().getCoursesDB().getCourseList()) as DBCourseConfig[];\n console.log(`existingCourses: \\n\\t${this.existingCourses.map((c) => c.name).join(',\\n\\t')}`);\n\n this.registeredCourses = this.existingCourses.filter((course) => {\n let match: boolean = false;\n userCourseIDs.forEach((id: string) => {\n if (course.courseID === id) {\n match = true;\n }\n });\n return match;\n });\n } catch (e) {\n console.error(`Error refreshing course data:`, e);\n alertUser({\n status: Status.error,\n text: `Failed to load courses: ${e || 'Database access error'}`,\n });\n }\n },\n async createCourse(): Promise<void> {\n this.awaitingCreateCourse = true;\n const resp = await serverRequest({\n type: ServerRequestType.CREATE_COURSE,\n data: {\n name: 'testCourseName',\n description: 'All of these courses will be the same!',\n public: true,\n deleted: false,\n creator: this.user!.getUsername(),\n admins: [this.user!.getUsername()],\n moderators: [],\n dataShapes: [],\n questionTypes: [],\n },\n user: this.user!.getUsername(),\n response: null,\n });\n\n alertUser({\n status: resp.response!,\n text: `Course ${JSON.stringify(resp)} created`,\n });\n this.awaitingCreateCourse = false;\n },\n\n async addCourse(course: string): Promise<void> {\n this.spinnerMap[course] = true;\n console.log(`Attempting to register for ${course}.`);\n await this.user?.registerForCourse(course);\n delete this.spinnerMap[course];\n this.refreshData();\n },\n\n async dropCourse(course: string): Promise<void> {\n this.spinnerMap[course] = true;\n console.log(`Attempting to drop ${course}.`);\n await this.user?.dropCourse(course);\n delete this.spinnerMap[course];\n this.refreshData();\n },\n },\n});\n</script>\n\n<style scoped>\n.component-fade-enter-active,\n.component-fade-leave-active {\n transition: all 0.65s ease;\n}\n.component-fade-enter,\n.component-fade-leave-to {\n opacity: 0;\n}\n.componnent-fade-move {\n transition: transform 1s;\n}\n</style>\n","<template>\n <v-container fluid>\n <!-- Fixed Action Button - Updated position classes -->\n <v-btn\n color=\"primary\"\n fixed\n location=\"bottom right\"\n icon=\"mdi-plus\"\n size=\"large\"\n class=\"mb-4 mr-4\"\n data-cy=\"create-course-fab\"\n v-bind=\"newCourseAttrs\"\n v-on=\"newCourseAttrs.on\"\n />\n\n <!-- Main Content Area -->\n <v-row>\n <!-- My Quilts Panel -->\n <v-col cols=\"12\">\n <v-expansion-panels v-model=\"myQuiltsPanel\">\n <v-expansion-panel>\n <v-expansion-panel-title data-cy=\"registered-quilts-panel\">My Registered Quilts</v-expansion-panel-title>\n <v-expansion-panel-text>\n <v-row>\n <v-col v-for=\"course in registeredCourses\" :key=\"course.courseID\" cols=\"12\" sm=\"6\" md=\"4\" lg=\"3\">\n <v-card variant=\"outlined\" density=\"compact\" class=\"pa-2\">\n <div class=\"d-flex align-center justify-space-between\">\n <div data-cy=\"registered-course\" class=\"d-flex align-center\">\n <router-link\n :to=\"`/q/${course.name.replaceAll(' ', '_')}`\"\n class=\"text-subtitle-2\"\n data-cy=\"registered-course-title\"\n >\n {{ course.name }}\n </router-link>\n <v-icon v-if=\"!course.public\" size=\"x-small\" class=\"ml-1\">mdi-eye-off</v-icon>\n </div>\n <v-btn\n size=\"x-small\"\n variant=\"text\"\n color=\"error\"\n data-cy=\"drop-course-button\"\n :loading=\"spinnerMap[course.courseID] !== undefined\"\n @click=\"dropCourse(course.courseID)\"\n >\n Drop\n </v-btn>\n </div>\n </v-card>\n </v-col>\n </v-row>\n </v-expansion-panel-text>\n </v-expansion-panel>\n </v-expansion-panels>\n </v-col>\n\n <!-- Available Quilts Section -->\n <v-col cols=\"12\" class=\"mt-4\">\n <h2 class=\"text-h5 mb-3\">Available Quilts</h2>\n <v-row>\n <v-col v-for=\"course in displayedAvailableCourses\" :key=\"course.courseID\" cols=\"12\" sm=\"6\" md=\"4\" lg=\"3\">\n <course-stub-card data-cy=\"available-course-card\" :course-id=\"course.courseID\" @refresh=\"refreshData\" />\n </v-col>\n </v-row>\n\n <!-- Show More Button -->\n <v-row v-if=\"hasMoreCourses\" justify=\"center\" class=\"mt-2\">\n <v-btn variant=\"text\" color=\"primary\" data-cy=\"courses-show-more-button\" @click=\"toggleShowMore\">\n {{ showAllCourses ? 'Show Less' : 'Show More' }}\n </v-btn>\n </v-row>\n </v-col>\n </v-row>\n\n <!-- New Course Dialog -->\n <v-dialog v-model=\"newCourseDialog\" fullscreen transition=\"dialog-bottom-transition\" :scrim=\"false\">\n <new-course-dialog @course-editing-complete=\"processResponse()\" />\n </v-dialog>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport NewCourseDialog from '@pui/components/Courses/NewCourseDialog.vue';\nimport CourseStubCard from '@pui/components/Courses/CourseStubCard.vue';\n\nimport serverRequest from '../server';\nimport { ServerRequestType, CourseConfig, Status } from '@vue-skuilder/common';\nimport { alertUser, getCurrentUser } from '@vue-skuilder/common-ui';\nimport { UserDBInterface, getDataLayer } from '@vue-skuilder/db';\n\ntype DBCourseConfig = CourseConfig & {\n courseID: string;\n};\n\nexport default defineComponent({\n name: 'CoursesView',\n\n components: {\n NewCourseDialog,\n CourseStubCard,\n },\n\n data() {\n return {\n existingCourses: [] as DBCourseConfig[],\n registeredCourses: [] as DBCourseConfig[],\n awaitingCreateCourse: false,\n spinnerMap: {} as { [key: string]: boolean },\n newCourseDialog: false,\n user: null as UserDBInterface | null,\n myQuiltsPanel: 0, // Controls expansion panel\n showAllCourses: false,\n coursesPerPage: 8,\n };\n },\n\n computed: {\n availableCourses(): DBCourseConfig[] {\n const availableCourses = this.existingCourses.filter((c) => !this.registeredCourses.includes(c));\n const user = this.user?.getUsername();\n\n const viewableCourses = availableCourses.filter((course) => {\n if (!user) {\n return false;\n }\n const viewable: boolean =\n course.public ||\n course.creator === user ||\n course.admins.indexOf(user) !== -1 ||\n course.moderators.indexOf(user) !== -1;\n\n return viewable;\n });\n\n return viewableCourses;\n },\n displayedAvailableCourses(): DBCourseConfig[] {\n if (this.showAllCourses) {\n return this.availableCourses;\n }\n return this.availableCourses.slice(0, this.coursesPerPage);\n },\n\n hasMoreCourses(): boolean {\n return this.availableCourses.length > this.coursesPerPage;\n },\n\n newCourseAttrs() {\n return {\n attrs: {\n 'aria-label': 'Create new quilt',\n },\n on: {\n click: () => (this.newCourseDialog = true),\n },\n };\n },\n },\n\n async created() {\n this.user = await getCurrentUser();\n this.refreshData();\n },\n\n methods: {\n processResponse(): void {\n this.newCourseDialog = false;\n this.refreshData();\n },\n\n toggleShowMore() {\n this.showAllCourses = !this.showAllCourses;\n },\n\n async refreshData(): Promise<void> {\n console.log(`Pulling user course data...`);\n try {\n const userCourseIDs = (await this.user!.getCourseRegistrationsDoc()).courses\n .filter((c) => {\n return c.status === 'active' || c.status === 'maintenance-mode' || c.status === undefined;\n })\n .map((c) => {\n return c.courseID;\n });\n console.log(`userCourseIDs: ${userCourseIDs}`);\n\n this.existingCourses = (await getDataLayer().getCoursesDB().getCourseList()) as DBCourseConfig[];\n console.log(`existingCourses: \\n\\t${this.existingCourses.map((c) => c.name).join(',\\n\\t')}`);\n\n this.registeredCourses = this.existingCourses.filter((course) => {\n let match: boolean = false;\n userCourseIDs.forEach((id: string) => {\n if (course.courseID === id) {\n match = true;\n }\n });\n return match;\n });\n } catch (e) {\n console.error(`Error refreshing course data:`, e);\n alertUser({\n status: Status.error,\n text: `Failed to load courses: ${e || 'Database access error'}`,\n });\n }\n },\n async createCourse(): Promise<void> {\n this.awaitingCreateCourse = true;\n const resp = await serverRequest({\n type: ServerRequestType.CREATE_COURSE,\n data: {\n name: 'testCourseName',\n description: 'All of these courses will be the same!',\n public: true,\n deleted: false,\n creator: this.user!.getUsername(),\n admins: [this.user!.getUsername()],\n moderators: [],\n dataShapes: [],\n questionTypes: [],\n },\n user: this.user!.getUsername(),\n response: null,\n });\n\n alertUser({\n status: resp.response!,\n text: `Course ${JSON.stringify(resp)} created`,\n });\n this.awaitingCreateCourse = false;\n },\n\n async addCourse(course: string): Promise<void> {\n this.spinnerMap[course] = true;\n console.log(`Attempting to register for ${course}.`);\n await this.user?.registerForCourse(course);\n delete this.spinnerMap[course];\n this.refreshData();\n },\n\n async dropCourse(course: string): Promise<void> {\n this.spinnerMap[course] = true;\n console.log(`Attempting to drop ${course}.`);\n await this.user?.dropCourse(course);\n delete this.spinnerMap[course];\n this.refreshData();\n },\n },\n});\n</script>\n\n<style scoped>\n.component-fade-enter-active,\n.component-fade-leave-active {\n transition: all 0.65s ease;\n}\n.component-fade-enter,\n.component-fade-leave-to {\n opacity: 0;\n}\n.componnent-fade-move {\n transition: transform 1s;\n}\n</style>\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import"./chunk-D6hFPZc3.js";import{$ as e,C as t,H as n,K as r,S as i,T as a,_ as o,v as s,y as c}from"./vue.runtime.esm-bundler-C3q8JS9f.js";import{B as l}from"./common-ui.es-p3cgaI_b.js";import{m as u}from"./dist-leWgtXBf.js";import"./MarkdownRenderer-DoVbFpA6-CvaBjTS8.js";import{k as d}from"./dist-DA7EuQY2.js";import{t as f}from"./index-B-cSF0fq.js";import"./CourseWare-BTFRjgBR-OzjKW1B2.js";import"./chess-BbHATAzk-BhFAwbgX.js";import"./math-B4HbgYf6-CLJIZTjv.js";import"./piano-DF1g6yaX-AR14jqWm.js";import"./sightsing-BFQ7HRig-BNrrORP_.js";import"./typing-BevtfWlp-Cl6jtRmX.js";import{t as p}from"./dist-DCY40cJ7.js";var m=a({name:`ELOModerator`,components:{CardLoader:l},props:{courseId:{type:String,required:!0}},data(){return{courseDB:null,updatePending:!0,courseConfig:null,cards:[],id1:null,id2:null,elo1:null,elo2:null,viewLookup:p.getView}},async created(){this.courseDB=d().getCourseDB(this.courseId),this.courseConfig=await this.courseDB.getCourseConfig(),await this.getNewCards()},methods:{vote(e){if(!this.elo1||!this.elo2)return;let t=u(this.elo1,this.elo2,e===`a`?1:0,{globalOnly:!0});this.courseDB.updateCardElo(this.cards[0].cardId,t.userElo),this.courseDB.updateCardElo(this.cards[1].cardId,t.cardElo),this.getNewCards()},async getNewCards(){this.courseDB&&(this.updatePending=!0,this.cards=await this.courseDB.getInexperiencedCards(),this.id1=null,this.id2=null,this.id1={courseID:this.courseId,cardID:this.cards[0].cardId},this.id2={courseID:this.courseId,cardID:this.cards[1].cardId},this.elo1=this.cards[0].elo,this.elo2=this.cards[1].elo,this.updatePending=!1)}}});function _sfc_render(a,l,u,d,f,p){let m=r(`v-col`),h=r(`v-row`),g=r(`v-icon`),_=r(`v-btn`),v=r(`card-loader`),y=r(`v-container`);return a.updatePending?c(``,!0):(n(),s(y,{key:0},{default:e(()=>[t(h,null,{default:e(()=>[t(m,{cols:`12`},{default:e(()=>l[2]||(l[2]=[o(`h1`,null,[i(`Which seems `),o(`em`,null,`harder`),i(`?`)],-1)])),_:1})]),_:1}),t(h,null,{default:e(()=>[t(m,null,{default:e(()=>[t(_,{color:`success`,class:`ma-5`,onClick:l[0]||(l[0]=e=>a.vote(`a`))},{default:e(()=>[t(g,null,{default:e(()=>l[3]||(l[3]=[i(`mdi-check`)])),_:1})]),_:1}),t(v,{class:`ma-2`,qualified_id:a.id1,"view-lookup":a.viewLookup},null,8,[`qualified_id`,`view-lookup`])]),_:1})]),_:1}),t(h,null,{default:e(()=>[t(m,null,{default:e(()=>[t(_,{color:`success`,class:`ma-5`,onClick:l[1]||(l[1]=e=>a.vote(`b`))},{default:e(()=>[t(g,null,{default:e(()=>l[4]||(l[4]=[i(`mdi-check`)])),_:1})]),_:1}),t(v,{class:`ma-2`,qualified_id:a.id2,"view-lookup":a.viewLookup},null,8,[`qualified_id`,`view-lookup`])]),_:1})]),_:1})]),_:1}))}var h=f(m,[[`render`,_sfc_render],[`__scopeId`,`data-v-df68b8b6`]]);export{h as default};
2
+ //# sourceMappingURL=EloModeration-BmU0CqZt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EloModeration-B6LM11G_.js","names":[],"sources":["../../src/components/Courses/EloModeration.vue","../../src/components/Courses/EloModeration.vue"],"sourcesContent":["<template>\n <v-container v-if=\"!updatePending\">\n <v-row>\n <v-col cols=\"12\">\n <h1>Which seems <em>harder</em>?</h1>\n </v-col>\n </v-row>\n\n <v-row>\n <v-col>\n <v-btn color=\"success\" class=\"ma-5\" @click=\"vote('a')\">\n <v-icon>mdi-check</v-icon>\n </v-btn>\n <card-loader class=\"ma-2\" :qualified_id=\"id1\" :view-lookup=\"viewLookup\" />\n </v-col>\n </v-row>\n\n <v-row>\n <v-col>\n <v-btn color=\"success\" class=\"ma-5\" @click=\"vote('b')\">\n <v-icon>mdi-check</v-icon>\n </v-btn>\n <card-loader class=\"ma-2\" :qualified_id=\"id2\" :view-lookup=\"viewLookup\" />\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { CardLoader } from '@vue-skuilder/common-ui';\nimport { allCourseWare } from '@vue-skuilder/courseware';\nimport { CourseElo, adjustCourseScores, CourseConfig } from '@vue-skuilder/common';\nimport { CourseDBInterface, getDataLayer, QualifiedCardID } from '@vue-skuilder/db';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'ELOModerator',\n\n components: {\n CardLoader,\n },\n\n props: {\n courseId: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n courseDB: null as CourseDBInterface | null,\n updatePending: true,\n courseConfig: null as CourseConfig | null,\n cards: [] as {\n courseId: string;\n cardId: string;\n elo: CourseElo;\n count: number;\n }[],\n id1: null as QualifiedCardID | null,\n id2: null as QualifiedCardID | null,\n elo1: null as CourseElo | null,\n elo2: null as CourseElo | null,\n viewLookup: allCourseWare.getView,\n };\n },\n\n async created() {\n this.courseDB = getDataLayer().getCourseDB(this.courseId);\n\n this.courseConfig = (await this.courseDB!.getCourseConfig())!;\n await this.getNewCards();\n },\n\n methods: {\n vote(x: 'a' | 'b') {\n if (!this.elo1 || !this.elo2) return;\n\n const scores = adjustCourseScores(this.elo1, this.elo2, x === 'a' ? 1 : 0, {\n globalOnly: true,\n });\n\n this.courseDB!.updateCardElo(this.cards[0].cardId, scores.userElo);\n this.courseDB!.updateCardElo(this.cards[1].cardId, scores.cardElo);\n\n this.getNewCards();\n },\n\n async getNewCards() {\n if (!this.courseDB) return;\n\n this.updatePending = true;\n this.cards = await this.courseDB!.getInexperiencedCards();\n\n // console.log('Comparing:\\n\\t' + JSON.stringify(this.cards));\n\n this.id1 = null;\n this.id2 = null;\n\n this.id1 = {\n courseID: this.courseId,\n cardID: this.cards[0].cardId,\n };\n this.id2 = {\n courseID: this.courseId,\n cardID: this.cards[1].cardId,\n };\n\n this.elo1 = this.cards[0].elo;\n this.elo2 = this.cards[1].elo;\n\n this.updatePending = false;\n },\n },\n});\n</script>\n\n<style scoped>\n.component-fade-enter-active,\n.component-fade-leave-active {\n transition: opacity 0.5s ease;\n}\n.component-fade-enter, .component-fade-leave-to\n/* .component-fade-leave-active below version 2.1.8 */ {\n opacity: 0;\n}\n</style>\n","<template>\n <v-container v-if=\"!updatePending\">\n <v-row>\n <v-col cols=\"12\">\n <h1>Which seems <em>harder</em>?</h1>\n </v-col>\n </v-row>\n\n <v-row>\n <v-col>\n <v-btn color=\"success\" class=\"ma-5\" @click=\"vote('a')\">\n <v-icon>mdi-check</v-icon>\n </v-btn>\n <card-loader class=\"ma-2\" :qualified_id=\"id1\" :view-lookup=\"viewLookup\" />\n </v-col>\n </v-row>\n\n <v-row>\n <v-col>\n <v-btn color=\"success\" class=\"ma-5\" @click=\"vote('b')\">\n <v-icon>mdi-check</v-icon>\n </v-btn>\n <card-loader class=\"ma-2\" :qualified_id=\"id2\" :view-lookup=\"viewLookup\" />\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { CardLoader } from '@vue-skuilder/common-ui';\nimport { allCourseWare } from '@vue-skuilder/courseware';\nimport { CourseElo, adjustCourseScores, CourseConfig } from '@vue-skuilder/common';\nimport { CourseDBInterface, getDataLayer, QualifiedCardID } from '@vue-skuilder/db';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'ELOModerator',\n\n components: {\n CardLoader,\n },\n\n props: {\n courseId: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n courseDB: null as CourseDBInterface | null,\n updatePending: true,\n courseConfig: null as CourseConfig | null,\n cards: [] as {\n courseId: string;\n cardId: string;\n elo: CourseElo;\n count: number;\n }[],\n id1: null as QualifiedCardID | null,\n id2: null as QualifiedCardID | null,\n elo1: null as CourseElo | null,\n elo2: null as CourseElo | null,\n viewLookup: allCourseWare.getView,\n };\n },\n\n async created() {\n this.courseDB = getDataLayer().getCourseDB(this.courseId);\n\n this.courseConfig = (await this.courseDB!.getCourseConfig())!;\n await this.getNewCards();\n },\n\n methods: {\n vote(x: 'a' | 'b') {\n if (!this.elo1 || !this.elo2) return;\n\n const scores = adjustCourseScores(this.elo1, this.elo2, x === 'a' ? 1 : 0, {\n globalOnly: true,\n });\n\n this.courseDB!.updateCardElo(this.cards[0].cardId, scores.userElo);\n this.courseDB!.updateCardElo(this.cards[1].cardId, scores.cardElo);\n\n this.getNewCards();\n },\n\n async getNewCards() {\n if (!this.courseDB) return;\n\n this.updatePending = true;\n this.cards = await this.courseDB!.getInexperiencedCards();\n\n // console.log('Comparing:\\n\\t' + JSON.stringify(this.cards));\n\n this.id1 = null;\n this.id2 = null;\n\n this.id1 = {\n courseID: this.courseId,\n cardID: this.cards[0].cardId,\n };\n this.id2 = {\n courseID: this.courseId,\n cardID: this.cards[1].cardId,\n };\n\n this.elo1 = this.cards[0].elo;\n this.elo2 = this.cards[1].elo;\n\n this.updatePending = false;\n },\n },\n});\n</script>\n\n<style scoped>\n.component-fade-enter-active,\n.component-fade-leave-active {\n transition: opacity 0.5s ease;\n}\n.component-fade-enter, .component-fade-leave-to\n/* .component-fade-leave-active below version 2.1.8 */ {\n opacity: 0;\n}\n</style>\n"],"mappings":"0YCmCA,IAAA,EAAe,EAAgB,CAC7B,KAAM,eAEN,WAAY,CACV,WAAA,EACD,CAED,MAAO,CACL,SAAU,CACR,KAAM,OACN,SAAU,GACX,CACF,CAED,MAAO,CACL,MAAO,CACL,SAAU,KACV,cAAe,GACf,aAAc,KACd,MAAO,EAAC,CAMR,IAAK,KACL,IAAK,KACL,KAAM,KACN,KAAM,KACN,WAAY,EAAc,QAC3B,EAGH,MAAM,SAAU,CACd,KAAK,SAAW,GAAc,CAAC,YAAY,KAAK,SAAS,CAEzD,KAAK,aAAgB,MAAM,KAAK,SAAU,iBAAiB,CAC3D,MAAM,KAAK,aAAa,EAG1B,QAAS,CACP,KAAK,EAAc,CACjB,GAAI,CAAC,KAAK,MAAQ,CAAC,KAAK,KAAM,OAE9B,IAAM,EAAS,EAAmB,KAAK,KAAM,KAAK,KAAM,IAAM,IAAM,EAAI,EAAG,CACzE,WAAY,GACb,CAAC,CAEF,KAAK,SAAU,cAAc,KAAK,MAAM,GAAG,OAAQ,EAAO,QAAQ,CAClE,KAAK,SAAU,cAAc,KAAK,MAAM,GAAG,OAAQ,EAAO,QAAQ,CAElE,KAAK,aAAa,EAGpB,MAAM,aAAc,CACb,KAAK,WAEV,KAAK,cAAgB,GACrB,KAAK,MAAQ,MAAM,KAAK,SAAU,uBAAuB,CAIzD,KAAK,IAAM,KACX,KAAK,IAAM,KAEX,KAAK,IAAM,CACT,SAAU,KAAK,SACf,OAAQ,KAAK,MAAM,GAAG,OACvB,CACD,KAAK,IAAM,CACT,SAAU,KAAK,SACf,OAAQ,KAAK,MAAM,GAAG,OACvB,CAED,KAAK,KAAO,KAAK,MAAM,GAAG,IAC1B,KAAK,KAAO,KAAK,MAAM,GAAG,IAE1B,KAAK,cAAgB,KAExB,CACF,CAAC,yIAlHoB,EAAA,cADtB,EAAA,GAAA,GAAA,EACsB,GAAA,CAApB,EAwBc,EAAA,CAzBhB,IAAA,EAAA,CAAA,CAAA,QAAA,MAMY,CAJR,EAIQ,EAAA,KAAA,CANZ,QAAA,MAKc,CAFR,EAEQ,EAAA,CAFD,KAAK,KAAI,CAAA,CAHtB,QAAA,MAI6C,EAAA,KAAA,EAAA,GAAA,CAArC,EAAqC,KAAA,KAAA,CAJ7C,EAIY,eAAY,CAAA,EAAe,KAAA,KAAX,SAAM,CAJlC,EAIuC,IAAC,SAJxC,EAAA,MAAA,EAAA,IAQI,EAOQ,EAAA,KAAA,CAfZ,QAAA,MAcc,CALR,EAKQ,EAAA,KAAA,CAdd,QAAA,MAYgB,CAFR,EAEQ,EAAA,CAFD,MAAM,UAAU,MAAM,OAAQ,QAAK,EAAA,KAAA,EAAA,GAAA,GAAE,EAAA,KAAI,IAAA,IAVxD,QAAA,MAWoC,CAA1B,EAA0B,EAAA,KAAA,CAXpC,QAAA,MAW2B,EAAA,KAAA,EAAA,GAAA,CAX3B,EAWkB,YAAS,CAAA,EAAA,CAX3B,EAAA,MAAA,EAAA,IAaQ,EAA0E,EAAA,CAA7D,MAAM,OAAQ,aAAc,EAAA,IAAM,cAAa,EAAA,qDAbpE,EAAA,MAAA,EAAA,IAiBI,EAOQ,EAAA,KAAA,CAxBZ,QAAA,MAuBc,CALR,EAKQ,EAAA,KAAA,CAvBd,QAAA,MAqBgB,CAFR,EAEQ,EAAA,CAFD,MAAM,UAAU,MAAM,OAAQ,QAAK,EAAA,KAAA,EAAA,GAAA,GAAE,EAAA,KAAI,IAAA,IAnBxD,QAAA,MAoBoC,CAA1B,EAA0B,EAAA,KAAA,CApBpC,QAAA,MAoB2B,EAAA,KAAA,EAAA,GAAA,CApB3B,EAoBkB,YAAS,CAAA,EAAA,CApB3B,EAAA,MAAA,EAAA,IAsBQ,EAA0E,EAAA,CAA7D,MAAM,OAAQ,aAAc,EAAA,IAAM,cAAa,EAAA,qDAtBpE,EAAA,MAAA,EAAA,MAAA,EAAA"}
1
+ {"version":3,"file":"EloModeration-BmU0CqZt.js","names":[],"sources":["../../src/components/Courses/EloModeration.vue","../../src/components/Courses/EloModeration.vue"],"sourcesContent":["<template>\n <v-container v-if=\"!updatePending\">\n <v-row>\n <v-col cols=\"12\">\n <h1>Which seems <em>harder</em>?</h1>\n </v-col>\n </v-row>\n\n <v-row>\n <v-col>\n <v-btn color=\"success\" class=\"ma-5\" @click=\"vote('a')\">\n <v-icon>mdi-check</v-icon>\n </v-btn>\n <card-loader class=\"ma-2\" :qualified_id=\"id1\" :view-lookup=\"viewLookup\" />\n </v-col>\n </v-row>\n\n <v-row>\n <v-col>\n <v-btn color=\"success\" class=\"ma-5\" @click=\"vote('b')\">\n <v-icon>mdi-check</v-icon>\n </v-btn>\n <card-loader class=\"ma-2\" :qualified_id=\"id2\" :view-lookup=\"viewLookup\" />\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { CardLoader } from '@vue-skuilder/common-ui';\nimport { allCourseWare } from '@vue-skuilder/courseware';\nimport { CourseElo, adjustCourseScores, CourseConfig } from '@vue-skuilder/common';\nimport { CourseDBInterface, getDataLayer, QualifiedCardID } from '@vue-skuilder/db';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'ELOModerator',\n\n components: {\n CardLoader,\n },\n\n props: {\n courseId: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n courseDB: null as CourseDBInterface | null,\n updatePending: true,\n courseConfig: null as CourseConfig | null,\n cards: [] as {\n courseId: string;\n cardId: string;\n elo: CourseElo;\n count: number;\n }[],\n id1: null as QualifiedCardID | null,\n id2: null as QualifiedCardID | null,\n elo1: null as CourseElo | null,\n elo2: null as CourseElo | null,\n viewLookup: allCourseWare.getView,\n };\n },\n\n async created() {\n this.courseDB = getDataLayer().getCourseDB(this.courseId);\n\n this.courseConfig = (await this.courseDB!.getCourseConfig())!;\n await this.getNewCards();\n },\n\n methods: {\n vote(x: 'a' | 'b') {\n if (!this.elo1 || !this.elo2) return;\n\n const scores = adjustCourseScores(this.elo1, this.elo2, x === 'a' ? 1 : 0, {\n globalOnly: true,\n });\n\n this.courseDB!.updateCardElo(this.cards[0].cardId, scores.userElo);\n this.courseDB!.updateCardElo(this.cards[1].cardId, scores.cardElo);\n\n this.getNewCards();\n },\n\n async getNewCards() {\n if (!this.courseDB) return;\n\n this.updatePending = true;\n this.cards = await this.courseDB!.getInexperiencedCards();\n\n // console.log('Comparing:\\n\\t' + JSON.stringify(this.cards));\n\n this.id1 = null;\n this.id2 = null;\n\n this.id1 = {\n courseID: this.courseId,\n cardID: this.cards[0].cardId,\n };\n this.id2 = {\n courseID: this.courseId,\n cardID: this.cards[1].cardId,\n };\n\n this.elo1 = this.cards[0].elo;\n this.elo2 = this.cards[1].elo;\n\n this.updatePending = false;\n },\n },\n});\n</script>\n\n<style scoped>\n.component-fade-enter-active,\n.component-fade-leave-active {\n transition: opacity 0.5s ease;\n}\n.component-fade-enter, .component-fade-leave-to\n/* .component-fade-leave-active below version 2.1.8 */ {\n opacity: 0;\n}\n</style>\n","<template>\n <v-container v-if=\"!updatePending\">\n <v-row>\n <v-col cols=\"12\">\n <h1>Which seems <em>harder</em>?</h1>\n </v-col>\n </v-row>\n\n <v-row>\n <v-col>\n <v-btn color=\"success\" class=\"ma-5\" @click=\"vote('a')\">\n <v-icon>mdi-check</v-icon>\n </v-btn>\n <card-loader class=\"ma-2\" :qualified_id=\"id1\" :view-lookup=\"viewLookup\" />\n </v-col>\n </v-row>\n\n <v-row>\n <v-col>\n <v-btn color=\"success\" class=\"ma-5\" @click=\"vote('b')\">\n <v-icon>mdi-check</v-icon>\n </v-btn>\n <card-loader class=\"ma-2\" :qualified_id=\"id2\" :view-lookup=\"viewLookup\" />\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { CardLoader } from '@vue-skuilder/common-ui';\nimport { allCourseWare } from '@vue-skuilder/courseware';\nimport { CourseElo, adjustCourseScores, CourseConfig } from '@vue-skuilder/common';\nimport { CourseDBInterface, getDataLayer, QualifiedCardID } from '@vue-skuilder/db';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'ELOModerator',\n\n components: {\n CardLoader,\n },\n\n props: {\n courseId: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n courseDB: null as CourseDBInterface | null,\n updatePending: true,\n courseConfig: null as CourseConfig | null,\n cards: [] as {\n courseId: string;\n cardId: string;\n elo: CourseElo;\n count: number;\n }[],\n id1: null as QualifiedCardID | null,\n id2: null as QualifiedCardID | null,\n elo1: null as CourseElo | null,\n elo2: null as CourseElo | null,\n viewLookup: allCourseWare.getView,\n };\n },\n\n async created() {\n this.courseDB = getDataLayer().getCourseDB(this.courseId);\n\n this.courseConfig = (await this.courseDB!.getCourseConfig())!;\n await this.getNewCards();\n },\n\n methods: {\n vote(x: 'a' | 'b') {\n if (!this.elo1 || !this.elo2) return;\n\n const scores = adjustCourseScores(this.elo1, this.elo2, x === 'a' ? 1 : 0, {\n globalOnly: true,\n });\n\n this.courseDB!.updateCardElo(this.cards[0].cardId, scores.userElo);\n this.courseDB!.updateCardElo(this.cards[1].cardId, scores.cardElo);\n\n this.getNewCards();\n },\n\n async getNewCards() {\n if (!this.courseDB) return;\n\n this.updatePending = true;\n this.cards = await this.courseDB!.getInexperiencedCards();\n\n // console.log('Comparing:\\n\\t' + JSON.stringify(this.cards));\n\n this.id1 = null;\n this.id2 = null;\n\n this.id1 = {\n courseID: this.courseId,\n cardID: this.cards[0].cardId,\n };\n this.id2 = {\n courseID: this.courseId,\n cardID: this.cards[1].cardId,\n };\n\n this.elo1 = this.cards[0].elo;\n this.elo2 = this.cards[1].elo;\n\n this.updatePending = false;\n },\n },\n});\n</script>\n\n<style scoped>\n.component-fade-enter-active,\n.component-fade-leave-active {\n transition: opacity 0.5s ease;\n}\n.component-fade-enter, .component-fade-leave-to\n/* .component-fade-leave-active below version 2.1.8 */ {\n opacity: 0;\n}\n</style>\n"],"mappings":"inBCmCA,IAAA,EAAe,EAAgB,CAC7B,KAAM,eAEN,WAAY,CACV,WAAA,EACD,CAED,MAAO,CACL,SAAU,CACR,KAAM,OACN,SAAU,GACX,CACF,CAED,MAAO,CACL,MAAO,CACL,SAAU,KACV,cAAe,GACf,aAAc,KACd,MAAO,EAAC,CAMR,IAAK,KACL,IAAK,KACL,KAAM,KACN,KAAM,KACN,WAAY,EAAc,QAC3B,EAGH,MAAM,SAAU,CACd,KAAK,SAAW,GAAc,CAAC,YAAY,KAAK,SAAS,CAEzD,KAAK,aAAgB,MAAM,KAAK,SAAU,iBAAiB,CAC3D,MAAM,KAAK,aAAa,EAG1B,QAAS,CACP,KAAK,EAAc,CACjB,GAAI,CAAC,KAAK,MAAQ,CAAC,KAAK,KAAM,OAE9B,IAAM,EAAS,EAAmB,KAAK,KAAM,KAAK,KAAM,IAAM,IAAM,EAAI,EAAG,CACzE,WAAY,GACb,CAAC,CAEF,KAAK,SAAU,cAAc,KAAK,MAAM,GAAG,OAAQ,EAAO,QAAQ,CAClE,KAAK,SAAU,cAAc,KAAK,MAAM,GAAG,OAAQ,EAAO,QAAQ,CAElE,KAAK,aAAa,EAGpB,MAAM,aAAc,CACb,KAAK,WAEV,KAAK,cAAgB,GACrB,KAAK,MAAQ,MAAM,KAAK,SAAU,uBAAuB,CAIzD,KAAK,IAAM,KACX,KAAK,IAAM,KAEX,KAAK,IAAM,CACT,SAAU,KAAK,SACf,OAAQ,KAAK,MAAM,GAAG,OACvB,CACD,KAAK,IAAM,CACT,SAAU,KAAK,SACf,OAAQ,KAAK,MAAM,GAAG,OACvB,CAED,KAAK,KAAO,KAAK,MAAM,GAAG,IAC1B,KAAK,KAAO,KAAK,MAAM,GAAG,IAE1B,KAAK,cAAgB,KAExB,CACF,CAAC,yIAlHoB,EAAA,cADtB,EAAA,GAAA,GAAA,EACsB,GAAA,CAApB,EAwBc,EAAA,CAzBhB,IAAA,EAAA,CAAA,CAAA,QAAA,MAMY,CAJR,EAIQ,EAAA,KAAA,CANZ,QAAA,MAKc,CAFR,EAEQ,EAAA,CAFD,KAAK,KAAI,CAAA,CAHtB,QAAA,MAI6C,EAAA,KAAA,EAAA,GAAA,CAArC,EAAqC,KAAA,KAAA,CAJ7C,EAIY,eAAY,CAAA,EAAe,KAAA,KAAX,SAAM,CAJlC,EAIuC,IAAC,SAJxC,EAAA,MAAA,EAAA,IAQI,EAOQ,EAAA,KAAA,CAfZ,QAAA,MAcc,CALR,EAKQ,EAAA,KAAA,CAdd,QAAA,MAYgB,CAFR,EAEQ,EAAA,CAFD,MAAM,UAAU,MAAM,OAAQ,QAAK,EAAA,KAAA,EAAA,GAAA,GAAE,EAAA,KAAI,IAAA,IAVxD,QAAA,MAWoC,CAA1B,EAA0B,EAAA,KAAA,CAXpC,QAAA,MAW2B,EAAA,KAAA,EAAA,GAAA,CAX3B,EAWkB,YAAS,CAAA,EAAA,CAX3B,EAAA,MAAA,EAAA,IAaQ,EAA0E,EAAA,CAA7D,MAAM,OAAQ,aAAc,EAAA,IAAM,cAAa,EAAA,qDAbpE,EAAA,MAAA,EAAA,IAiBI,EAOQ,EAAA,KAAA,CAxBZ,QAAA,MAuBc,CALR,EAKQ,EAAA,KAAA,CAvBd,QAAA,MAqBgB,CAFR,EAEQ,EAAA,CAFD,MAAM,UAAU,MAAM,OAAQ,QAAK,EAAA,KAAA,EAAA,GAAA,GAAE,EAAA,KAAI,IAAA,IAnBxD,QAAA,MAoBoC,CAA1B,EAA0B,EAAA,KAAA,CApBpC,QAAA,MAoB2B,EAAA,KAAA,EAAA,GAAA,CApB3B,EAoBkB,YAAS,CAAA,EAAA,CApB3B,EAAA,MAAA,EAAA,IAsBQ,EAA0E,EAAA,CAA7D,MAAM,OAAQ,aAAc,EAAA,IAAM,cAAa,EAAA,qDAtBpE,EAAA,MAAA,EAAA,MAAA,EAAA"}
@@ -1,3 +1,3 @@
1
- import"./chunk-D6hFPZc3.js";import{$ as e,C as t,H as n,K as r,T as i,Vt as a,b as o,v as s}from"./vue.runtime.esm-bundler-C3q8JS9f.js";import{f as c}from"./dist-CrcJCHFk.js";import{k as l}from"./dist-CzLl7g6t.js";import{t as u}from"./index-DUZItsH-.js";var d=i({name:`JoinCode`,props:{classroomId:{type:String,required:!0}},data(){return{classroomCfg:null,classroomDB:null,updatePending:!0}},async created(){this.classroomDB=await l().getClassroomDB(this.classroomId,`teacher`),this.classroomCfg=this.classroomDB.getConfig(),await Promise.all([]),c(`Route loaded w/ (prop) _id: ${this.classroomId}`),c(`Config:
1
+ import"./chunk-D6hFPZc3.js";import{$ as e,C as t,H as n,K as r,T as i,Vt as a,b as o,v as s}from"./vue.runtime.esm-bundler-C3q8JS9f.js";import{f as c}from"./dist-leWgtXBf.js";import{k as l}from"./dist-DA7EuQY2.js";import{t as u}from"./index-B-cSF0fq.js";var d=i({name:`JoinCode`,props:{classroomId:{type:String,required:!0}},data(){return{classroomCfg:null,classroomDB:null,updatePending:!0}},async created(){this.classroomDB=await l().getClassroomDB(this.classroomId,`teacher`),this.classroomCfg=this.classroomDB.getConfig(),await Promise.all([]),c(`Route loaded w/ (prop) _id: ${this.classroomId}`),c(`Config:
2
2
  ${JSON.stringify(this.classroomCfg)}`),this.updatePending=!1},methods:{close(){this.$router.back()}}}),f={key:0,class:`join-code`};function _sfc_render(i,c,l,u,d,p){let m=r(`v-btn`),h=r(`v-progress-circular`),g=r(`v-col`),_=r(`v-row`),v=r(`v-container`);return n(),s(v,{fluid:``,class:`fill-height pa-0`},{default:e(()=>[t(m,{icon:`mdi-close`,color:`red`,variant:`elevated`,class:`close-btn`,onClick:i.close},null,8,[`onClick`]),t(_,{align:`center`,justify:`center`,class:`fill-height`},{default:e(()=>[t(g,{cols:`12`,class:`text-center`},{default:e(()=>[i.updatePending?(n(),s(h,{key:1,indeterminate:``,size:`64`})):(n(),o(`div`,f,a(i.classroomCfg?.joinCode),1))]),_:1})]),_:1})]),_:1})}var p=u(d,[[`render`,_sfc_render]]);export{p as default};
3
- //# sourceMappingURL=JoinCode-DgPD_OFL.js.map
3
+ //# sourceMappingURL=JoinCode-KoSLXpUy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"JoinCode-DgPD_OFL.js","names":[],"sources":["../../src/components/Classrooms/JoinCode.vue","../../src/components/Classrooms/JoinCode.vue"],"sourcesContent":["<template>\n <v-container fluid class=\"fill-height pa-0\">\n <!-- Close button in top-right corner -->\n <v-btn icon=\"mdi-close\" color=\"red\" variant=\"elevated\" class=\"close-btn\" @click=\"close\"> </v-btn>\n\n <!-- Main content -->\n <v-row align=\"center\" justify=\"center\" class=\"fill-height\">\n <v-col cols=\"12\" class=\"text-center\">\n <div v-if=\"!updatePending\" class=\"join-code\">\n {{ classroomCfg?.joinCode }}\n </div>\n <v-progress-circular v-else indeterminate size=\"64\"></v-progress-circular>\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { log } from '@vue-skuilder/common';\nimport { TeacherClassroomDBInterface, getDataLayer } from '@vue-skuilder/db';\nimport { ClassroomConfig } from '@vue-skuilder/common';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'JoinCode',\n\n props: {\n classroomId: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n classroomCfg: null as ClassroomConfig | null,\n classroomDB: null as TeacherClassroomDBInterface | null,\n updatePending: true,\n };\n },\n\n async created() {\n const dl = getDataLayer();\n\n this.classroomDB = await dl.getClassroomDB(this.classroomId, 'teacher');\n this.classroomCfg = this.classroomDB.getConfig();\n await Promise.all([]);\n log(`Route loaded w/ (prop) _id: ${this.classroomId}`);\n log(`Config:\n ${JSON.stringify(this.classroomCfg)}`);\n this.updatePending = false;\n },\n\n methods: {\n close() {\n this.$router.back();\n },\n },\n});\n</script>\n\n<style>\n.close-btn {\n position: fixed;\n top: 80px;\n right: 16px;\n z-index: 100;\n}\n\n.join-code {\n font-size: 8rem;\n font-weight: bold;\n line-height: 1.2;\n letter-spacing: 0.1em;\n}\n\n/* Responsive adjustments */\n@media (max-width: 600px) {\n .join-code {\n font-size: 4rem;\n }\n}\n</style>\n","<template>\n <v-container fluid class=\"fill-height pa-0\">\n <!-- Close button in top-right corner -->\n <v-btn icon=\"mdi-close\" color=\"red\" variant=\"elevated\" class=\"close-btn\" @click=\"close\"> </v-btn>\n\n <!-- Main content -->\n <v-row align=\"center\" justify=\"center\" class=\"fill-height\">\n <v-col cols=\"12\" class=\"text-center\">\n <div v-if=\"!updatePending\" class=\"join-code\">\n {{ classroomCfg?.joinCode }}\n </div>\n <v-progress-circular v-else indeterminate size=\"64\"></v-progress-circular>\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { log } from '@vue-skuilder/common';\nimport { TeacherClassroomDBInterface, getDataLayer } from '@vue-skuilder/db';\nimport { ClassroomConfig } from '@vue-skuilder/common';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'JoinCode',\n\n props: {\n classroomId: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n classroomCfg: null as ClassroomConfig | null,\n classroomDB: null as TeacherClassroomDBInterface | null,\n updatePending: true,\n };\n },\n\n async created() {\n const dl = getDataLayer();\n\n this.classroomDB = await dl.getClassroomDB(this.classroomId, 'teacher');\n this.classroomCfg = this.classroomDB.getConfig();\n await Promise.all([]);\n log(`Route loaded w/ (prop) _id: ${this.classroomId}`);\n log(`Config:\n ${JSON.stringify(this.classroomCfg)}`);\n this.updatePending = false;\n },\n\n methods: {\n close() {\n this.$router.back();\n },\n },\n});\n</script>\n\n<style>\n.close-btn {\n position: fixed;\n top: 80px;\n right: 16px;\n z-index: 100;\n}\n\n.join-code {\n font-size: 8rem;\n font-weight: bold;\n line-height: 1.2;\n letter-spacing: 0.1em;\n}\n\n/* Responsive adjustments */\n@media (max-width: 600px) {\n .join-code {\n font-size: 4rem;\n }\n}\n</style>\n"],"mappings":"8PCuBA,IAAA,EAAe,EAAgB,CAC7B,KAAM,WAEN,MAAO,CACL,YAAa,CACX,KAAM,OACN,SAAU,GACX,CACF,CAED,MAAO,CACL,MAAO,CACL,aAAc,KACd,YAAa,KACb,cAAe,GAChB,EAGH,MAAM,SAAU,CAGd,KAAK,YAAc,MAFR,GAAc,CAEG,eAAe,KAAK,YAAa,UAAU,CACvE,KAAK,aAAe,KAAK,YAAY,WAAW,CAChD,MAAM,QAAQ,IAAI,EAAE,CAAC,CACrB,EAAI,+BAA+B,KAAK,cAAc,CACtD,EAAI;MACF,KAAK,UAAU,KAAK,aAAa,GAAG,CACtC,KAAK,cAAgB,IAGvB,QAAS,CACP,OAAQ,CACN,KAAK,QAAQ,MAAM,EAEtB,CACF,CAAC,IA1DF,IAAA,EAQmC,MAAM,mJAPvC,EAac,EAAA,CAbD,MAAA,GAAM,MAAM,qBAD3B,QAAA,MAGqG,CAAjG,EAAiG,EAAA,CAA1F,KAAK,YAAY,MAAM,MAAM,QAAQ,WAAW,MAAM,YAAa,QAAO,EAAA,2BAGjF,EAOQ,EAAA,CAPD,MAAM,SAAS,QAAQ,SAAS,MAAM,gBANjD,QAAA,MAYc,CALR,EAKQ,EAAA,CALD,KAAK,KAAK,MAAM,gBAP7B,QAAA,MAUc,CAFM,EAAA,eACe,GAAA,CAE3B,EAA0E,EAAA,CAXlF,IAAA,EAWoC,cAAA,GAAc,KAAK,SAHnC,GAAA,CAAZ,EAEM,MAFN,EAEM,EADD,EAAA,cAAc,SAAQ,CAAA,EAAA,IATnC,EAAA,MAAA,EAAA,MAAA,EAAA"}
1
+ {"version":3,"file":"JoinCode-KoSLXpUy.js","names":[],"sources":["../../src/components/Classrooms/JoinCode.vue","../../src/components/Classrooms/JoinCode.vue"],"sourcesContent":["<template>\n <v-container fluid class=\"fill-height pa-0\">\n <!-- Close button in top-right corner -->\n <v-btn icon=\"mdi-close\" color=\"red\" variant=\"elevated\" class=\"close-btn\" @click=\"close\"> </v-btn>\n\n <!-- Main content -->\n <v-row align=\"center\" justify=\"center\" class=\"fill-height\">\n <v-col cols=\"12\" class=\"text-center\">\n <div v-if=\"!updatePending\" class=\"join-code\">\n {{ classroomCfg?.joinCode }}\n </div>\n <v-progress-circular v-else indeterminate size=\"64\"></v-progress-circular>\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { log } from '@vue-skuilder/common';\nimport { TeacherClassroomDBInterface, getDataLayer } from '@vue-skuilder/db';\nimport { ClassroomConfig } from '@vue-skuilder/common';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'JoinCode',\n\n props: {\n classroomId: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n classroomCfg: null as ClassroomConfig | null,\n classroomDB: null as TeacherClassroomDBInterface | null,\n updatePending: true,\n };\n },\n\n async created() {\n const dl = getDataLayer();\n\n this.classroomDB = await dl.getClassroomDB(this.classroomId, 'teacher');\n this.classroomCfg = this.classroomDB.getConfig();\n await Promise.all([]);\n log(`Route loaded w/ (prop) _id: ${this.classroomId}`);\n log(`Config:\n ${JSON.stringify(this.classroomCfg)}`);\n this.updatePending = false;\n },\n\n methods: {\n close() {\n this.$router.back();\n },\n },\n});\n</script>\n\n<style>\n.close-btn {\n position: fixed;\n top: 80px;\n right: 16px;\n z-index: 100;\n}\n\n.join-code {\n font-size: 8rem;\n font-weight: bold;\n line-height: 1.2;\n letter-spacing: 0.1em;\n}\n\n/* Responsive adjustments */\n@media (max-width: 600px) {\n .join-code {\n font-size: 4rem;\n }\n}\n</style>\n","<template>\n <v-container fluid class=\"fill-height pa-0\">\n <!-- Close button in top-right corner -->\n <v-btn icon=\"mdi-close\" color=\"red\" variant=\"elevated\" class=\"close-btn\" @click=\"close\"> </v-btn>\n\n <!-- Main content -->\n <v-row align=\"center\" justify=\"center\" class=\"fill-height\">\n <v-col cols=\"12\" class=\"text-center\">\n <div v-if=\"!updatePending\" class=\"join-code\">\n {{ classroomCfg?.joinCode }}\n </div>\n <v-progress-circular v-else indeterminate size=\"64\"></v-progress-circular>\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { log } from '@vue-skuilder/common';\nimport { TeacherClassroomDBInterface, getDataLayer } from '@vue-skuilder/db';\nimport { ClassroomConfig } from '@vue-skuilder/common';\nimport { defineComponent } from 'vue';\n\nexport default defineComponent({\n name: 'JoinCode',\n\n props: {\n classroomId: {\n type: String,\n required: true,\n },\n },\n\n data() {\n return {\n classroomCfg: null as ClassroomConfig | null,\n classroomDB: null as TeacherClassroomDBInterface | null,\n updatePending: true,\n };\n },\n\n async created() {\n const dl = getDataLayer();\n\n this.classroomDB = await dl.getClassroomDB(this.classroomId, 'teacher');\n this.classroomCfg = this.classroomDB.getConfig();\n await Promise.all([]);\n log(`Route loaded w/ (prop) _id: ${this.classroomId}`);\n log(`Config:\n ${JSON.stringify(this.classroomCfg)}`);\n this.updatePending = false;\n },\n\n methods: {\n close() {\n this.$router.back();\n },\n },\n});\n</script>\n\n<style>\n.close-btn {\n position: fixed;\n top: 80px;\n right: 16px;\n z-index: 100;\n}\n\n.join-code {\n font-size: 8rem;\n font-weight: bold;\n line-height: 1.2;\n letter-spacing: 0.1em;\n}\n\n/* Responsive adjustments */\n@media (max-width: 600px) {\n .join-code {\n font-size: 4rem;\n }\n}\n</style>\n"],"mappings":"8PCuBA,IAAA,EAAe,EAAgB,CAC7B,KAAM,WAEN,MAAO,CACL,YAAa,CACX,KAAM,OACN,SAAU,GACX,CACF,CAED,MAAO,CACL,MAAO,CACL,aAAc,KACd,YAAa,KACb,cAAe,GAChB,EAGH,MAAM,SAAU,CAGd,KAAK,YAAc,MAFR,GAAc,CAEG,eAAe,KAAK,YAAa,UAAU,CACvE,KAAK,aAAe,KAAK,YAAY,WAAW,CAChD,MAAM,QAAQ,IAAI,EAAE,CAAC,CACrB,EAAI,+BAA+B,KAAK,cAAc,CACtD,EAAI;MACF,KAAK,UAAU,KAAK,aAAa,GAAG,CACtC,KAAK,cAAgB,IAGvB,QAAS,CACP,OAAQ,CACN,KAAK,QAAQ,MAAM,EAEtB,CACF,CAAC,IA1DF,IAAA,EAQmC,MAAM,mJAPvC,EAac,EAAA,CAbD,MAAA,GAAM,MAAM,qBAD3B,QAAA,MAGqG,CAAjG,EAAiG,EAAA,CAA1F,KAAK,YAAY,MAAM,MAAM,QAAQ,WAAW,MAAM,YAAa,QAAO,EAAA,2BAGjF,EAOQ,EAAA,CAPD,MAAM,SAAS,QAAQ,SAAS,MAAM,gBANjD,QAAA,MAYc,CALR,EAKQ,EAAA,CALD,KAAK,KAAK,MAAM,gBAP7B,QAAA,MAUc,CAFM,EAAA,eACe,GAAA,CAE3B,EAA0E,EAAA,CAXlF,IAAA,EAWoC,cAAA,GAAc,KAAK,SAHnC,GAAA,CAAZ,EAEM,MAFN,EAEM,EADD,EAAA,cAAc,SAAQ,CAAA,EAAA,IATnC,EAAA,MAAA,EAAA,MAAA,EAAA"}