From dea7bfc5d0a50230702b6942ae62459994caf444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Dietrich?= Date: Thu, 2 Mar 2023 10:49:19 +0100 Subject: [PATCH 01/11] fix: prevent reading file in 'memory' mode --- dist/app.js | 2 +- dist/static/200.html | 4 +-- dist/static/_nuxt/{c07bfe1.js => 66d19af.js} | 0 dist/static/_nuxt/LICENSES | 30 ++++++++++---------- dist/static/_nuxt/{4f34372.js => cbd1cfd.js} | 0 dist/static/_nuxt/{e79d311.js => d79b545.js} | 2 +- dist/static/_nuxt/{557d4ed.js => de6de5c.js} | 0 dist/static/_nuxt/{1f1f747.js => e1eb2d9.js} | 0 dist/static/_nuxt/{d960efc.js => e6ac9d3.js} | 0 dist/static/index.html | 4 +-- server/auth.ts | 2 +- 11 files changed, 22 insertions(+), 22 deletions(-) rename dist/static/_nuxt/{c07bfe1.js => 66d19af.js} (100%) rename dist/static/_nuxt/{4f34372.js => cbd1cfd.js} (100%) rename dist/static/_nuxt/{e79d311.js => d79b545.js} (94%) rename dist/static/_nuxt/{557d4ed.js => de6de5c.js} (100%) rename dist/static/_nuxt/{1f1f747.js => e1eb2d9.js} (100%) rename dist/static/_nuxt/{d960efc.js => e6ac9d3.js} (100%) diff --git a/dist/app.js b/dist/app.js index 98cfe50..b84e4e5 100644 --- a/dist/app.js +++ b/dist/app.js @@ -28685,7 +28685,7 @@ async function get_class_and_role(class_id, user_id) { } let jwt_public_key; let jwt_private_key; -if (jwt_keys_path) { +if (jwt_keys_path && data_engine !== 'memory') { jwt_private_key = await crypto.subtle.importKey('pkcs8', mod9.decode(await Deno.readTextFile(`${jwt_keys_path}/jwt_private_key`)), { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-512' diff --git a/dist/static/200.html b/dist/static/200.html index b5b6342..ca1aaaf 100644 --- a/dist/static/200.html +++ b/dist/static/200.html @@ -1,9 +1,9 @@ - Home - Edrys + Home - Edrys
Loading...
- + diff --git a/dist/static/_nuxt/c07bfe1.js b/dist/static/_nuxt/66d19af.js similarity index 100% rename from dist/static/_nuxt/c07bfe1.js rename to dist/static/_nuxt/66d19af.js diff --git a/dist/static/_nuxt/LICENSES b/dist/static/_nuxt/LICENSES index 464cec5..4b2c26f 100644 --- a/dist/static/_nuxt/LICENSES +++ b/dist/static/_nuxt/LICENSES @@ -15,21 +15,6 @@ */ -/*! - * vue-client-only v0.0.0-semantic-release - * (c) 2021-present egoist <0x142857@gmail.com> - * Released under the MIT License. - */ - -/*! - * vue-no-ssr v1.1.1 - * (c) 2018-present egoist <0x142857@gmail.com> - * Released under the MIT License. - */ - -/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ - - /*! * vue-router v3.5.3 * (c) 2021 Evan You @@ -47,3 +32,18 @@ * (c) 2021 Evan You * @license MIT */ + + +/*! + * vue-client-only v0.0.0-semantic-release + * (c) 2021-present egoist <0x142857@gmail.com> + * Released under the MIT License. + */ + +/*! + * vue-no-ssr v1.1.1 + * (c) 2018-present egoist <0x142857@gmail.com> + * Released under the MIT License. + */ + +/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ diff --git a/dist/static/_nuxt/4f34372.js b/dist/static/_nuxt/cbd1cfd.js similarity index 100% rename from dist/static/_nuxt/4f34372.js rename to dist/static/_nuxt/cbd1cfd.js diff --git a/dist/static/_nuxt/e79d311.js b/dist/static/_nuxt/d79b545.js similarity index 94% rename from dist/static/_nuxt/e79d311.js rename to dist/static/_nuxt/d79b545.js index cbf3304..4755d7c 100644 --- a/dist/static/_nuxt/e79d311.js +++ b/dist/static/_nuxt/d79b545.js @@ -1 +1 @@ -!function(e){function r(data){for(var r,n,f=data[0],l=data[1],d=data[2],i=0,h=[];i - Home - Edrys + Home - Edrys
Loading...
- + diff --git a/server/auth.ts b/server/auth.ts index efc1435..ab18b62 100644 --- a/server/auth.ts +++ b/server/auth.ts @@ -10,7 +10,7 @@ let jwt_private_key: any /** * Init JWT keys */ -if (env.jwt_keys_path) { +if (env.jwt_keys_path && env.data_engine !== 'memory') { /** * If a key pair is provided, use public key scheme */ From 9fe12578188c2dc5db91eed951731c2bd39eccd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Dietrich?= Date: Tue, 14 Mar 2023 14:29:16 +0100 Subject: [PATCH 02/11] chore: set default serve path to dist/static --- server/env.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/env.ts b/server/env.ts index 078021b..e7d6886 100644 --- a/server/env.ts +++ b/server/env.ts @@ -22,7 +22,7 @@ if (secret == 'secret') 'For production, please specify a unique --secret to generate a secret private key. Currently using default.' ) export const totp_window = parseInt(getArg('TOTP_WINDOW')) -export const serve_path = getArg('SERVE_PATH') ?? `./static` +export const serve_path = getArg('SERVE_PATH') ?? `dist/static` export const config_class_creators = ( getArg('CONFIG_CLASS_CREATORS_CSV') ?? '*' ).split(',') From 32cbb84f5f18a7138794a1b2a369858896372b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Dietrich?= Date: Tue, 14 Mar 2023 14:29:56 +0100 Subject: [PATCH 03/11] improve: test read permission in authentification --- server/auth.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/auth.ts b/server/auth.ts index d259cd5..0d70fc6 100644 --- a/server/auth.ts +++ b/server/auth.ts @@ -7,10 +7,12 @@ export let ready = false export let jwt_public_key: any let jwt_private_key: any +const readPermission = await Deno.permissions.query({ name: 'read' }) + /** * Init JWT keys */ -if (env.jwt_keys_path && env.data_engine === 'file') { +if (env.jwt_keys_path && readPermission.state === 'granted') { /** * If a key pair is provided, use public key scheme */ From 0cb8c23570fc01cb3f7bf21843d0a0858e4339b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Dietrich?= Date: Tue, 14 Mar 2023 14:37:30 +0100 Subject: [PATCH 04/11] Update with read permission check and default serve path --- dist/app.js | 7 ++- dist/static/200.html | 4 +- dist/static/_nuxt/{ec221a2.js => 33034d1.js} | 0 dist/static/_nuxt/{7531966.js => 5eaf00d.js} | 2 +- dist/static/_nuxt/{c07bfe1.js => 66d19af.js} | 0 dist/static/_nuxt/LICENSES | 30 +++++------ dist/static/_nuxt/{4f34372.js => cbd1cfd.js} | 0 dist/static/_nuxt/{557d4ed.js => de6de5c.js} | 0 dist/static/_nuxt/{1f1f747.js => e1eb2d9.js} | 0 dist/static/dist/.nojekyll | 0 dist/static/dist/200.html | 9 ---- dist/static/dist/_nuxt/0486f46.js | 1 - dist/static/dist/_nuxt/1f1f747.js | 1 - dist/static/dist/_nuxt/25e418e.js | 1 - dist/static/dist/_nuxt/2643e57.js | 1 - dist/static/dist/_nuxt/37ef1b7.js | 1 - dist/static/dist/_nuxt/4f34372.js | 1 - dist/static/dist/_nuxt/64533e5.js | 2 - dist/static/dist/_nuxt/7342da3.js | 1 - dist/static/dist/_nuxt/809e9cd.js | 2 - dist/static/dist/_nuxt/LICENSES | 49 ------------------ dist/static/dist/_nuxt/a12ef56.js | 2 - dist/static/dist/_nuxt/a1a65e5.js | 1 - dist/static/dist/_nuxt/c07bfe1.js | 1 - dist/static/dist/_nuxt/c9be933.js | 1 - .../fonts/IBMPlexSans-Medium.e177754.ttf | Bin 182716 -> 0 bytes .../materialdesignicons-webfont.6245a82.woff | Bin 431124 -> 0 bytes .../materialdesignicons-webfont.9b167c7.ttf | Bin 940432 -> 0 bytes .../materialdesignicons-webfont.a7e1929.woff2 | Bin 303580 -> 0 bytes .../materialdesignicons-webfont.d1e00c3.eot | Bin 940652 -> 0 bytes .../dist/_nuxt/img/logo-dark.1825cea.svg | 25 --------- dist/static/dist/_nuxt/img/logo.570d7ce.svg | 25 --------- dist/static/dist/favicon.png | Bin 10861 -> 0 bytes dist/static/dist/index.html | 9 ---- dist/static/dist/sw.js | 17 ------ dist/static/index.html | 4 +- 36 files changed, 25 insertions(+), 172 deletions(-) rename dist/static/_nuxt/{ec221a2.js => 33034d1.js} (100%) rename dist/static/_nuxt/{7531966.js => 5eaf00d.js} (94%) rename dist/static/_nuxt/{c07bfe1.js => 66d19af.js} (100%) rename dist/static/_nuxt/{4f34372.js => cbd1cfd.js} (100%) rename dist/static/_nuxt/{557d4ed.js => de6de5c.js} (100%) rename dist/static/_nuxt/{1f1f747.js => e1eb2d9.js} (100%) delete mode 100644 dist/static/dist/.nojekyll delete mode 100644 dist/static/dist/200.html delete mode 100644 dist/static/dist/_nuxt/0486f46.js delete mode 100644 dist/static/dist/_nuxt/1f1f747.js delete mode 100644 dist/static/dist/_nuxt/25e418e.js delete mode 100644 dist/static/dist/_nuxt/2643e57.js delete mode 100644 dist/static/dist/_nuxt/37ef1b7.js delete mode 100644 dist/static/dist/_nuxt/4f34372.js delete mode 100644 dist/static/dist/_nuxt/64533e5.js delete mode 100644 dist/static/dist/_nuxt/7342da3.js delete mode 100644 dist/static/dist/_nuxt/809e9cd.js delete mode 100644 dist/static/dist/_nuxt/LICENSES delete mode 100644 dist/static/dist/_nuxt/a12ef56.js delete mode 100644 dist/static/dist/_nuxt/a1a65e5.js delete mode 100644 dist/static/dist/_nuxt/c07bfe1.js delete mode 100644 dist/static/dist/_nuxt/c9be933.js delete mode 100644 dist/static/dist/_nuxt/fonts/IBMPlexSans-Medium.e177754.ttf delete mode 100644 dist/static/dist/_nuxt/fonts/materialdesignicons-webfont.6245a82.woff delete mode 100644 dist/static/dist/_nuxt/fonts/materialdesignicons-webfont.9b167c7.ttf delete mode 100644 dist/static/dist/_nuxt/fonts/materialdesignicons-webfont.a7e1929.woff2 delete mode 100644 dist/static/dist/_nuxt/fonts/materialdesignicons-webfont.d1e00c3.eot delete mode 100644 dist/static/dist/_nuxt/img/logo-dark.1825cea.svg delete mode 100644 dist/static/dist/_nuxt/img/logo.570d7ce.svg delete mode 100644 dist/static/dist/favicon.png delete mode 100644 dist/static/dist/index.html delete mode 100644 dist/static/dist/sw.js diff --git a/dist/app.js b/dist/app.js index ab623ba..81fd2df 100644 --- a/dist/app.js +++ b/dist/app.js @@ -26822,7 +26822,7 @@ const address = getArg('ADDRESS') ?? 'localhost:8000'; const secret = getArg('SECRET') ?? 'secret'; if (secret == 'secret') mod8.warning('For production, please specify a unique --secret to generate a secret private key. Currently using default.'); const totp_window = parseInt(getArg('TOTP_WINDOW')); -const serve_path = getArg('SERVE_PATH') ?? `./static`; +const serve_path = getArg('SERVE_PATH') ?? `dist/static`; const config_class_creators = (getArg('CONFIG_CLASS_CREATORS_CSV') ?? '*').split(','); getArg('HTTPS_CERT_FILE') ?? undefined; getArg('HTTPS_KEY_FILE') ?? undefined; @@ -27013,7 +27013,10 @@ async function get_class_and_role(class_id, user_id) { } let jwt_public_key; let jwt_private_key; -if (jwt_keys_path && data_engine === 'file') { +const readPermission = await Deno.permissions.query({ + name: 'read' +}); +if (jwt_keys_path && readPermission.state === 'granted') { jwt_private_key = await crypto.subtle.importKey('pkcs8', mod.decode(await Deno.readTextFile(`${jwt_keys_path}/jwt_private_key`)), { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-512' diff --git a/dist/static/200.html b/dist/static/200.html index 2759e6e..4e79c6a 100644 --- a/dist/static/200.html +++ b/dist/static/200.html @@ -1,9 +1,9 @@ - Home - Edrys + Home - Edrys
Loading...
- + diff --git a/dist/static/_nuxt/ec221a2.js b/dist/static/_nuxt/33034d1.js similarity index 100% rename from dist/static/_nuxt/ec221a2.js rename to dist/static/_nuxt/33034d1.js diff --git a/dist/static/_nuxt/7531966.js b/dist/static/_nuxt/5eaf00d.js similarity index 94% rename from dist/static/_nuxt/7531966.js rename to dist/static/_nuxt/5eaf00d.js index db9a3c0..8658f7f 100644 --- a/dist/static/_nuxt/7531966.js +++ b/dist/static/_nuxt/5eaf00d.js @@ -1 +1 @@ -!function(e){function r(data){for(var r,n,f=data[0],l=data[1],d=data[2],i=0,h=[];i - * Released under the MIT License. - */ - -/*! - * vue-no-ssr v1.1.1 - * (c) 2018-present egoist <0x142857@gmail.com> - * Released under the MIT License. - */ - -/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ - - /*! * vue-router v3.5.3 * (c) 2021 Evan You @@ -47,3 +32,18 @@ * (c) 2021 Evan You * @license MIT */ + + +/*! + * vue-client-only v0.0.0-semantic-release + * (c) 2021-present egoist <0x142857@gmail.com> + * Released under the MIT License. + */ + +/*! + * vue-no-ssr v1.1.1 + * (c) 2018-present egoist <0x142857@gmail.com> + * Released under the MIT License. + */ + +/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ diff --git a/dist/static/_nuxt/4f34372.js b/dist/static/_nuxt/cbd1cfd.js similarity index 100% rename from dist/static/_nuxt/4f34372.js rename to dist/static/_nuxt/cbd1cfd.js diff --git a/dist/static/_nuxt/557d4ed.js b/dist/static/_nuxt/de6de5c.js similarity index 100% rename from dist/static/_nuxt/557d4ed.js rename to dist/static/_nuxt/de6de5c.js diff --git a/dist/static/_nuxt/1f1f747.js b/dist/static/_nuxt/e1eb2d9.js similarity index 100% rename from dist/static/_nuxt/1f1f747.js rename to dist/static/_nuxt/e1eb2d9.js diff --git a/dist/static/dist/.nojekyll b/dist/static/dist/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/dist/static/dist/200.html b/dist/static/dist/200.html deleted file mode 100644 index b554e51..0000000 --- a/dist/static/dist/200.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - Home - Edrys - - -
Loading...
- - diff --git a/dist/static/dist/_nuxt/0486f46.js b/dist/static/dist/_nuxt/0486f46.js deleted file mode 100644 index 73215ff..0000000 --- a/dist/static/dist/_nuxt/0486f46.js +++ /dev/null @@ -1 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{529:function(e,t,n){var content=n(559);content.__esModule&&(content=content.default),"string"==typeof content&&(content=[[e.i,content,""]]),content.locals&&(e.exports=content.locals);(0,n(20).default)("a3a3f8c0",content,!0,{sourceMap:!1})},537:function(e,t,n){"use strict";n.r(t);n(59),n(65),n(12),n(72),n(85),n(13),n(15),n(11),n(16);var r=n(56),o=n(26),l=n(2),c=(n(99),n(61),n(86),n(4),n(46),n(58),n(301),n(179),n(41),n(42),n(27),n(71),n(14),n(546),n(547),n(62),n(84),n(548)),d=(n(549),n(551)),v=(n(552),n(553),n(554),n(555),n(556),n(528)),m=n.n(v);function f(object,e){var t=Object.keys(object);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(object);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(object,e).enumerable}))),t.push.apply(t,n)}return t}function h(e){for(var i=1;i=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,l=!0,c=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return l=e.done,e},e:function(e){c=!0,o=e},f:function(){try{l||null==n.return||n.return()}finally{if(c)throw o}}}}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var i=0,n=new Array(t);i0&&void 0!==arguments[0]?arguments[0]:void 0;try{var t,n,o,l;return e=e||this.$store.state.class_,this.className=e.name,this.memberTeacher=(null===(t=e.members)||void 0===t?void 0:t.teacher.join("\n"))||"",this.memberStudent=(null===(n=e.members)||void 0===n||null===(o=n.student)||void 0===o?void 0:o.join("\n"))||"",this.modules=Object(r.a)(null===(l=e)||void 0===l?void 0:l.modules.map((function(e){return h(h({},e),{},{config:x.dump(e.config),studentConfig:x.dump(e.studentConfig),teacherConfig:x.dump(e.teacherConfig),stationConfig:x.dump(e.stationConfig),showInCustom:e.showInCustom})})))||[],this.memberUrl=window.location.href.replace("#station","").replace("http://","").replace("https://",""),this.stationUrl=window.location.href.replace("#settings","").replace("#station","").replace("http://","").replace("https://","")+"#station",!0}catch(e){return this.errorMessage="The provided classroom configuration does not seem to be valid. I receive the following error message:\n

\n ".concat(e,"\n

\n Please check the content manually."),this.saveError=!0,!1}},copyStationUrl:function(){navigator.clipboard.writeText(this.stationUrl)},copyMemberUrl:function(){navigator.clipboard.writeText(this.memberUrl)},deleteClass:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n,r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=e.$store.state.class_.id,t.prev=1,t.next=4,e.$axios.$get("/data/deleteClass/".concat(n));case 4:t.next=12;break;case 6:return t.prev=6,t.t0=t.catch(1),console.log("Error deleting class...",t.t0),e.saveError=!0,e.errorMessage="Error deleting class: ".concat(t.t0),t.abrupt("return");case 12:return t.next=14,e.$axios.$get("/data/readUser");case 14:return r=t.sent,t.t1=e.$store,t.next=18,e.$axios.$get("/data/updateUser?user=".concat(encodeURIComponent(JSON.stringify(h(h({},r),{},{memberships:r.memberships.filter((function(e){return e.class_id!=n}))})))));case 18:t.t2=t.sent,t.t1.commit.call(t.t1,"setUser",t.t2),e.$router.push({path:"/"});case 21:case"end":return t.stop()}}),t,null,[[1,6]])})))()},strToList:function(e){return e.replace(/ /g,"").split(",").flatMap((function(s){return s.trim().split("\n")}))},importModule:function(){this.modules.push({url:this.moduleImportUrl,config:"",studentConfig:"",teacherConfig:"",stationConfig:"",showInCustom:"",width:"full",height:"tall"}),this.moduleImportUrl=""},save:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(n=e.newClass).modules=n.modules.map((function(e){return h(h({},e),{},{config:x.load(e.config),studentConfig:x.load(e.studentConfig),teacherConfig:x.load(e.teacherConfig),stationConfig:x.load(e.stationConfig),showInCustom:e.showInCustom})})),e.saveError=!1,e.saveSuccess=!1,e.saveLoading=!0,t.prev=5,t.t0=e.$store,t.next=9,e.$axios.$get("/data/updateClass/".concat(e.$store.state.class_.id)+"?class=".concat(encodeURIComponent(JSON.stringify(n))));case 9:t.t1=t.sent,t.t0.commit.call(t.t0,"setClass",t.t1),e.saveLoading=!1,e.saveSuccess=!0,e.$emit("update:pendingEdits",!1),e.$emit("close"),t.next=23;break;case 17:t.prev=17,t.t2=t.catch(5),console.log("Saving failed:",t.t2),e.saveError=!0,e.saveLoading=!1,e.errorMessage="Saving failed with the following error message: ".concat(t.t2);case 23:e.$router.app.refresh();case 24:case"end":return t.stop()}}),t,null,[[5,17]])})))()},highlighter:function(code){return Object(d.highlight)(code,d.languages.yaml,"yaml")}},components:{PrismEditor:c.a,draggable:m.a}},C=k,S=(n(558),n(108)),U=n(143),L=n.n(U),I=n(612),V=n(613),M=n(224),O=n(209),R=n(98),$=n(610),j=n(564),E=n(614),T=n(615),F=n(616),P=n(617),A=n(624),N=n(489),D=n(205),J=n(531),H=n(510),B=n(532),z=n(538),G=n(495),Y=n(625),K=n(611),Q=n(618),W=n(492),X=n(493),Z=n(619),ee=n(626),te=n(623),ne=n(600),re=n(221),ae=n(620),se=n(57),oe=n(230),component=Object(S.a)(C,(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("v-card",[n("v-toolbar",{attrs:{dark:"",flat:""},scopedSlots:e._u([{key:"extension",fn:function(){return[n("v-tabs",{attrs:{"fixed-tabs":"","center-active":"","show-arrows":""},model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab",{attrs:{active:""}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-book-open-outline ")]),e._v("\n Settings\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-account-group ")]),e._v("\n Members\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-dashboard ")]),e._v("\n Modules\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-router-wireless ")]),e._v("\n Stations\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-share-variant ")]),e._v("\n Share\n ")],1)],1)]},proxy:!0}])},[n("v-toolbar-title",[e._v("Class Settings")]),e._v(" "),n("v-spacer"),e._v(" "),n("v-btn",{attrs:{icon:""},on:{click:function(t){return e.$emit("close")}}},[n("v-icon",[e._v("mdi-close")])],1)],1),e._v(" "),n("v-card-text",{staticStyle:{height:"565px"}},[n("v-tabs-items",{staticClass:"pt-5",model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab-item",[n("v-form",{ref:"form",on:{submit:function(t){return t.preventDefault(),e.save.apply(null,arguments)}}},[n("v-text-field",{attrs:{counter:20,label:"Class Name",outlined:"",required:""},model:{value:e.className,callback:function(t){e.className=t},expression:"className"}})],1)],1),e._v(" "),n("v-tab-item",[n("v-alert",{attrs:{outlined:"",dense:"",type:"info"}},[e._v("\n Enter emails below, one per line or separated by commas. Next,\n invite your users in by sharing this link:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"10px"}},[n("a",{attrs:{href:"//"+e.memberUrl}},[e._v(e._s(e.memberUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyMemberUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1)]),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of teacher emails"},model:{value:e.memberTeacher,callback:function(t){e.memberTeacher=t},expression:"memberTeacher"}}),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of student emails"},model:{value:e.memberStudent,callback:function(t){e.memberStudent=t},expression:"memberStudent"}})],1),e._v(" "),n("v-tab-item",[n("v-form",{on:{submit:function(t){return t.preventDefault(),e.importModule.apply(null,arguments)}}},[e.scrapedModules.length==e.modules.length?n("v-list",{attrs:{"two-line":""}},[n("draggable",{attrs:{handle:".handle"},model:{value:e.modules,callback:function(t){e.modules=t},expression:"modules"}},e._l(e.modules,(function(t,i){return n("v-list-item",{key:i,staticClass:"handle"},[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(e._s(e.scrapedModules[i].icon||"mdi-package")+"\n ")])],1),e._v(" "),n("v-list-item-content",[n("v-list-item-title",[e._v(e._s(e.scrapedModules[i].name))]),e._v(" "),n("v-list-item-subtitle",{staticStyle:{"white-space":"break-spaces"},domProps:{innerHTML:e._s(e.scrapedModules[i].description)}})],1),e._v(" "),n("v-list-item-action",[n("v-menu",{attrs:{"close-on-content-click":!1,"nudge-width":200,"offset-x":"","offset-y":"",transition:"slide-y-transition",bottom:""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({attrs:{icon:""}},"v-btn",o,!1),r),[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-cog")])],1)]}}],null,!0)},[e._v(" "),n("v-expansion-panels",{staticStyle:{width:"100%"},attrs:{accordion:""}},[n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-link ")])]},proxy:!0}],null,!0)},[e._v("\n URL\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Module URL"},model:{value:t.url,callback:function(n){e.$set(t,"url",n)},expression:"m.url"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-script-text ")])]},proxy:!0}],null,!0)},[e._v("\n General settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.config,callback:function(n){e.$set(t,"config",n)},expression:"m.config"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-account-circle-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Student Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.studentConfig,callback:function(n){e.$set(t,"studentConfig",n)},expression:"m.studentConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-clipboard-account-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Teacher Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.teacherConfig,callback:function(n){e.$set(t,"teacherConfig",n)},expression:"m.teacherConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-router-wireless ")])]},proxy:!0}],null,!0)},[e._v("\n Station Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.stationConfig,callback:function(n){e.$set(t,"stationConfig",n)},expression:"m.stationConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-eye ")])]},proxy:!0}],null,!0)},[e._v("\n Show in\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Comma separated list of rooms, or: lobby, * for all, teacher-only, station"},model:{value:t.showInCustom,callback:function(n){e.$set(t,"showInCustom",n)},expression:"m.showInCustom"}})],1)],1)],1)],1)],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{icon:""},on:{click:function(){e.modules.splice(i,1)}}},[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-close")])],1)],1)],1)})),1)],1):n("div",[n("v-skeleton-loader",{staticClass:"mx-auto",attrs:{type:"list-item-avatar-two-line"}})],1),e._v(" "),n("v-list-item",[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(" mdi-link ")])],1),e._v(" "),n("v-list-item-content",[n("v-text-field",{attrs:{label:"Module URL",required:""},model:{value:e.moduleImportUrl,callback:function(t){e.moduleImportUrl=t},expression:"moduleImportUrl"}})],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{depressed:"",type:"submit",disabled:!e.validate_url(e.moduleImportUrl)}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-grid-plus ")]),e._v("\n Add\n ")],1)],1)],1)],1),e._v(" "),n("v-divider",{staticClass:"pb-2"}),e._v(" "),n("v-btn",{attrs:{href:"https://github.com/topics/edrys-module",target:"_blank"}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-github ")]),e._v("\n Explore on GitHub\n ")],1)],1),e._v(" "),n("v-tab-item",[e._v("\n To add a new station, simply open this link on the client device:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"15px"}},[n("a",{attrs:{href:"//"+e.stationUrl,target:"_blank"}},[e._v(e._s(e.stationUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyStationUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1),e._v(" "),n("br")]),e._v(" "),n("v-tab-item",[n("v-row",[n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("yaml")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.yml)\n ")],1)],1),e._v(" "),n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("json")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.json)\n ")],1)],1)],1),e._v(" "),n("v-row",[n("v-col",[n("v-file-input",{attrs:{dense:"",rules:e.restoreFileRules,accept:"application/yaml,application/json",label:"Restore class from file (yaml, json)","prepend-icon":"mdi-upload"},on:{change:e.restoreFile},model:{value:e.selectedFile,callback:function(t){e.selectedFile=t},expression:"selectedFile"}})],1),e._v(" "),n("v-col",[n("v-row",{attrs:{"no-gutters":""}},[n("v-col",{attrs:{cols:"4"}},[n("v-btn",{attrs:{"prepend-icon":"mdi-link"},on:{click:e.restoreURL}},[n("v-icon",[e._v("\n mdi-link\n ")]),e._v("\n Load\n ")],1)],1),e._v(" "),n("v-col",{attrs:{cols:"8"}},[n("v-text-field",{attrs:{dense:"",label:"class from URL"},on:{keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.restoreURL.apply(null,arguments)}},model:{value:e.selectedURL,callback:function(t){e.selectedURL=t},expression:"selectedURL"}})],1)],1)],1)],1)],1)],1),e._v(" "),e.errorMessage?n("v-alert",{attrs:{"close-text":"Close Alert",color:"red",type:"error",dark:"",outlined:"",dismissible:""},on:{input:function(){e.errorMessage=void 0}}},[n("div",{domProps:{innerHTML:e._s(e.errorMessage)}})]):e._e()],1),e._v(" "),n("v-snackbar",{attrs:{timeout:2e3,value:e.restoreSuccess,absolute:"",bottom:"",right:"",color:"success"}},[e._v("\n File restored - check everything is okay then save\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:600,value:e.saveSuccess,absolute:"",bottom:"",right:""}},[e._v("\n Class saved successfully\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:1400,value:e.saveError,color:"error",absolute:"",bottom:"",right:""}},[e._v("\n Sorry there was a problem saving, please try again\n ")]),e._v(" "),n("v-card-actions",[n("div",{staticClass:"pr-4 float-right"},[n("v-badge",{staticStyle:{"margin-top":"30px"},attrs:{overlap:"",dot:"",color:"red",value:e.pendingEdits}},[n("v-btn",{attrs:{color:"primary",loading:e.saveLoading,disabled:e.saveLoading},on:{click:e.save}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-upload ")]),e._v("\n Save\n ")],1)],1)],1),e._v(" "),n("v-menu",{attrs:{"offset-y":""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({staticClass:"float-right",staticStyle:{"margin-top":"30px","margin-right":"10px"},attrs:{color:"",depressed:""}},"v-btn",o,!1),r),[e._v("\n Delete Class")])]}}])},[e._v(" "),n("v-list",[n("v-list-item",[n("v-list-item-content",[e._v("Are you sure?\n\n "),n("v-btn",{staticClass:"float-right",staticStyle:{"margin-top":"10px"},attrs:{color:"red",depressed:""},on:{click:e.deleteClass}},[e._v("\n Yes, delete forever")])],1)],1)],1)],1)],1)],1)}),[],!1,null,null,null);t.default=component.exports;L()(component,{VAlert:I.a,VBadge:V.a,VBtn:M.a,VCard:O.a,VCardActions:R.a,VCardText:R.c,VCol:$.a,VDivider:j.a,VExpansionPanel:E.a,VExpansionPanelContent:T.a,VExpansionPanelHeader:F.a,VExpansionPanels:P.a,VFileInput:A.a,VForm:N.a,VIcon:D.a,VList:J.a,VListItem:H.a,VListItemAction:B.a,VListItemAvatar:z.a,VListItemContent:G.a,VListItemSubtitle:G.b,VListItemTitle:G.c,VMenu:Y.a,VRow:K.a,VSkeletonLoader:Q.a,VSnackbar:W.a,VSpacer:X.a,VTab:Z.a,VTabItem:ee.a,VTabs:te.a,VTabsItems:ne.a,VTextField:re.a,VTextarea:ae.a,VToolbar:se.a,VToolbarTitle:oe.a})},558:function(e,t,n){"use strict";n(529)},559:function(e,t,n){var r=n(19)(!1);r.push([e.i,".prism-editor{background:#2d2d2d;color:#ccc;font-family:Fira code,Fira Mono,Consolas,Menlo,Courier,monospace;font-size:14px;line-height:1.5;padding:5px;max-height:35 vh}",""]),e.exports=r}}]); \ No newline at end of file diff --git a/dist/static/dist/_nuxt/1f1f747.js b/dist/static/dist/_nuxt/1f1f747.js deleted file mode 100644 index 1ed55a0..0000000 --- a/dist/static/dist/_nuxt/1f1f747.js +++ /dev/null @@ -1 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[8,6,7],{497:function(e,t,r){var content=r(501);content.__esModule&&(content=content.default),"string"==typeof content&&(content=[[e.i,content,""]]),content.locals&&(e.exports=content.locals);(0,r(20).default)("4a760226",content,!0,{sourceMap:!1})},498:function(e,t,r){"use strict";r.r(t);var n=r(2);r(4),r(46),r(58),r(301),r(179),r(13),r(12),r(14),r(15),r(11),r(16);function o(object,e){var t=Object.keys(object);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(object);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(object,e).enumerable}))),t.push.apply(t,r)}return t}var c={name:"Module",props:["role","username","liveClassProxy","scrapedModule"],data:function(){return{}},computed:{iframeOrigin:function(){return new URL(this.scrapedModule.url).origin}},watch:{liveClassProxy:function(){this.updateIframe()},"$store.state.lastRecievedMessage":function(e){null!=e&&this.$refs.iframe.contentWindow.postMessage(function(e){for(var i=1;i=1?r("div",{staticClass:"title",staticStyle:{padding:"10px"}},[t._v("\n My Classes\n ")]):r("div",{staticClass:"subtitle",staticStyle:{padding:"10px"}},[t._v("\n Looks like you aren't a part of any classes on this isntance yet.\n Ask your instructors for an invite link.\n ")]),t._v(" "),r("div",{staticClass:"items"},[t._l(this.$store.state.user.memberships,(function(e){return r("v-card",{key:e.class_id,staticClass:"item",attrs:{elevation:"2",to:"/class/"+e.class_id,nuxt:""}},[r("v-card-title",[t._v(t._s(e.class_name))]),t._v(" "),r("v-card-subtitle",["student"==e.role?r("span",[t._v("You're a student here")]):"teacher"==e.role?r("span",[t._v("You teach this class")]):t._e()]),t._v(" "),r("v-card-actions",[r("v-spacer"),t._v(" "),r("v-btn",{attrs:{icon:""}},[r("v-icon",[t._v("mdi-arrow-right-bold")])],1)],1)],1)})),t._v(" "),r("v-card",{directives:[{name:"show",rawName:"v-show",value:t.canCreateClass,expression:"canCreateClass"}],staticClass:"item",attrs:{color:"primary",elevation:"2",disabled:t.creatingClass},on:{click:function(e){t.canCreateClass?t.createClass():t.alertCantCreateClass=!0}}},[r("v-card-title",[t._v("Create a class")]),t._v(" "),r("v-card-subtitle",[t._v("Start teaching now")]),t._v(" "),r("v-card-actions",[r("v-spacer"),t._v(" "),r("v-btn",{attrs:{icon:"",loading:t.creatingClass,disabled:t.creatingClass}},[r("v-icon",[t._v("mdi-plus")])],1)],1)],1),t._v(" "),r("v-dialog",{attrs:{width:"500"},model:{value:t.alertCantCreateClass,callback:function(e){t.alertCantCreateClass=e},expression:"alertCantCreateClass"}},[r("v-card",[r("v-card-title",[t._v(" Sorry ")]),t._v(" "),r("v-card-text",[t._v("\n It looks like you're not allowed to create new classes on your\n current instance. Switch to a new instance and try again.\n ")]),t._v(" "),r("v-divider"),t._v(" "),r("v-card-actions",[r("v-spacer"),t._v(" "),r("v-btn",{attrs:{color:"primary",text:""},on:{click:function(e){t.alertCantCreateClass=!1}}},[t._v("\n OK\n ")])],1)],1)],1)],2)])],1)],1)],1)}),[],!1,null,"605003e9",null);e.default=component.exports;d()(component,{VBtn:v.a,VCard:h.a,VCardActions:m.a,VCardSubtitle:m.b,VCardText:m.c,VCardTitle:m.d,VCol:f.a,VContainer:C.a,VDialog:x.a,VDivider:y.a,VIcon:w.a,VRow:_.a,VSpacer:O.a})}}]); \ No newline at end of file diff --git a/dist/static/dist/_nuxt/37ef1b7.js b/dist/static/dist/_nuxt/37ef1b7.js deleted file mode 100644 index 2603ae0..0000000 --- a/dist/static/dist/_nuxt/37ef1b7.js +++ /dev/null @@ -1 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{215:function(e,t,o){"use strict";o(13),o(14),o(15),o(11),o(16);var n=o(2),r=o(26),c=(o(99),o(27),o(144),o(4),o(73),o(46),o(58),o(301),o(179),o(32),o(71),o(83),o(86),o(61),o(42),o(12),o(72),o(432),o(148),o(62),o(433),o(435),o(437),o(443),o(445),o(446),o(447),o(450),o(451),o(452),o(453),o(454),o(455),o(456),o(457),o(459),o(460),o(461),o(462),o(463),o(464),o(465),o(466),o(467),o(468),o(469),o(43),o(1)),m=o(293);function d(object,e){var t=Object.keys(object);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(object);e&&(o=o.filter((function(e){return Object.getOwnPropertyDescriptor(object,e).enumerable}))),t.push.apply(t,o)}return t}function f(e){for(var i=1;i<\/script>'):'');var o=new URL(t,base).toString();return'
Loading...
- - diff --git a/dist/static/dist/sw.js b/dist/static/dist/sw.js deleted file mode 100644 index 2d4d460..0000000 --- a/dist/static/dist/sw.js +++ /dev/null @@ -1,17 +0,0 @@ -// THIS FILE SHOULD NOT BE VERSION CONTROLLED - -// https://github.com/NekR/self-destroying-sw - -self.addEventListener('install', function (e) { - self.skipWaiting() -}) - -self.addEventListener('activate', function (e) { - self.registration.unregister() - .then(function () { - return self.clients.matchAll() - }) - .then(function (clients) { - clients.forEach(client => client.navigate(client.url)) - }) -}) diff --git a/dist/static/index.html b/dist/static/index.html index 2759e6e..4e79c6a 100644 --- a/dist/static/index.html +++ b/dist/static/index.html @@ -1,9 +1,9 @@ - Home - Edrys + Home - Edrys
Loading...
- + From 0cb81dd31b18ab25e4324537b6f3fd804baf6383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Dietrich?= Date: Wed, 15 Mar 2023 12:35:28 +0100 Subject: [PATCH 05/11] improve: Add readPermission check set default engine 'file' or 'memory' --- server/env.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/server/env.ts b/server/env.ts index e7d6886..b864082 100644 --- a/server/env.ts +++ b/server/env.ts @@ -44,7 +44,11 @@ export const smtp_debug = getArg('SMTP_DEBUG') == 'true' /** * Data */ -export const data_engine = getArg('DATA_ENGINE') ?? 'file' +const readPermission = + (await Deno.permissions.query({ name: 'read' })).state === 'granted' + +export const data_engine = + getArg('DATA_ENGINE') ?? (readPermission ? 'file' : 'memory') export const data_file_path = getArg('DATA_FILE_PATH') ?? '.edrys' export const data_s3_endpoint = getArg('DATA_S3_ENDPOINT') ?? '' export const data_s3_port = Number(getArg('DATA_S3_PORT') ?? '443') @@ -54,6 +58,16 @@ export const data_s3_access_key = getArg('DATA_S3_ACCESS_KEY') ?? '' export const data_s3_secret_key = getArg('DATA_S3_SECRET_KEY') ?? '' export const data_s3_bucket = getArg('DATA_S3_BUCKET') ?? '' +if (!getArg('DATA_ENGINE')) { + if (readPermission) { + log.debug('Undefined "DATA_ENGINE", setting storage to file.') + } else { + log.warning( + 'Undefined "DATA_ENGINE" and no write access, setting storage to memory. Use this not in production, all states will be deleted after a reload.' + ) + } +} + /** * Advanced */ From 04f508978fd12214620b28dd105e1ede428bf96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Dietrich?= Date: Wed, 15 Mar 2023 12:44:43 +0100 Subject: [PATCH 06/11] updated logging --- dist/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/app.js b/dist/app.js index 097d9d8..8bc947c 100644 --- a/dist/app.js +++ b/dist/app.js @@ -26835,7 +26835,7 @@ const smtp_password = getArg('SMTP_PASSWORD') ?? ''; const smtp_from = getArg('SMTP_FROM') ?? ''; const smtp_debug = getArg('SMTP_DEBUG') == 'true'; const readPermission = (await Deno.permissions.query({ - name: 'read' + name: 'write' })).state === 'granted'; const data_engine = getArg('DATA_ENGINE') ?? (readPermission ? 'file' : 'memory'); const data_file_path = getArg('DATA_FILE_PATH') ?? '.edrys'; @@ -26848,7 +26848,7 @@ const data_s3_secret_key = getArg('DATA_S3_SECRET_KEY') ?? ''; const data_s3_bucket = getArg('DATA_S3_BUCKET') ?? ''; if (!getArg('DATA_ENGINE')) { if (readPermission) { - mod8.debug('Undefined "DATA_ENGINE", setting storage to file.'); + mod8.warning('Undefined "DATA_ENGINE", setting storage to file.'); } else { mod8.warning('Undefined "DATA_ENGINE" and no write access, setting storage to memory. Use this not in production, all states will be deleted after a reload.'); } From 8b592d257a7d709f3e7ddc7b62d06c0ec6309e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Dietrich?= Date: Wed, 10 May 2023 14:45:51 +0200 Subject: [PATCH 07/11] new build --- dist/app.js | 5 +++-- dist/static/200.html | 4 ++-- dist/static/_nuxt/579ea4e.js | 1 + dist/static/_nuxt/a9673ed.js | 1 - dist/static/_nuxt/{7d05504.js => c16fb80.js} | 2 +- dist/static/index.html | 4 ++-- 6 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 dist/static/_nuxt/579ea4e.js delete mode 100644 dist/static/_nuxt/a9673ed.js rename dist/static/_nuxt/{7d05504.js => c16fb80.js} (97%) diff --git a/dist/app.js b/dist/app.js index a3ed7ce..7c8c719 100644 --- a/dist/app.js +++ b/dist/app.js @@ -27266,10 +27266,11 @@ const router1 = new mod6.Router().get('/readUser', async (ctx)=>{ ctx.response.body = new_class_id; ctx.response.status = 200; } -}).get('/updateClass/:class_id', async (ctx)=>{ +}).post('/updateClass/:class_id', async (ctx)=>{ if (!ctx.state.user) ctx.throw(401); const class_id = ctx?.params?.class_id; - const class_new = JSON.parse(mod6.helpers.getQuery(ctx)['class']); + const body = await ctx.request.body(); + const class_new = body.type === 'json' ? await body.value : null; if (!class_new || class_id != class_new.id || !validate_class(class_new)) { ctx.response.status = 400; return; diff --git a/dist/static/200.html b/dist/static/200.html index d4fdf1f..e802366 100644 --- a/dist/static/200.html +++ b/dist/static/200.html @@ -1,9 +1,9 @@ - Home - Edrys + Home - Edrys
Loading...
- + diff --git a/dist/static/_nuxt/579ea4e.js b/dist/static/_nuxt/579ea4e.js new file mode 100644 index 0000000..55c4b1a --- /dev/null +++ b/dist/static/_nuxt/579ea4e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{529:function(e,t,n){var content=n(559);content.__esModule&&(content=content.default),"string"==typeof content&&(content=[[e.i,content,""]]),content.locals&&(e.exports=content.locals);(0,n(20).default)("a3a3f8c0",content,!0,{sourceMap:!1})},537:function(e,t,n){"use strict";n.r(t);n(59),n(65),n(12),n(72),n(85),n(13),n(15),n(11),n(16);var r=n(56),o=n(26),l=n(2),c=(n(99),n(61),n(86),n(4),n(46),n(58),n(301),n(179),n(41),n(42),n(27),n(71),n(14),n(546),n(547),n(62),n(84),n(548)),d=(n(549),n(551)),v=(n(552),n(553),n(554),n(555),n(556),n(528)),m=n.n(v);function f(object,e){var t=Object.keys(object);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(object);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(object,e).enumerable}))),t.push.apply(t,n)}return t}function h(e){for(var i=1;i=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,l=!0,c=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return l=e.done,e},e:function(e){c=!0,o=e},f:function(){try{l||null==n.return||n.return()}finally{if(c)throw o}}}}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var i=0,n=new Array(t);i0&&void 0!==arguments[0]?arguments[0]:void 0;try{var t,n,o,l;return e=e||this.$store.state.class_,this.className=e.name,this.memberTeacher=(null===(t=e.members)||void 0===t?void 0:t.teacher.join("\n"))||"",this.memberStudent=(null===(n=e.members)||void 0===n||null===(o=n.student)||void 0===o?void 0:o.join("\n"))||"",this.modules=Object(r.a)(null===(l=e)||void 0===l?void 0:l.modules.map((function(e){return h(h({},e),{},{config:x.dump(e.config),studentConfig:x.dump(e.studentConfig),teacherConfig:x.dump(e.teacherConfig),stationConfig:x.dump(e.stationConfig),showInCustom:e.showInCustom})})))||[],this.memberUrl=window.location.href.replace("#station","").replace("http://","").replace("https://",""),this.stationUrl=window.location.href.replace("#settings","").replace("#station","").replace("http://","").replace("https://","")+"#station",!0}catch(e){return this.errorMessage="The provided classroom configuration does not seem to be valid. I receive the following error message:\n

\n ".concat(e,"\n

\n Please check the content manually."),this.saveError=!0,!1}},copyStationUrl:function(){navigator.clipboard.writeText(this.stationUrl)},copyMemberUrl:function(){navigator.clipboard.writeText(this.memberUrl)},deleteClass:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n,r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=e.$store.state.class_.id,t.prev=1,t.next=4,e.$axios.$get("/data/deleteClass/".concat(n));case 4:t.next=12;break;case 6:return t.prev=6,t.t0=t.catch(1),console.log("Error deleting class...",t.t0),e.saveError=!0,e.errorMessage="Error deleting class: ".concat(t.t0),t.abrupt("return");case 12:return t.next=14,e.$axios.$get("/data/readUser");case 14:return r=t.sent,t.t1=e.$store,t.next=18,e.$axios.$get("/data/updateUser?user=".concat(encodeURIComponent(JSON.stringify(h(h({},r),{},{memberships:r.memberships.filter((function(e){return e.class_id!=n}))})))));case 18:t.t2=t.sent,t.t1.commit.call(t.t1,"setUser",t.t2),e.$router.push({path:"/"});case 21:case"end":return t.stop()}}),t,null,[[1,6]])})))()},strToList:function(e){return e.replace(/ /g,"").split(",").flatMap((function(s){return s.trim().split("\n")})).filter((function(e){return/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(e)}))},importModule:function(){this.modules.push({url:this.moduleImportUrl,config:"",studentConfig:"",teacherConfig:"",stationConfig:"",showInCustom:"",width:"full",height:"tall"}),this.moduleImportUrl=""},save:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(n=e.newClass).modules=n.modules.map((function(e){return h(h({},e),{},{config:x.load(e.config),studentConfig:x.load(e.studentConfig),teacherConfig:x.load(e.teacherConfig),stationConfig:x.load(e.stationConfig),showInCustom:e.showInCustom})})),e.saveError=!1,e.saveSuccess=!1,e.saveLoading=!0,t.prev=5,t.t0=e.$store,t.next=9,e.$axios.$post("/data/updateClass/".concat(e.$store.state.class_.id),n);case 9:t.t1=t.sent,t.t0.commit.call(t.t0,"setClass",t.t1),e.saveLoading=!1,e.saveSuccess=!0,e.$emit("update:pendingEdits",!1),e.$emit("close"),t.next=23;break;case 17:t.prev=17,t.t2=t.catch(5),console.log("Saving failed:",t.t2),e.saveError=!0,e.saveLoading=!1,e.errorMessage="Saving failed with the following error message: ".concat(t.t2);case 23:e.$router.app.refresh();case 24:case"end":return t.stop()}}),t,null,[[5,17]])})))()},highlighter:function(code){return Object(d.highlight)(code,d.languages.yaml,"yaml")}},components:{PrismEditor:c.a,draggable:m.a}},C=k,S=(n(558),n(108)),U=n(143),L=n.n(U),I=n(612),M=n(613),V=n(224),$=n(209),O=n(98),R=n(610),j=n(564),E=n(614),T=n(615),F=n(616),P=n(617),A=n(624),N=n(489),D=n(205),J=n(531),H=n(510),z=n(532),B=n(538),G=n(495),Y=n(625),K=n(611),Q=n(618),W=n(492),X=n(493),Z=n(619),ee=n(626),te=n(623),ne=n(600),re=n(221),se=n(620),ae=n(57),oe=n(230),component=Object(S.a)(C,(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("v-card",[n("v-toolbar",{attrs:{dark:"",flat:""},scopedSlots:e._u([{key:"extension",fn:function(){return[n("v-tabs",{attrs:{"fixed-tabs":"","center-active":"","show-arrows":""},model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab",{attrs:{active:""}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-book-open-outline ")]),e._v("\n Settings\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-account-group ")]),e._v("\n Members\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-dashboard ")]),e._v("\n Modules\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-router-wireless ")]),e._v("\n Stations\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-share-variant ")]),e._v("\n Share\n ")],1)],1)]},proxy:!0}])},[n("v-toolbar-title",[e._v("Class Settings")]),e._v(" "),n("v-spacer"),e._v(" "),n("v-btn",{attrs:{icon:""},on:{click:function(t){return e.$emit("close")}}},[n("v-icon",[e._v("mdi-close")])],1)],1),e._v(" "),n("v-card-text",{staticStyle:{height:"565px"}},[n("v-tabs-items",{staticClass:"pt-5",model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab-item",[n("v-form",{ref:"form",on:{submit:function(t){return t.preventDefault(),e.save.apply(null,arguments)}}},[n("v-text-field",{attrs:{counter:20,label:"Class Name",outlined:"",required:""},model:{value:e.className,callback:function(t){e.className=t},expression:"className"}})],1)],1),e._v(" "),n("v-tab-item",[n("v-alert",{attrs:{outlined:"",dense:"",type:"info"}},[e._v("\n Enter emails below, one per line or separated by commas. Next,\n invite your users in by sharing this link:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"10px"}},[n("a",{attrs:{href:"//"+e.memberUrl}},[e._v(e._s(e.memberUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyMemberUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1)]),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of teacher emails"},model:{value:e.memberTeacher,callback:function(t){e.memberTeacher=t},expression:"memberTeacher"}}),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of student emails"},model:{value:e.memberStudent,callback:function(t){e.memberStudent=t},expression:"memberStudent"}})],1),e._v(" "),n("v-tab-item",[n("v-form",{on:{submit:function(t){return t.preventDefault(),e.importModule.apply(null,arguments)}}},[e.scrapedModules.length==e.modules.length?n("v-list",{attrs:{"two-line":""}},[n("draggable",{attrs:{handle:".handle"},model:{value:e.modules,callback:function(t){e.modules=t},expression:"modules"}},e._l(e.modules,(function(t,i){return n("v-list-item",{key:i,staticClass:"handle"},[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(e._s(e.scrapedModules[i].icon||"mdi-package")+"\n ")])],1),e._v(" "),n("v-list-item-content",[n("v-list-item-title",[e._v(e._s(e.scrapedModules[i].name)+"\n "),n("span",{staticStyle:{display:"inline-block",padding:"4px 8px","background-color":"#424242",color:"white","font-size":"12px","font-weight":"bold","border-radius":"16px"}},[e._v("\n "+e._s(e.scrapedModules[i].showInCustom)+"\n ")])]),e._v(" "),n("v-list-item-subtitle",{staticStyle:{"white-space":"break-spaces"},domProps:{innerHTML:e._s(e.scrapedModules[i].description)}})],1),e._v(" "),n("v-list-item-action",[n("v-menu",{attrs:{"close-on-content-click":!1,"nudge-width":200,"offset-x":"","offset-y":"",transition:"slide-y-transition",bottom:""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({attrs:{icon:""}},"v-btn",o,!1),r),[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-cog")])],1)]}}],null,!0)},[e._v(" "),n("v-expansion-panels",{staticStyle:{width:"100%"},attrs:{accordion:""}},[n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-link ")])]},proxy:!0}],null,!0)},[e._v("\n URL\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Module URL"},model:{value:t.url,callback:function(n){e.$set(t,"url",n)},expression:"m.url"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-script-text ")])]},proxy:!0}],null,!0)},[e._v("\n General settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.config,callback:function(n){e.$set(t,"config",n)},expression:"m.config"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-account-circle-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Student Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.studentConfig,callback:function(n){e.$set(t,"studentConfig",n)},expression:"m.studentConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-clipboard-account-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Teacher Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.teacherConfig,callback:function(n){e.$set(t,"teacherConfig",n)},expression:"m.teacherConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-router-wireless ")])]},proxy:!0}],null,!0)},[e._v("\n Station Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.stationConfig,callback:function(n){e.$set(t,"stationConfig",n)},expression:"m.stationConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-eye ")])]},proxy:!0}],null,!0)},[e._v("\n Show in\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Comma separated list of rooms, or: lobby, * for all, teacher-only, station"},model:{value:t.showInCustom,callback:function(n){e.$set(t,"showInCustom",n)},expression:"m.showInCustom"}})],1)],1)],1)],1)],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{icon:""},on:{click:function(){e.modules.splice(i,1)}}},[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-close")])],1)],1)],1)})),1)],1):n("div",[n("v-skeleton-loader",{staticClass:"mx-auto",attrs:{type:"list-item-avatar-two-line"}})],1),e._v(" "),n("v-list-item",[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(" mdi-link ")])],1),e._v(" "),n("v-list-item-content",[n("v-text-field",{attrs:{label:"Module URL",required:""},model:{value:e.moduleImportUrl,callback:function(t){e.moduleImportUrl=t},expression:"moduleImportUrl"}})],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{depressed:"",type:"submit",disabled:!e.validate_url(e.moduleImportUrl)}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-grid-plus ")]),e._v("\n Add\n ")],1)],1)],1)],1),e._v(" "),n("v-divider",{staticClass:"pb-2"}),e._v(" "),n("v-btn",{attrs:{href:"https://github.com/topics/edrys-module",target:"_blank"}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-github ")]),e._v("\n Explore on GitHub\n ")],1)],1),e._v(" "),n("v-tab-item",[e._v("\n To add a new station, simply open this link on the client device:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"15px"}},[n("a",{attrs:{href:"//"+e.stationUrl,target:"_blank"}},[e._v(e._s(e.stationUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyStationUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1),e._v(" "),n("br")]),e._v(" "),n("v-tab-item",[n("v-row",[n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("yaml")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.yml)\n ")],1)],1),e._v(" "),n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("json")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.json)\n ")],1)],1)],1),e._v(" "),n("v-row",[n("v-col",[n("v-file-input",{attrs:{dense:"",rules:e.restoreFileRules,accept:"application/yaml,application/json",label:"Restore class from file (yaml, json)","prepend-icon":"mdi-upload"},on:{change:e.restoreFile},model:{value:e.selectedFile,callback:function(t){e.selectedFile=t},expression:"selectedFile"}})],1),e._v(" "),n("v-col",[n("v-row",{attrs:{"no-gutters":""}},[n("v-col",{attrs:{cols:"4"}},[n("v-btn",{attrs:{"prepend-icon":"mdi-link"},on:{click:e.restoreURL}},[n("v-icon",[e._v("\n mdi-link\n ")]),e._v("\n Load\n ")],1)],1),e._v(" "),n("v-col",{attrs:{cols:"8"}},[n("v-text-field",{attrs:{dense:"",label:"class from URL"},on:{keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.restoreURL.apply(null,arguments)}},model:{value:e.selectedURL,callback:function(t){e.selectedURL=t},expression:"selectedURL"}})],1)],1)],1)],1),e._v(" "),n("v-divider",{staticClass:"pb-2"}),e._v(" "),n("v-btn",{attrs:{href:"https://github.com/topics/edrys-classroom",target:"_blank"}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-github ")]),e._v("\n Explore on GitHub\n ")],1)],1)],1),e._v(" "),e.errorMessage?n("v-alert",{attrs:{"close-text":"Close Alert",color:"red",type:"error",dark:"",outlined:"",dismissible:""},on:{input:function(){e.errorMessage=void 0}}},[n("div",{domProps:{innerHTML:e._s(e.errorMessage)}})]):e._e()],1),e._v(" "),n("v-snackbar",{attrs:{timeout:2e3,value:e.restoreSuccess,absolute:"",bottom:"",right:"",color:"success"}},[e._v("\n File restored - check everything is okay then save\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:600,value:e.saveSuccess,absolute:"",bottom:"",right:""}},[e._v("\n Class saved successfully\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:1400,value:e.saveError,color:"error",absolute:"",bottom:"",right:""}},[e._v("\n Sorry there was a problem saving, please try again\n ")]),e._v(" "),n("v-card-actions",[n("div",{staticClass:"pr-4 float-right"},[n("v-badge",{staticStyle:{"margin-top":"30px"},attrs:{overlap:"",dot:"",color:"red",value:e.pendingEdits}},[n("v-btn",{attrs:{color:"primary",loading:e.saveLoading,disabled:e.saveLoading},on:{click:e.save}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-upload ")]),e._v("\n Save\n ")],1)],1)],1),e._v(" "),n("v-menu",{attrs:{"offset-y":""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({staticClass:"float-right",staticStyle:{"margin-top":"30px","margin-right":"10px"},attrs:{color:"",depressed:""}},"v-btn",o,!1),r),[e._v("\n Delete Class")])]}}])},[e._v(" "),n("v-list",[n("v-list-item",[n("v-list-item-content",[e._v("Are you sure?\n\n "),n("v-btn",{staticClass:"float-right",staticStyle:{"margin-top":"10px"},attrs:{color:"red",depressed:""},on:{click:e.deleteClass}},[e._v("\n Yes, delete forever")])],1)],1)],1)],1)],1)],1)}),[],!1,null,null,null);t.default=component.exports;L()(component,{VAlert:I.a,VBadge:M.a,VBtn:V.a,VCard:$.a,VCardActions:O.a,VCardText:O.c,VCol:R.a,VDivider:j.a,VExpansionPanel:E.a,VExpansionPanelContent:T.a,VExpansionPanelHeader:F.a,VExpansionPanels:P.a,VFileInput:A.a,VForm:N.a,VIcon:D.a,VList:J.a,VListItem:H.a,VListItemAction:z.a,VListItemAvatar:B.a,VListItemContent:G.a,VListItemSubtitle:G.b,VListItemTitle:G.c,VMenu:Y.a,VRow:K.a,VSkeletonLoader:Q.a,VSnackbar:W.a,VSpacer:X.a,VTab:Z.a,VTabItem:ee.a,VTabs:te.a,VTabsItems:ne.a,VTextField:re.a,VTextarea:se.a,VToolbar:ae.a,VToolbarTitle:oe.a})},558:function(e,t,n){"use strict";n(529)},559:function(e,t,n){var r=n(19)(!1);r.push([e.i,".prism-editor{background:#2d2d2d;color:#ccc;font-family:Fira code,Fira Mono,Consolas,Menlo,Courier,monospace;font-size:14px;line-height:1.5;padding:5px;max-height:35 vh}",""]),e.exports=r}}]); \ No newline at end of file diff --git a/dist/static/_nuxt/a9673ed.js b/dist/static/_nuxt/a9673ed.js deleted file mode 100644 index 6bd84b8..0000000 --- a/dist/static/_nuxt/a9673ed.js +++ /dev/null @@ -1 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{529:function(e,t,n){var content=n(559);content.__esModule&&(content=content.default),"string"==typeof content&&(content=[[e.i,content,""]]),content.locals&&(e.exports=content.locals);(0,n(20).default)("a3a3f8c0",content,!0,{sourceMap:!1})},537:function(e,t,n){"use strict";n.r(t);n(59),n(65),n(12),n(72),n(85),n(13),n(15),n(11),n(16);var r=n(56),o=n(26),l=n(2),c=(n(99),n(61),n(86),n(4),n(46),n(58),n(301),n(179),n(41),n(42),n(27),n(71),n(14),n(546),n(547),n(62),n(84),n(548)),d=(n(549),n(551)),v=(n(552),n(553),n(554),n(555),n(556),n(528)),m=n.n(v);function f(object,e){var t=Object.keys(object);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(object);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(object,e).enumerable}))),t.push.apply(t,n)}return t}function h(e){for(var i=1;i=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,l=!0,c=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return l=e.done,e},e:function(e){c=!0,o=e},f:function(){try{l||null==n.return||n.return()}finally{if(c)throw o}}}}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var i=0,n=new Array(t);i0&&void 0!==arguments[0]?arguments[0]:void 0;try{var t,n,o,l;return e=e||this.$store.state.class_,this.className=e.name,this.memberTeacher=(null===(t=e.members)||void 0===t?void 0:t.teacher.join("\n"))||"",this.memberStudent=(null===(n=e.members)||void 0===n||null===(o=n.student)||void 0===o?void 0:o.join("\n"))||"",this.modules=Object(r.a)(null===(l=e)||void 0===l?void 0:l.modules.map((function(e){return h(h({},e),{},{config:x.dump(e.config),studentConfig:x.dump(e.studentConfig),teacherConfig:x.dump(e.teacherConfig),stationConfig:x.dump(e.stationConfig),showInCustom:e.showInCustom})})))||[],this.memberUrl=window.location.href.replace("#station","").replace("http://","").replace("https://",""),this.stationUrl=window.location.href.replace("#settings","").replace("#station","").replace("http://","").replace("https://","")+"#station",!0}catch(e){return this.errorMessage="The provided classroom configuration does not seem to be valid. I receive the following error message:\n

\n ".concat(e,"\n

\n Please check the content manually."),this.saveError=!0,!1}},copyStationUrl:function(){navigator.clipboard.writeText(this.stationUrl)},copyMemberUrl:function(){navigator.clipboard.writeText(this.memberUrl)},deleteClass:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n,r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=e.$store.state.class_.id,t.prev=1,t.next=4,e.$axios.$get("/data/deleteClass/".concat(n));case 4:t.next=12;break;case 6:return t.prev=6,t.t0=t.catch(1),console.log("Error deleting class...",t.t0),e.saveError=!0,e.errorMessage="Error deleting class: ".concat(t.t0),t.abrupt("return");case 12:return t.next=14,e.$axios.$get("/data/readUser");case 14:return r=t.sent,t.t1=e.$store,t.next=18,e.$axios.$get("/data/updateUser?user=".concat(encodeURIComponent(JSON.stringify(h(h({},r),{},{memberships:r.memberships.filter((function(e){return e.class_id!=n}))})))));case 18:t.t2=t.sent,t.t1.commit.call(t.t1,"setUser",t.t2),e.$router.push({path:"/"});case 21:case"end":return t.stop()}}),t,null,[[1,6]])})))()},strToList:function(e){return e.replace(/ /g,"").split(",").flatMap((function(s){return s.trim().split("\n")})).filter((function(e){return/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(e)}))},importModule:function(){this.modules.push({url:this.moduleImportUrl,config:"",studentConfig:"",teacherConfig:"",stationConfig:"",showInCustom:"",width:"full",height:"tall"}),this.moduleImportUrl=""},save:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(n=e.newClass).modules=n.modules.map((function(e){return h(h({},e),{},{config:x.load(e.config),studentConfig:x.load(e.studentConfig),teacherConfig:x.load(e.teacherConfig),stationConfig:x.load(e.stationConfig),showInCustom:e.showInCustom})})),e.saveError=!1,e.saveSuccess=!1,e.saveLoading=!0,t.prev=5,t.t0=e.$store,t.next=9,e.$axios.$get("/data/updateClass/".concat(e.$store.state.class_.id)+"?class=".concat(encodeURIComponent(JSON.stringify(n))));case 9:t.t1=t.sent,t.t0.commit.call(t.t0,"setClass",t.t1),e.saveLoading=!1,e.saveSuccess=!0,e.$emit("update:pendingEdits",!1),e.$emit("close"),t.next=23;break;case 17:t.prev=17,t.t2=t.catch(5),console.log("Saving failed:",t.t2),e.saveError=!0,e.saveLoading=!1,e.errorMessage="Saving failed with the following error message: ".concat(t.t2);case 23:e.$router.app.refresh();case 24:case"end":return t.stop()}}),t,null,[[5,17]])})))()},highlighter:function(code){return Object(d.highlight)(code,d.languages.yaml,"yaml")}},components:{PrismEditor:c.a,draggable:m.a}},C=k,S=(n(558),n(108)),U=n(143),L=n.n(U),I=n(612),V=n(613),$=n(224),M=n(209),O=n(98),R=n(610),j=n(564),E=n(614),T=n(615),F=n(616),P=n(617),A=n(624),N=n(489),D=n(205),J=n(531),H=n(510),B=n(532),G=n(538),z=n(495),Y=n(625),K=n(611),Q=n(618),W=n(492),X=n(493),Z=n(619),ee=n(626),te=n(623),ne=n(600),re=n(221),se=n(620),ae=n(57),oe=n(230),component=Object(S.a)(C,(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("v-card",[n("v-toolbar",{attrs:{dark:"",flat:""},scopedSlots:e._u([{key:"extension",fn:function(){return[n("v-tabs",{attrs:{"fixed-tabs":"","center-active":"","show-arrows":""},model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab",{attrs:{active:""}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-book-open-outline ")]),e._v("\n Settings\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-account-group ")]),e._v("\n Members\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-dashboard ")]),e._v("\n Modules\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-router-wireless ")]),e._v("\n Stations\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-share-variant ")]),e._v("\n Share\n ")],1)],1)]},proxy:!0}])},[n("v-toolbar-title",[e._v("Class Settings")]),e._v(" "),n("v-spacer"),e._v(" "),n("v-btn",{attrs:{icon:""},on:{click:function(t){return e.$emit("close")}}},[n("v-icon",[e._v("mdi-close")])],1)],1),e._v(" "),n("v-card-text",{staticStyle:{height:"565px"}},[n("v-tabs-items",{staticClass:"pt-5",model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab-item",[n("v-form",{ref:"form",on:{submit:function(t){return t.preventDefault(),e.save.apply(null,arguments)}}},[n("v-text-field",{attrs:{counter:20,label:"Class Name",outlined:"",required:""},model:{value:e.className,callback:function(t){e.className=t},expression:"className"}})],1)],1),e._v(" "),n("v-tab-item",[n("v-alert",{attrs:{outlined:"",dense:"",type:"info"}},[e._v("\n Enter emails below, one per line or separated by commas. Next,\n invite your users in by sharing this link:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"10px"}},[n("a",{attrs:{href:"//"+e.memberUrl}},[e._v(e._s(e.memberUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyMemberUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1)]),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of teacher emails"},model:{value:e.memberTeacher,callback:function(t){e.memberTeacher=t},expression:"memberTeacher"}}),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of student emails"},model:{value:e.memberStudent,callback:function(t){e.memberStudent=t},expression:"memberStudent"}})],1),e._v(" "),n("v-tab-item",[n("v-form",{on:{submit:function(t){return t.preventDefault(),e.importModule.apply(null,arguments)}}},[e.scrapedModules.length==e.modules.length?n("v-list",{attrs:{"two-line":""}},[n("draggable",{attrs:{handle:".handle"},model:{value:e.modules,callback:function(t){e.modules=t},expression:"modules"}},e._l(e.modules,(function(t,i){return n("v-list-item",{key:i,staticClass:"handle"},[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(e._s(e.scrapedModules[i].icon||"mdi-package")+"\n ")])],1),e._v(" "),n("v-list-item-content",[n("v-list-item-title",[e._v(e._s(e.scrapedModules[i].name))]),e._v(" "),n("v-list-item-subtitle",{staticStyle:{"white-space":"break-spaces"},domProps:{innerHTML:e._s(e.scrapedModules[i].description)}})],1),e._v(" "),n("v-list-item-action",[n("v-menu",{attrs:{"close-on-content-click":!1,"nudge-width":200,"offset-x":"","offset-y":"",transition:"slide-y-transition",bottom:""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({attrs:{icon:""}},"v-btn",o,!1),r),[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-cog")])],1)]}}],null,!0)},[e._v(" "),n("v-expansion-panels",{staticStyle:{width:"100%"},attrs:{accordion:""}},[n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-link ")])]},proxy:!0}],null,!0)},[e._v("\n URL\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Module URL"},model:{value:t.url,callback:function(n){e.$set(t,"url",n)},expression:"m.url"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-script-text ")])]},proxy:!0}],null,!0)},[e._v("\n General settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.config,callback:function(n){e.$set(t,"config",n)},expression:"m.config"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-account-circle-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Student Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.studentConfig,callback:function(n){e.$set(t,"studentConfig",n)},expression:"m.studentConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-clipboard-account-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Teacher Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.teacherConfig,callback:function(n){e.$set(t,"teacherConfig",n)},expression:"m.teacherConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-router-wireless ")])]},proxy:!0}],null,!0)},[e._v("\n Station Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.stationConfig,callback:function(n){e.$set(t,"stationConfig",n)},expression:"m.stationConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-eye ")])]},proxy:!0}],null,!0)},[e._v("\n Show in\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Comma separated list of rooms, or: lobby, * for all, teacher-only, station"},model:{value:t.showInCustom,callback:function(n){e.$set(t,"showInCustom",n)},expression:"m.showInCustom"}})],1)],1)],1)],1)],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{icon:""},on:{click:function(){e.modules.splice(i,1)}}},[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-close")])],1)],1)],1)})),1)],1):n("div",[n("v-skeleton-loader",{staticClass:"mx-auto",attrs:{type:"list-item-avatar-two-line"}})],1),e._v(" "),n("v-list-item",[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(" mdi-link ")])],1),e._v(" "),n("v-list-item-content",[n("v-text-field",{attrs:{label:"Module URL",required:""},model:{value:e.moduleImportUrl,callback:function(t){e.moduleImportUrl=t},expression:"moduleImportUrl"}})],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{depressed:"",type:"submit",disabled:!e.validate_url(e.moduleImportUrl)}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-grid-plus ")]),e._v("\n Add\n ")],1)],1)],1)],1),e._v(" "),n("v-divider",{staticClass:"pb-2"}),e._v(" "),n("v-btn",{attrs:{href:"https://github.com/topics/edrys-module",target:"_blank"}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-github ")]),e._v("\n Explore on GitHub\n ")],1)],1),e._v(" "),n("v-tab-item",[e._v("\n To add a new station, simply open this link on the client device:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"15px"}},[n("a",{attrs:{href:"//"+e.stationUrl,target:"_blank"}},[e._v(e._s(e.stationUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyStationUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1),e._v(" "),n("br")]),e._v(" "),n("v-tab-item",[n("v-row",[n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("yaml")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.yml)\n ")],1)],1),e._v(" "),n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("json")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.json)\n ")],1)],1)],1),e._v(" "),n("v-row",[n("v-col",[n("v-file-input",{attrs:{dense:"",rules:e.restoreFileRules,accept:"application/yaml,application/json",label:"Restore class from file (yaml, json)","prepend-icon":"mdi-upload"},on:{change:e.restoreFile},model:{value:e.selectedFile,callback:function(t){e.selectedFile=t},expression:"selectedFile"}})],1),e._v(" "),n("v-col",[n("v-row",{attrs:{"no-gutters":""}},[n("v-col",{attrs:{cols:"4"}},[n("v-btn",{attrs:{"prepend-icon":"mdi-link"},on:{click:e.restoreURL}},[n("v-icon",[e._v("\n mdi-link\n ")]),e._v("\n Load\n ")],1)],1),e._v(" "),n("v-col",{attrs:{cols:"8"}},[n("v-text-field",{attrs:{dense:"",label:"class from URL"},on:{keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.restoreURL.apply(null,arguments)}},model:{value:e.selectedURL,callback:function(t){e.selectedURL=t},expression:"selectedURL"}})],1)],1)],1)],1),e._v(" "),n("v-divider",{staticClass:"pb-2"}),e._v(" "),n("v-btn",{attrs:{href:"https://github.com/topics/edrys-classroom",target:"_blank"}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-github ")]),e._v("\n Explore on GitHub\n ")],1)],1)],1),e._v(" "),e.errorMessage?n("v-alert",{attrs:{"close-text":"Close Alert",color:"red",type:"error",dark:"",outlined:"",dismissible:""},on:{input:function(){e.errorMessage=void 0}}},[n("div",{domProps:{innerHTML:e._s(e.errorMessage)}})]):e._e()],1),e._v(" "),n("v-snackbar",{attrs:{timeout:2e3,value:e.restoreSuccess,absolute:"",bottom:"",right:"",color:"success"}},[e._v("\n File restored - check everything is okay then save\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:600,value:e.saveSuccess,absolute:"",bottom:"",right:""}},[e._v("\n Class saved successfully\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:1400,value:e.saveError,color:"error",absolute:"",bottom:"",right:""}},[e._v("\n Sorry there was a problem saving, please try again\n ")]),e._v(" "),n("v-card-actions",[n("div",{staticClass:"pr-4 float-right"},[n("v-badge",{staticStyle:{"margin-top":"30px"},attrs:{overlap:"",dot:"",color:"red",value:e.pendingEdits}},[n("v-btn",{attrs:{color:"primary",loading:e.saveLoading,disabled:e.saveLoading},on:{click:e.save}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-upload ")]),e._v("\n Save\n ")],1)],1)],1),e._v(" "),n("v-menu",{attrs:{"offset-y":""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({staticClass:"float-right",staticStyle:{"margin-top":"30px","margin-right":"10px"},attrs:{color:"",depressed:""}},"v-btn",o,!1),r),[e._v("\n Delete Class")])]}}])},[e._v(" "),n("v-list",[n("v-list-item",[n("v-list-item-content",[e._v("Are you sure?\n\n "),n("v-btn",{staticClass:"float-right",staticStyle:{"margin-top":"10px"},attrs:{color:"red",depressed:""},on:{click:e.deleteClass}},[e._v("\n Yes, delete forever")])],1)],1)],1)],1)],1)],1)}),[],!1,null,null,null);t.default=component.exports;L()(component,{VAlert:I.a,VBadge:V.a,VBtn:$.a,VCard:M.a,VCardActions:O.a,VCardText:O.c,VCol:R.a,VDivider:j.a,VExpansionPanel:E.a,VExpansionPanelContent:T.a,VExpansionPanelHeader:F.a,VExpansionPanels:P.a,VFileInput:A.a,VForm:N.a,VIcon:D.a,VList:J.a,VListItem:H.a,VListItemAction:B.a,VListItemAvatar:G.a,VListItemContent:z.a,VListItemSubtitle:z.b,VListItemTitle:z.c,VMenu:Y.a,VRow:K.a,VSkeletonLoader:Q.a,VSnackbar:W.a,VSpacer:X.a,VTab:Z.a,VTabItem:ee.a,VTabs:te.a,VTabsItems:ne.a,VTextField:re.a,VTextarea:se.a,VToolbar:ae.a,VToolbarTitle:oe.a})},558:function(e,t,n){"use strict";n(529)},559:function(e,t,n){var r=n(19)(!1);r.push([e.i,".prism-editor{background:#2d2d2d;color:#ccc;font-family:Fira code,Fira Mono,Consolas,Menlo,Courier,monospace;font-size:14px;line-height:1.5;padding:5px;max-height:35 vh}",""]),e.exports=r}}]); \ No newline at end of file diff --git a/dist/static/_nuxt/7d05504.js b/dist/static/_nuxt/c16fb80.js similarity index 97% rename from dist/static/_nuxt/7d05504.js rename to dist/static/_nuxt/c16fb80.js index a6368c2..c75b09a 100644 --- a/dist/static/_nuxt/7d05504.js +++ b/dist/static/_nuxt/c16fb80.js @@ -1 +1 @@ -!function(e){function r(data){for(var r,n,f=data[0],l=data[1],d=data[2],i=0,h=[];i - Home - Edrys + Home - Edrys
Loading...
- + From f565b73f14b8e89747ed0afeed633cec2e0e0da5 Mon Sep 17 00:00:00 2001 From: Karl Fessel Date: Thu, 11 May 2023 14:45:10 +0200 Subject: [PATCH 08/11] update client --- dist/static/200.html | 4 +-- dist/static/_nuxt/{ed8a7c2.js => 328d516.js} | 0 dist/static/_nuxt/{579ea4e.js => 51511d9.js} | 2 +- dist/static/_nuxt/{c16fb80.js => 51601b1.js} | 2 +- dist/static/_nuxt/{33034d1.js => 710d71d.js} | 0 dist/static/_nuxt/{6c212d8.js => 8586d10.js} | 0 dist/static/_nuxt/LICENSES | 30 ++++++++++---------- dist/static/_nuxt/{d830c61.js => d463427.js} | 0 dist/static/_nuxt/{345976e.js => def4792.js} | 0 dist/static/index.html | 4 +-- 10 files changed, 21 insertions(+), 21 deletions(-) rename dist/static/_nuxt/{ed8a7c2.js => 328d516.js} (100%) rename dist/static/_nuxt/{579ea4e.js => 51511d9.js} (83%) rename dist/static/_nuxt/{c16fb80.js => 51601b1.js} (94%) rename dist/static/_nuxt/{33034d1.js => 710d71d.js} (100%) rename dist/static/_nuxt/{6c212d8.js => 8586d10.js} (100%) rename dist/static/_nuxt/{d830c61.js => d463427.js} (100%) rename dist/static/_nuxt/{345976e.js => def4792.js} (100%) diff --git a/dist/static/200.html b/dist/static/200.html index e802366..d153dcf 100644 --- a/dist/static/200.html +++ b/dist/static/200.html @@ -1,9 +1,9 @@ - Home - Edrys + Home - Edrys
Loading...
- + diff --git a/dist/static/_nuxt/ed8a7c2.js b/dist/static/_nuxt/328d516.js similarity index 100% rename from dist/static/_nuxt/ed8a7c2.js rename to dist/static/_nuxt/328d516.js diff --git a/dist/static/_nuxt/579ea4e.js b/dist/static/_nuxt/51511d9.js similarity index 83% rename from dist/static/_nuxt/579ea4e.js rename to dist/static/_nuxt/51511d9.js index 55c4b1a..271f3f8 100644 --- a/dist/static/_nuxt/579ea4e.js +++ b/dist/static/_nuxt/51511d9.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{529:function(e,t,n){var content=n(559);content.__esModule&&(content=content.default),"string"==typeof content&&(content=[[e.i,content,""]]),content.locals&&(e.exports=content.locals);(0,n(20).default)("a3a3f8c0",content,!0,{sourceMap:!1})},537:function(e,t,n){"use strict";n.r(t);n(59),n(65),n(12),n(72),n(85),n(13),n(15),n(11),n(16);var r=n(56),o=n(26),l=n(2),c=(n(99),n(61),n(86),n(4),n(46),n(58),n(301),n(179),n(41),n(42),n(27),n(71),n(14),n(546),n(547),n(62),n(84),n(548)),d=(n(549),n(551)),v=(n(552),n(553),n(554),n(555),n(556),n(528)),m=n.n(v);function f(object,e){var t=Object.keys(object);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(object);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(object,e).enumerable}))),t.push.apply(t,n)}return t}function h(e){for(var i=1;i=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,l=!0,c=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return l=e.done,e},e:function(e){c=!0,o=e},f:function(){try{l||null==n.return||n.return()}finally{if(c)throw o}}}}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var i=0,n=new Array(t);i0&&void 0!==arguments[0]?arguments[0]:void 0;try{var t,n,o,l;return e=e||this.$store.state.class_,this.className=e.name,this.memberTeacher=(null===(t=e.members)||void 0===t?void 0:t.teacher.join("\n"))||"",this.memberStudent=(null===(n=e.members)||void 0===n||null===(o=n.student)||void 0===o?void 0:o.join("\n"))||"",this.modules=Object(r.a)(null===(l=e)||void 0===l?void 0:l.modules.map((function(e){return h(h({},e),{},{config:x.dump(e.config),studentConfig:x.dump(e.studentConfig),teacherConfig:x.dump(e.teacherConfig),stationConfig:x.dump(e.stationConfig),showInCustom:e.showInCustom})})))||[],this.memberUrl=window.location.href.replace("#station","").replace("http://","").replace("https://",""),this.stationUrl=window.location.href.replace("#settings","").replace("#station","").replace("http://","").replace("https://","")+"#station",!0}catch(e){return this.errorMessage="The provided classroom configuration does not seem to be valid. I receive the following error message:\n

\n ".concat(e,"\n

\n Please check the content manually."),this.saveError=!0,!1}},copyStationUrl:function(){navigator.clipboard.writeText(this.stationUrl)},copyMemberUrl:function(){navigator.clipboard.writeText(this.memberUrl)},deleteClass:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n,r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=e.$store.state.class_.id,t.prev=1,t.next=4,e.$axios.$get("/data/deleteClass/".concat(n));case 4:t.next=12;break;case 6:return t.prev=6,t.t0=t.catch(1),console.log("Error deleting class...",t.t0),e.saveError=!0,e.errorMessage="Error deleting class: ".concat(t.t0),t.abrupt("return");case 12:return t.next=14,e.$axios.$get("/data/readUser");case 14:return r=t.sent,t.t1=e.$store,t.next=18,e.$axios.$get("/data/updateUser?user=".concat(encodeURIComponent(JSON.stringify(h(h({},r),{},{memberships:r.memberships.filter((function(e){return e.class_id!=n}))})))));case 18:t.t2=t.sent,t.t1.commit.call(t.t1,"setUser",t.t2),e.$router.push({path:"/"});case 21:case"end":return t.stop()}}),t,null,[[1,6]])})))()},strToList:function(e){return e.replace(/ /g,"").split(",").flatMap((function(s){return s.trim().split("\n")})).filter((function(e){return/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(e)}))},importModule:function(){this.modules.push({url:this.moduleImportUrl,config:"",studentConfig:"",teacherConfig:"",stationConfig:"",showInCustom:"",width:"full",height:"tall"}),this.moduleImportUrl=""},save:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(n=e.newClass).modules=n.modules.map((function(e){return h(h({},e),{},{config:x.load(e.config),studentConfig:x.load(e.studentConfig),teacherConfig:x.load(e.teacherConfig),stationConfig:x.load(e.stationConfig),showInCustom:e.showInCustom})})),e.saveError=!1,e.saveSuccess=!1,e.saveLoading=!0,t.prev=5,t.t0=e.$store,t.next=9,e.$axios.$post("/data/updateClass/".concat(e.$store.state.class_.id),n);case 9:t.t1=t.sent,t.t0.commit.call(t.t0,"setClass",t.t1),e.saveLoading=!1,e.saveSuccess=!0,e.$emit("update:pendingEdits",!1),e.$emit("close"),t.next=23;break;case 17:t.prev=17,t.t2=t.catch(5),console.log("Saving failed:",t.t2),e.saveError=!0,e.saveLoading=!1,e.errorMessage="Saving failed with the following error message: ".concat(t.t2);case 23:e.$router.app.refresh();case 24:case"end":return t.stop()}}),t,null,[[5,17]])})))()},highlighter:function(code){return Object(d.highlight)(code,d.languages.yaml,"yaml")}},components:{PrismEditor:c.a,draggable:m.a}},C=k,S=(n(558),n(108)),U=n(143),L=n.n(U),I=n(612),M=n(613),V=n(224),$=n(209),O=n(98),R=n(610),j=n(564),E=n(614),T=n(615),F=n(616),P=n(617),A=n(624),N=n(489),D=n(205),J=n(531),H=n(510),z=n(532),B=n(538),G=n(495),Y=n(625),K=n(611),Q=n(618),W=n(492),X=n(493),Z=n(619),ee=n(626),te=n(623),ne=n(600),re=n(221),se=n(620),ae=n(57),oe=n(230),component=Object(S.a)(C,(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("v-card",[n("v-toolbar",{attrs:{dark:"",flat:""},scopedSlots:e._u([{key:"extension",fn:function(){return[n("v-tabs",{attrs:{"fixed-tabs":"","center-active":"","show-arrows":""},model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab",{attrs:{active:""}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-book-open-outline ")]),e._v("\n Settings\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-account-group ")]),e._v("\n Members\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-dashboard ")]),e._v("\n Modules\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-router-wireless ")]),e._v("\n Stations\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-share-variant ")]),e._v("\n Share\n ")],1)],1)]},proxy:!0}])},[n("v-toolbar-title",[e._v("Class Settings")]),e._v(" "),n("v-spacer"),e._v(" "),n("v-btn",{attrs:{icon:""},on:{click:function(t){return e.$emit("close")}}},[n("v-icon",[e._v("mdi-close")])],1)],1),e._v(" "),n("v-card-text",{staticStyle:{height:"565px"}},[n("v-tabs-items",{staticClass:"pt-5",model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab-item",[n("v-form",{ref:"form",on:{submit:function(t){return t.preventDefault(),e.save.apply(null,arguments)}}},[n("v-text-field",{attrs:{counter:20,label:"Class Name",outlined:"",required:""},model:{value:e.className,callback:function(t){e.className=t},expression:"className"}})],1)],1),e._v(" "),n("v-tab-item",[n("v-alert",{attrs:{outlined:"",dense:"",type:"info"}},[e._v("\n Enter emails below, one per line or separated by commas. Next,\n invite your users in by sharing this link:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"10px"}},[n("a",{attrs:{href:"//"+e.memberUrl}},[e._v(e._s(e.memberUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyMemberUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1)]),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of teacher emails"},model:{value:e.memberTeacher,callback:function(t){e.memberTeacher=t},expression:"memberTeacher"}}),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of student emails"},model:{value:e.memberStudent,callback:function(t){e.memberStudent=t},expression:"memberStudent"}})],1),e._v(" "),n("v-tab-item",[n("v-form",{on:{submit:function(t){return t.preventDefault(),e.importModule.apply(null,arguments)}}},[e.scrapedModules.length==e.modules.length?n("v-list",{attrs:{"two-line":""}},[n("draggable",{attrs:{handle:".handle"},model:{value:e.modules,callback:function(t){e.modules=t},expression:"modules"}},e._l(e.modules,(function(t,i){return n("v-list-item",{key:i,staticClass:"handle"},[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(e._s(e.scrapedModules[i].icon||"mdi-package")+"\n ")])],1),e._v(" "),n("v-list-item-content",[n("v-list-item-title",[e._v(e._s(e.scrapedModules[i].name)+"\n "),n("span",{staticStyle:{display:"inline-block",padding:"4px 8px","background-color":"#424242",color:"white","font-size":"12px","font-weight":"bold","border-radius":"16px"}},[e._v("\n "+e._s(e.scrapedModules[i].showInCustom)+"\n ")])]),e._v(" "),n("v-list-item-subtitle",{staticStyle:{"white-space":"break-spaces"},domProps:{innerHTML:e._s(e.scrapedModules[i].description)}})],1),e._v(" "),n("v-list-item-action",[n("v-menu",{attrs:{"close-on-content-click":!1,"nudge-width":200,"offset-x":"","offset-y":"",transition:"slide-y-transition",bottom:""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({attrs:{icon:""}},"v-btn",o,!1),r),[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-cog")])],1)]}}],null,!0)},[e._v(" "),n("v-expansion-panels",{staticStyle:{width:"100%"},attrs:{accordion:""}},[n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-link ")])]},proxy:!0}],null,!0)},[e._v("\n URL\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Module URL"},model:{value:t.url,callback:function(n){e.$set(t,"url",n)},expression:"m.url"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-script-text ")])]},proxy:!0}],null,!0)},[e._v("\n General settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.config,callback:function(n){e.$set(t,"config",n)},expression:"m.config"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-account-circle-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Student Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.studentConfig,callback:function(n){e.$set(t,"studentConfig",n)},expression:"m.studentConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-clipboard-account-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Teacher Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.teacherConfig,callback:function(n){e.$set(t,"teacherConfig",n)},expression:"m.teacherConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-router-wireless ")])]},proxy:!0}],null,!0)},[e._v("\n Station Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.stationConfig,callback:function(n){e.$set(t,"stationConfig",n)},expression:"m.stationConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-eye ")])]},proxy:!0}],null,!0)},[e._v("\n Show in\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Comma separated list of rooms, or: lobby, * for all, teacher-only, station"},model:{value:t.showInCustom,callback:function(n){e.$set(t,"showInCustom",n)},expression:"m.showInCustom"}})],1)],1)],1)],1)],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{icon:""},on:{click:function(){e.modules.splice(i,1)}}},[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-close")])],1)],1)],1)})),1)],1):n("div",[n("v-skeleton-loader",{staticClass:"mx-auto",attrs:{type:"list-item-avatar-two-line"}})],1),e._v(" "),n("v-list-item",[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(" mdi-link ")])],1),e._v(" "),n("v-list-item-content",[n("v-text-field",{attrs:{label:"Module URL",required:""},model:{value:e.moduleImportUrl,callback:function(t){e.moduleImportUrl=t},expression:"moduleImportUrl"}})],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{depressed:"",type:"submit",disabled:!e.validate_url(e.moduleImportUrl)}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-grid-plus ")]),e._v("\n Add\n ")],1)],1)],1)],1),e._v(" "),n("v-divider",{staticClass:"pb-2"}),e._v(" "),n("v-btn",{attrs:{href:"https://github.com/topics/edrys-module",target:"_blank"}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-github ")]),e._v("\n Explore on GitHub\n ")],1)],1),e._v(" "),n("v-tab-item",[e._v("\n To add a new station, simply open this link on the client device:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"15px"}},[n("a",{attrs:{href:"//"+e.stationUrl,target:"_blank"}},[e._v(e._s(e.stationUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyStationUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1),e._v(" "),n("br")]),e._v(" "),n("v-tab-item",[n("v-row",[n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("yaml")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.yml)\n ")],1)],1),e._v(" "),n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("json")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.json)\n ")],1)],1)],1),e._v(" "),n("v-row",[n("v-col",[n("v-file-input",{attrs:{dense:"",rules:e.restoreFileRules,accept:"application/yaml,application/json",label:"Restore class from file (yaml, json)","prepend-icon":"mdi-upload"},on:{change:e.restoreFile},model:{value:e.selectedFile,callback:function(t){e.selectedFile=t},expression:"selectedFile"}})],1),e._v(" "),n("v-col",[n("v-row",{attrs:{"no-gutters":""}},[n("v-col",{attrs:{cols:"4"}},[n("v-btn",{attrs:{"prepend-icon":"mdi-link"},on:{click:e.restoreURL}},[n("v-icon",[e._v("\n mdi-link\n ")]),e._v("\n Load\n ")],1)],1),e._v(" "),n("v-col",{attrs:{cols:"8"}},[n("v-text-field",{attrs:{dense:"",label:"class from URL"},on:{keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.restoreURL.apply(null,arguments)}},model:{value:e.selectedURL,callback:function(t){e.selectedURL=t},expression:"selectedURL"}})],1)],1)],1)],1),e._v(" "),n("v-divider",{staticClass:"pb-2"}),e._v(" "),n("v-btn",{attrs:{href:"https://github.com/topics/edrys-classroom",target:"_blank"}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-github ")]),e._v("\n Explore on GitHub\n ")],1)],1)],1),e._v(" "),e.errorMessage?n("v-alert",{attrs:{"close-text":"Close Alert",color:"red",type:"error",dark:"",outlined:"",dismissible:""},on:{input:function(){e.errorMessage=void 0}}},[n("div",{domProps:{innerHTML:e._s(e.errorMessage)}})]):e._e()],1),e._v(" "),n("v-snackbar",{attrs:{timeout:2e3,value:e.restoreSuccess,absolute:"",bottom:"",right:"",color:"success"}},[e._v("\n File restored - check everything is okay then save\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:600,value:e.saveSuccess,absolute:"",bottom:"",right:""}},[e._v("\n Class saved successfully\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:1400,value:e.saveError,color:"error",absolute:"",bottom:"",right:""}},[e._v("\n Sorry there was a problem saving, please try again\n ")]),e._v(" "),n("v-card-actions",[n("div",{staticClass:"pr-4 float-right"},[n("v-badge",{staticStyle:{"margin-top":"30px"},attrs:{overlap:"",dot:"",color:"red",value:e.pendingEdits}},[n("v-btn",{attrs:{color:"primary",loading:e.saveLoading,disabled:e.saveLoading},on:{click:e.save}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-upload ")]),e._v("\n Save\n ")],1)],1)],1),e._v(" "),n("v-menu",{attrs:{"offset-y":""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({staticClass:"float-right",staticStyle:{"margin-top":"30px","margin-right":"10px"},attrs:{color:"",depressed:""}},"v-btn",o,!1),r),[e._v("\n Delete Class")])]}}])},[e._v(" "),n("v-list",[n("v-list-item",[n("v-list-item-content",[e._v("Are you sure?\n\n "),n("v-btn",{staticClass:"float-right",staticStyle:{"margin-top":"10px"},attrs:{color:"red",depressed:""},on:{click:e.deleteClass}},[e._v("\n Yes, delete forever")])],1)],1)],1)],1)],1)],1)}),[],!1,null,null,null);t.default=component.exports;L()(component,{VAlert:I.a,VBadge:M.a,VBtn:V.a,VCard:$.a,VCardActions:O.a,VCardText:O.c,VCol:R.a,VDivider:j.a,VExpansionPanel:E.a,VExpansionPanelContent:T.a,VExpansionPanelHeader:F.a,VExpansionPanels:P.a,VFileInput:A.a,VForm:N.a,VIcon:D.a,VList:J.a,VListItem:H.a,VListItemAction:z.a,VListItemAvatar:B.a,VListItemContent:G.a,VListItemSubtitle:G.b,VListItemTitle:G.c,VMenu:Y.a,VRow:K.a,VSkeletonLoader:Q.a,VSnackbar:W.a,VSpacer:X.a,VTab:Z.a,VTabItem:ee.a,VTabs:te.a,VTabsItems:ne.a,VTextField:re.a,VTextarea:se.a,VToolbar:ae.a,VToolbarTitle:oe.a})},558:function(e,t,n){"use strict";n(529)},559:function(e,t,n){var r=n(19)(!1);r.push([e.i,".prism-editor{background:#2d2d2d;color:#ccc;font-family:Fira code,Fira Mono,Consolas,Menlo,Courier,monospace;font-size:14px;line-height:1.5;padding:5px;max-height:35 vh}",""]),e.exports=r}}]); \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[1],{529:function(e,t,n){var content=n(559);content.__esModule&&(content=content.default),"string"==typeof content&&(content=[[e.i,content,""]]),content.locals&&(e.exports=content.locals);(0,n(20).default)("a3a3f8c0",content,!0,{sourceMap:!1})},537:function(e,t,n){"use strict";n.r(t);n(59),n(65),n(12),n(72),n(85),n(13),n(15),n(11),n(16);var r=n(56),o=n(26),l=n(2),c=(n(99),n(61),n(86),n(4),n(46),n(58),n(301),n(179),n(41),n(42),n(27),n(71),n(14),n(546),n(547),n(62),n(84),n(548)),d=(n(549),n(551)),v=(n(552),n(553),n(554),n(555),n(556),n(528)),m=n.n(v);function f(object,e){var t=Object.keys(object);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(object);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(object,e).enumerable}))),t.push.apply(t,n)}return t}function h(e){for(var i=1;i=e.length?{done:!0}:{done:!1,value:e[i++]}},e:function(e){throw e},f:r}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,l=!0,c=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return l=e.done,e},e:function(e){c=!0,o=e},f:function(){try{l||null==n.return||n.return()}finally{if(c)throw o}}}}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var i=0,n=new Array(t);i0&&void 0!==arguments[0]?arguments[0]:void 0;try{var t,n,o,l;return e=e||this.$store.state.class_,this.className=e.name,this.memberTeacher=(null===(t=e.members)||void 0===t?void 0:t.teacher.join("\n"))||"",this.memberStudent=(null===(n=e.members)||void 0===n||null===(o=n.student)||void 0===o?void 0:o.join("\n"))||"",this.modules=Object(r.a)(null===(l=e)||void 0===l?void 0:l.modules.map((function(e){return h(h({},e),{},{config:x.dump(e.config),studentConfig:x.dump(e.studentConfig),teacherConfig:x.dump(e.teacherConfig),stationConfig:x.dump(e.stationConfig),showInCustom:e.showInCustom})})))||[],this.memberUrl=window.location.href.replace("#station","").replace("http://","").replace("https://",""),this.stationUrl=window.location.href.replace("#settings","").replace("#station","").replace("http://","").replace("https://","")+"#station",!0}catch(e){return this.errorMessage="The provided classroom configuration does not seem to be valid. I receive the following error message:\n

\n ".concat(e,"\n

\n Please check the content manually."),this.saveError=!0,!1}},copyStationUrl:function(){navigator.clipboard.writeText(this.stationUrl)},copyMemberUrl:function(){navigator.clipboard.writeText(this.memberUrl)},deleteClass:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n,r;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return n=e.$store.state.class_.id,t.prev=1,t.next=4,e.$axios.$get("/data/deleteClass/".concat(n));case 4:t.next=12;break;case 6:return t.prev=6,t.t0=t.catch(1),console.log("Error deleting class...",t.t0),e.saveError=!0,e.errorMessage="Error deleting class: ".concat(t.t0),t.abrupt("return");case 12:return t.next=14,e.$axios.$get("/data/readUser");case 14:return r=t.sent,t.t1=e.$store,t.next=18,e.$axios.$get("/data/updateUser?user=".concat(encodeURIComponent(JSON.stringify(h(h({},r),{},{memberships:r.memberships.filter((function(e){return e.class_id!=n}))})))));case 18:t.t2=t.sent,t.t1.commit.call(t.t1,"setUser",t.t2),e.$router.push({path:"/"});case 21:case"end":return t.stop()}}),t,null,[[1,6]])})))()},strToList:function(e){return e.replace(/ /g,"").split(",").flatMap((function(s){return s.trim().split("\n")})).filter((function(e){return/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(e)}))},importModule:function(){this.modules.push({url:this.moduleImportUrl,config:"",studentConfig:"",teacherConfig:"",stationConfig:"",showInCustom:"",width:"full",height:"tall"}),this.moduleImportUrl=""},save:function(){var e=this;return Object(o.a)(regeneratorRuntime.mark((function t(){var n;return regeneratorRuntime.wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return(n=e.newClass).modules=n.modules.map((function(e){return h(h({},e),{},{config:x.load(e.config),studentConfig:x.load(e.studentConfig),teacherConfig:x.load(e.teacherConfig),stationConfig:x.load(e.stationConfig),showInCustom:e.showInCustom})})),e.saveError=!1,e.saveSuccess=!1,e.saveLoading=!0,t.prev=5,t.t0=e.$store,t.next=9,e.$axios.$post("/data/updateClass/".concat(e.$store.state.class_.id),n);case 9:t.t1=t.sent,t.t0.commit.call(t.t0,"setClass",t.t1),e.saveLoading=!1,e.saveSuccess=!0,e.$emit("update:pendingEdits",!1),e.$emit("close"),t.next=23;break;case 17:t.prev=17,t.t2=t.catch(5),console.log("Saving failed:",t.t2),e.saveError=!0,e.saveLoading=!1,e.errorMessage="Saving failed with the following error message: ".concat(t.t2);case 23:e.$router.app.refresh();case 24:case"end":return t.stop()}}),t,null,[[5,17]])})))()},highlighter:function(code){return Object(d.highlight)(code,d.languages.yaml,"yaml")}},components:{PrismEditor:c.a,draggable:m.a}},C=k,S=(n(558),n(108)),U=n(143),L=n.n(U),I=n(612),M=n(613),V=n(224),$=n(209),O=n(98),R=n(610),j=n(564),E=n(614),T=n(615),F=n(616),P=n(617),A=n(624),N=n(489),D=n(205),J=n(531),H=n(510),z=n(532),B=n(538),G=n(495),Y=n(625),K=n(611),Q=n(618),W=n(492),X=n(493),Z=n(619),ee=n(626),te=n(623),ne=n(600),re=n(221),se=n(620),ae=n(57),oe=n(230),component=Object(S.a)(C,(function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("v-card",[n("v-toolbar",{attrs:{dark:"",flat:""},scopedSlots:e._u([{key:"extension",fn:function(){return[n("v-tabs",{attrs:{"fixed-tabs":"","center-active":"","show-arrows":""},model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab",{attrs:{active:""}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-book-open-outline ")]),e._v("\n Settings\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-account-group ")]),e._v("\n Members\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-dashboard ")]),e._v("\n Modules\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-router-wireless ")]),e._v("\n Stations\n ")],1),e._v(" "),n("v-tab",[n("v-icon",{attrs:{left:""}},[e._v(" mdi-share-variant ")]),e._v("\n Share\n ")],1)],1)]},proxy:!0}])},[n("v-toolbar-title",[e._v("Class Settings")]),e._v(" "),n("v-spacer"),e._v(" "),n("v-btn",{attrs:{icon:""},on:{click:function(t){return e.$emit("close")}}},[n("v-icon",[e._v("mdi-close")])],1)],1),e._v(" "),n("v-card-text",{staticStyle:{height:"565px"}},[n("v-tabs-items",{staticClass:"pt-5",model:{value:e.tab,callback:function(t){e.tab=t},expression:"tab"}},[n("v-tab-item",[n("v-form",{ref:"form",on:{submit:function(t){return t.preventDefault(),e.save.apply(null,arguments)}}},[n("v-text-field",{attrs:{counter:20,label:"Class Name",outlined:"",required:""},model:{value:e.className,callback:function(t){e.className=t},expression:"className"}})],1)],1),e._v(" "),n("v-tab-item",[n("v-alert",{attrs:{outlined:"",dense:"",type:"info"}},[e._v("\n Enter emails below, one per line or separated by commas. Next,\n invite your users in by sharing this link:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"10px"}},[n("a",{attrs:{href:"//"+e.memberUrl}},[e._v(e._s(e.memberUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyMemberUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1)]),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of teacher emails"},model:{value:e.memberTeacher,callback:function(t){e.memberTeacher=t},expression:"memberTeacher"}}),e._v(" "),n("v-textarea",{attrs:{outlined:"",label:"List of student emails"},model:{value:e.memberStudent,callback:function(t){e.memberStudent=t},expression:"memberStudent"}})],1),e._v(" "),n("v-tab-item",[n("v-form",{on:{submit:function(t){return t.preventDefault(),e.importModule.apply(null,arguments)}}},[e.scrapedModules.length==e.modules.length?n("v-list",{attrs:{"two-line":""}},[n("draggable",{attrs:{handle:".handle"},model:{value:e.modules,callback:function(t){e.modules=t},expression:"modules"}},e._l(e.modules,(function(t,i){return n("v-list-item",{key:i,staticClass:"handle"},[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(e._s(e.scrapedModules[i].icon||"mdi-package")+"\n ")])],1),e._v(" "),n("v-list-item-content",[n("v-list-item-title",[e._v(e._s(e.scrapedModules[i].name)+"\n "),n("span",{staticStyle:{display:"inline-block",padding:"4px 8px","background-color":"#424242",color:"white","font-size":"12px","font-weight":"bold","border-radius":"16px"}},[e._v("\n "+e._s(e.scrapedModules[i].showInCustom)+"\n ")])]),e._v(" "),n("v-list-item-subtitle",{staticStyle:{"white-space":"break-spaces"},domProps:{innerHTML:e._s(e.scrapedModules[i].description)}})],1),e._v(" "),n("v-list-item-action",[n("v-menu",{attrs:{"close-on-content-click":!1,"nudge-width":200,"offset-x":"","offset-y":"",transition:"slide-y-transition",bottom:""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({attrs:{icon:""}},"v-btn",o,!1),r),[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-cog")])],1)]}}],null,!0)},[e._v(" "),n("v-expansion-panels",{staticStyle:{width:"100%"},attrs:{accordion:""}},[n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-link ")])]},proxy:!0}],null,!0)},[e._v("\n URL\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Module URL"},model:{value:t.url,callback:function(n){e.$set(t,"url",n)},expression:"m.url"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-script-text ")])]},proxy:!0}],null,!0)},[e._v("\n General settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.config,callback:function(n){e.$set(t,"config",n)},expression:"m.config"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-account-circle-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Student Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.studentConfig,callback:function(n){e.$set(t,"studentConfig",n)},expression:"m.studentConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-clipboard-account-outline ")])]},proxy:!0}],null,!0)},[e._v("\n Teacher Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.teacherConfig,callback:function(n){e.$set(t,"teacherConfig",n)},expression:"m.teacherConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-router-wireless ")])]},proxy:!0}],null,!0)},[e._v("\n Station Settings\n ")]),e._v(" "),n("v-expansion-panel-content",[n("prism-editor",{staticStyle:{"max-height":"60vh"},attrs:{highlight:e.highlighter,"line-numbers":""},model:{value:t.stationConfig,callback:function(n){e.$set(t,"stationConfig",n)},expression:"m.stationConfig"}})],1)],1),e._v(" "),n("v-expansion-panel",[n("v-expansion-panel-header",{attrs:{"disable-icon-rotate":""},scopedSlots:e._u([{key:"actions",fn:function(){return[n("v-icon",[e._v(" mdi-eye ")])]},proxy:!0}],null,!0)},[e._v("\n Show in\n ")]),e._v(" "),n("v-expansion-panel-content",[n("v-text-field",{attrs:{filled:"",label:"Comma separated list of rooms, or: lobby, * for all, teacher-only, station"},model:{value:t.showInCustom,callback:function(n){e.$set(t,"showInCustom",n)},expression:"m.showInCustom"}})],1)],1)],1)],1)],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{icon:""},on:{click:function(){e.modules.splice(i,1)}}},[n("v-icon",{attrs:{color:"grey darken-1"}},[e._v("mdi-close")])],1)],1)],1)})),1)],1):n("div",[n("v-skeleton-loader",{staticClass:"mx-auto",attrs:{type:"list-item-avatar-two-line"}})],1),e._v(" "),n("v-list-item",[n("v-list-item-avatar",[n("v-icon",{staticClass:"grey darken-3",attrs:{dark:""}},[e._v(" mdi-link ")])],1),e._v(" "),n("v-list-item-content",[n("v-text-field",{attrs:{label:"Module URL",required:""},model:{value:e.moduleImportUrl,callback:function(t){e.moduleImportUrl=t},expression:"moduleImportUrl"}})],1),e._v(" "),n("v-list-item-action",[n("v-btn",{attrs:{depressed:"",type:"submit",disabled:!e.validate_url(e.moduleImportUrl)}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-view-grid-plus ")]),e._v("\n Add\n ")],1)],1)],1)],1),e._v(" "),n("v-divider",{staticClass:"pb-2"}),e._v(" "),n("v-btn",{attrs:{href:"https://github.com/topics/edrys-module",target:"_blank"}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-github ")]),e._v("\n Explore on GitHub\n ")],1)],1),e._v(" "),n("v-tab-item",[e._v("\n To add a new station, simply open this link on the client device:\n "),n("br"),e._v(" "),n("br"),e._v(" "),n("blockquote",{staticStyle:{"margin-left":"15px"}},[n("a",{attrs:{href:"//"+e.stationUrl,target:"_blank"}},[e._v(e._s(e.stationUrl))]),e._v(" "),n("v-btn",{attrs:{icon:"",small:""},on:{click:e.copyStationUrl}},[n("v-icon",{attrs:{small:""}},[e._v("mdi-content-copy")])],1)],1),e._v(" "),n("br")]),e._v(" "),n("v-tab-item",[n("v-row",[n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("yaml")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.yml)\n ")],1)],1),e._v(" "),n("v-col",[n("v-btn",{attrs:{depressed:"",block:""},on:{click:function(t){return e.downloadClass("json")}}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-download ")]),e._v("\n Download class file (.json)\n ")],1)],1)],1),e._v(" "),n("v-row",[n("v-col",[n("v-file-input",{attrs:{dense:"",rules:e.restoreFileRules,accept:".yml,.yaml,.json,application/yaml,application/json",label:"Restore class from file (yaml, json)","prepend-icon":"mdi-upload"},on:{change:e.restoreFile},model:{value:e.selectedFile,callback:function(t){e.selectedFile=t},expression:"selectedFile"}})],1),e._v(" "),n("v-col",[n("v-row",{attrs:{"no-gutters":""}},[n("v-col",{attrs:{cols:"4"}},[n("v-btn",{attrs:{"prepend-icon":"mdi-link"},on:{click:e.restoreURL}},[n("v-icon",[e._v("\n mdi-link\n ")]),e._v("\n Load\n ")],1)],1),e._v(" "),n("v-col",{attrs:{cols:"8"}},[n("v-text-field",{attrs:{dense:"",label:"class from URL"},on:{keyup:function(t){return!t.type.indexOf("key")&&e._k(t.keyCode,"enter",13,t.key,"Enter")?null:e.restoreURL.apply(null,arguments)}},model:{value:e.selectedURL,callback:function(t){e.selectedURL=t},expression:"selectedURL"}})],1)],1)],1)],1),e._v(" "),n("v-divider",{staticClass:"pb-2"}),e._v(" "),n("v-btn",{attrs:{href:"https://github.com/topics/edrys-classroom",target:"_blank"}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-github ")]),e._v("\n Explore on GitHub\n ")],1)],1)],1),e._v(" "),e.errorMessage?n("v-alert",{attrs:{"close-text":"Close Alert",color:"red",type:"error",dark:"",outlined:"",dismissible:""},on:{input:function(){e.errorMessage=void 0}}},[n("div",{domProps:{innerHTML:e._s(e.errorMessage)}})]):e._e()],1),e._v(" "),n("v-snackbar",{attrs:{timeout:2e3,value:e.restoreSuccess,absolute:"",bottom:"",right:"",color:"success"}},[e._v("\n File restored - check everything is okay then save\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:600,value:e.saveSuccess,absolute:"",bottom:"",right:""}},[e._v("\n Class saved successfully\n ")]),e._v(" "),n("v-snackbar",{attrs:{timeout:1400,value:e.saveError,color:"error",absolute:"",bottom:"",right:""}},[e._v("\n Sorry there was a problem saving, please try again\n ")]),e._v(" "),n("v-card-actions",[n("div",{staticClass:"pr-4 float-right"},[n("v-badge",{staticStyle:{"margin-top":"30px"},attrs:{overlap:"",dot:"",color:"red",value:e.pendingEdits}},[n("v-btn",{attrs:{color:"primary",loading:e.saveLoading,disabled:e.saveLoading},on:{click:e.save}},[n("v-icon",{attrs:{left:""}},[e._v(" mdi-upload ")]),e._v("\n Save\n ")],1)],1)],1),e._v(" "),n("v-menu",{attrs:{"offset-y":""},scopedSlots:e._u([{key:"activator",fn:function(t){var r=t.on,o=t.attrs;return[n("v-btn",e._g(e._b({staticClass:"float-right",staticStyle:{"margin-top":"30px","margin-right":"10px"},attrs:{color:"",depressed:""}},"v-btn",o,!1),r),[e._v("\n Delete Class")])]}}])},[e._v(" "),n("v-list",[n("v-list-item",[n("v-list-item-content",[e._v("Are you sure?\n\n "),n("v-btn",{staticClass:"float-right",staticStyle:{"margin-top":"10px"},attrs:{color:"red",depressed:""},on:{click:e.deleteClass}},[e._v("\n Yes, delete forever")])],1)],1)],1)],1)],1)],1)}),[],!1,null,null,null);t.default=component.exports;L()(component,{VAlert:I.a,VBadge:M.a,VBtn:V.a,VCard:$.a,VCardActions:O.a,VCardText:O.c,VCol:R.a,VDivider:j.a,VExpansionPanel:E.a,VExpansionPanelContent:T.a,VExpansionPanelHeader:F.a,VExpansionPanels:P.a,VFileInput:A.a,VForm:N.a,VIcon:D.a,VList:J.a,VListItem:H.a,VListItemAction:z.a,VListItemAvatar:B.a,VListItemContent:G.a,VListItemSubtitle:G.b,VListItemTitle:G.c,VMenu:Y.a,VRow:K.a,VSkeletonLoader:Q.a,VSnackbar:W.a,VSpacer:X.a,VTab:Z.a,VTabItem:ee.a,VTabs:te.a,VTabsItems:ne.a,VTextField:re.a,VTextarea:se.a,VToolbar:ae.a,VToolbarTitle:oe.a})},558:function(e,t,n){"use strict";n(529)},559:function(e,t,n){var r=n(19)(!1);r.push([e.i,".prism-editor{background:#2d2d2d;color:#ccc;font-family:Fira code,Fira Mono,Consolas,Menlo,Courier,monospace;font-size:14px;line-height:1.5;padding:5px;max-height:35 vh}",""]),e.exports=r}}]); \ No newline at end of file diff --git a/dist/static/_nuxt/c16fb80.js b/dist/static/_nuxt/51601b1.js similarity index 94% rename from dist/static/_nuxt/c16fb80.js rename to dist/static/_nuxt/51601b1.js index c75b09a..c1bac64 100644 --- a/dist/static/_nuxt/c16fb80.js +++ b/dist/static/_nuxt/51601b1.js @@ -1 +1 @@ -!function(e){function r(data){for(var r,n,f=data[0],l=data[1],d=data[2],i=0,h=[];i - * Released under the MIT License. - */ - -/*! - * vue-no-ssr v1.1.1 - * (c) 2018-present egoist <0x142857@gmail.com> - * Released under the MIT License. - */ - -/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ - - /** * Prism: Lightweight, robust, elegant syntax highlighting * @@ -47,3 +32,18 @@ * (c) 2021 Evan You * @license MIT */ + + +/*! + * vue-client-only v0.0.0-semantic-release + * (c) 2021-present egoist <0x142857@gmail.com> + * Released under the MIT License. + */ + +/*! + * vue-no-ssr v1.1.1 + * (c) 2018-present egoist <0x142857@gmail.com> + * Released under the MIT License. + */ + +/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ diff --git a/dist/static/_nuxt/d830c61.js b/dist/static/_nuxt/d463427.js similarity index 100% rename from dist/static/_nuxt/d830c61.js rename to dist/static/_nuxt/d463427.js diff --git a/dist/static/_nuxt/345976e.js b/dist/static/_nuxt/def4792.js similarity index 100% rename from dist/static/_nuxt/345976e.js rename to dist/static/_nuxt/def4792.js diff --git a/dist/static/index.html b/dist/static/index.html index e802366..d153dcf 100644 --- a/dist/static/index.html +++ b/dist/static/index.html @@ -1,9 +1,9 @@ - Home - Edrys + Home - Edrys
Loading...
- + From 9c33a9dc17cfbfe83662072841c38df6d9d60594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Dietrich?= Date: Sat, 8 Jul 2023 07:09:06 +0200 Subject: [PATCH 09/11] Students can now change their rooms manually --- client/components/Student.vue | 179 +++++++++++++++++++++++++++++++++- server/data_web.ts | 26 ++--- 2 files changed, 186 insertions(+), 19 deletions(-) diff --git a/client/components/Student.vue b/client/components/Student.vue index 8944b5e..fe302c4 100644 --- a/client/components/Student.vue +++ b/client/components/Student.vue @@ -1,5 +1,119 @@