@vue-skuilder/common-ui 0.1.13-1 → 0.1.13-11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index.css +2 -2
- package/dist/common-ui.es.js +1235 -261
- package/dist/common-ui.es.js.map +1 -1
- package/dist/common-ui.umd.js +2 -2
- package/dist/common-ui.umd.js.map +1 -1
- package/dist/components/auth/index.d.ts +4 -0
- package/dist/components/auth/index.d.ts.map +1 -1
- package/dist/composables/useEntitlements.d.ts +32 -0
- package/dist/composables/useEntitlements.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/services/authAPI.d.ts +65 -0
- package/dist/services/authAPI.d.ts.map +1 -0
- package/dist/stores/useAuthStore.d.ts +2 -2
- package/dist/stores/useAuthStore.d.ts.map +1 -1
- package/dist/stores/useConfigStore.d.ts.map +1 -1
- package/dist/utils/passwordValidation.d.ts +13 -0
- package/dist/utils/passwordValidation.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/components/SkMouseTrap.vue +1 -1
- package/src/components/StudySession.vue +29 -14
- package/src/components/auth/RequestPasswordReset.vue +131 -0
- package/src/components/auth/ResetPassword.vue +188 -0
- package/src/components/auth/UserLogin.vue +36 -9
- package/src/components/auth/UserLoginAndRegistrationContainer.vue +40 -10
- package/src/components/auth/UserRegistration.vue +90 -9
- package/src/components/auth/VerifyEmail.vue +156 -0
- package/src/components/auth/index.ts +19 -1
- package/src/components/cardRendering/CardViewer.vue +9 -19
- package/src/composables/useEntitlements.ts +118 -0
- package/src/index.ts +6 -0
- package/src/services/authAPI.ts +243 -0
- package/src/stores/useAuthStore.ts +6 -2
- package/src/stores/useConfigStore.ts +27 -13
- package/src/utils/passwordValidation.ts +31 -0
package/dist/common-ui.es.js
CHANGED
|
@@ -4001,7 +4001,7 @@ hooks.HTML5_FMT = {
|
|
|
4001
4001
|
MONTH: "YYYY-MM"
|
|
4002
4002
|
// <input type="month" />
|
|
4003
4003
|
};
|
|
4004
|
-
const _sfc_main$
|
|
4004
|
+
const _sfc_main$w = defineComponent({
|
|
4005
4005
|
name: "HeatMap",
|
|
4006
4006
|
props: {
|
|
4007
4007
|
// Accept activity records directly as a prop
|
|
@@ -4246,10 +4246,10 @@ const _export_sfc = (sfc, props) => {
|
|
|
4246
4246
|
}
|
|
4247
4247
|
return target;
|
|
4248
4248
|
};
|
|
4249
|
-
const _hoisted_1$
|
|
4250
|
-
const _hoisted_2$
|
|
4251
|
-
const _hoisted_3$
|
|
4252
|
-
function _sfc_render$
|
|
4249
|
+
const _hoisted_1$m = ["width", "height"];
|
|
4250
|
+
const _hoisted_2$c = ["transform"];
|
|
4251
|
+
const _hoisted_3$9 = ["y", "width", "height", "fill", "onMouseover"];
|
|
4252
|
+
function _sfc_render$q(_ctx, _cache, $props, $setup, $data, $options) {
|
|
4253
4253
|
return openBlock(), createElementBlock("div", null, [
|
|
4254
4254
|
(openBlock(), createElementBlock("svg", {
|
|
4255
4255
|
width: _ctx.width,
|
|
@@ -4270,11 +4270,11 @@ function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4270
4270
|
fill: _ctx.getColor(day.count),
|
|
4271
4271
|
onMouseover: ($event) => _ctx.showTooltip(day, $event),
|
|
4272
4272
|
onMouseout: _cache[0] || (_cache[0] = (...args) => _ctx.hideTooltip && _ctx.hideTooltip(...args))
|
|
4273
|
-
}, null, 40, _hoisted_3$
|
|
4273
|
+
}, null, 40, _hoisted_3$9);
|
|
4274
4274
|
}), 128))
|
|
4275
|
-
], 8, _hoisted_2$
|
|
4275
|
+
], 8, _hoisted_2$c);
|
|
4276
4276
|
}), 128))
|
|
4277
|
-
], 8, _hoisted_1$
|
|
4277
|
+
], 8, _hoisted_1$m)),
|
|
4278
4278
|
_ctx.tooltipData ? (openBlock(), createElementBlock("div", {
|
|
4279
4279
|
key: 0,
|
|
4280
4280
|
class: "tooltip",
|
|
@@ -4282,7 +4282,7 @@ function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4282
4282
|
}, toDisplayString(_ctx.tooltipData.count) + " review" + toDisplayString(_ctx.tooltipData.count !== 1 ? "s" : "") + " on " + toDisplayString(_ctx.toDateString(_ctx.tooltipData.date)), 5)) : createCommentVNode("", true)
|
|
4283
4283
|
]);
|
|
4284
4284
|
}
|
|
4285
|
-
const HeatMap = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
4285
|
+
const HeatMap = /* @__PURE__ */ _export_sfc(_sfc_main$w, [["render", _sfc_render$q], ["__scopeId", "data-v-ca46239a"]]);
|
|
4286
4286
|
function getDefaultExportFromCjs(x) {
|
|
4287
4287
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
4288
4288
|
}
|
|
@@ -4862,7 +4862,7 @@ const _SkldrMouseTrap = class _SkldrMouseTrap {
|
|
|
4862
4862
|
};
|
|
4863
4863
|
__publicField(_SkldrMouseTrap, "_instance");
|
|
4864
4864
|
let SkldrMouseTrap = _SkldrMouseTrap;
|
|
4865
|
-
const _sfc_main$
|
|
4865
|
+
const _sfc_main$v = defineComponent({
|
|
4866
4866
|
name: "SkMouseTrap",
|
|
4867
4867
|
props: {
|
|
4868
4868
|
refreshInterval: {
|
|
@@ -4892,8 +4892,8 @@ const _sfc_main$s = defineComponent({
|
|
|
4892
4892
|
}
|
|
4893
4893
|
}
|
|
4894
4894
|
});
|
|
4895
|
-
const _hoisted_1$
|
|
4896
|
-
function _sfc_render$
|
|
4895
|
+
const _hoisted_1$l = { class: "text-caption ml-2" };
|
|
4896
|
+
function _sfc_render$p(_ctx, _cache, $props, $setup, $data, $options) {
|
|
4897
4897
|
const _component_v_icon = resolveComponent("v-icon");
|
|
4898
4898
|
const _component_v_btn = resolveComponent("v-btn");
|
|
4899
4899
|
const _component_v_toolbar_title = resolveComponent("v-toolbar-title");
|
|
@@ -4928,7 +4928,7 @@ function _sfc_render$m(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4928
4928
|
createVNode(_component_v_card, null, {
|
|
4929
4929
|
default: withCtx(() => [
|
|
4930
4930
|
createVNode(_component_v_toolbar, {
|
|
4931
|
-
color: "
|
|
4931
|
+
color: "secondary",
|
|
4932
4932
|
dark: "",
|
|
4933
4933
|
dense: ""
|
|
4934
4934
|
}, {
|
|
@@ -4962,7 +4962,7 @@ function _sfc_render$m(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4962
4962
|
_: 2
|
|
4963
4963
|
}, 1024),
|
|
4964
4964
|
createVNode(_component_v_spacer),
|
|
4965
|
-
createElementVNode("span", _hoisted_1$
|
|
4965
|
+
createElementVNode("span", _hoisted_1$l, toDisplayString(hk.command), 1)
|
|
4966
4966
|
]),
|
|
4967
4967
|
_: 2
|
|
4968
4968
|
}, 1024);
|
|
@@ -4977,8 +4977,8 @@ function _sfc_render$m(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4977
4977
|
_: 1
|
|
4978
4978
|
})) : createCommentVNode("", true);
|
|
4979
4979
|
}
|
|
4980
|
-
const SkMouseTrap = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
4981
|
-
const _sfc_main$
|
|
4980
|
+
const SkMouseTrap = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["render", _sfc_render$p]]);
|
|
4981
|
+
const _sfc_main$u = defineComponent({
|
|
4982
4982
|
name: "SkMouseTrapToolTip",
|
|
4983
4983
|
props: {
|
|
4984
4984
|
hotkey: {
|
|
@@ -5127,7 +5127,7 @@ const _sfc_main$r = defineComponent({
|
|
|
5127
5127
|
};
|
|
5128
5128
|
}
|
|
5129
5129
|
});
|
|
5130
|
-
function _sfc_render$
|
|
5130
|
+
function _sfc_render$o(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5131
5131
|
return openBlock(), createElementBlock("div", {
|
|
5132
5132
|
class: normalizeClass(["sk-mousetrap-tooltip-wrapper", [
|
|
5133
5133
|
_ctx.isControlKeyPressed && !_ctx.disabled && _ctx.highlightEffect !== "none" ? `sk-mousetrap-highlight-${_ctx.highlightEffect}` : ""
|
|
@@ -5151,7 +5151,7 @@ function _sfc_render$l(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5151
5151
|
})
|
|
5152
5152
|
], 2);
|
|
5153
5153
|
}
|
|
5154
|
-
const SkMouseTrapToolTip = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5154
|
+
const SkMouseTrapToolTip = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["render", _sfc_render$o], ["__scopeId", "data-v-5d6fb09c"]]);
|
|
5155
5155
|
const SnackbarServiceModule = /* @__PURE__ */ (() => {
|
|
5156
5156
|
let _instance = null;
|
|
5157
5157
|
return {
|
|
@@ -5175,7 +5175,7 @@ const SnackbarServiceModule = /* @__PURE__ */ (() => {
|
|
|
5175
5175
|
};
|
|
5176
5176
|
})();
|
|
5177
5177
|
const { setInstance, alertUser } = SnackbarServiceModule;
|
|
5178
|
-
const _sfc_main$
|
|
5178
|
+
const _sfc_main$t = defineComponent({
|
|
5179
5179
|
name: "SnackbarService",
|
|
5180
5180
|
data() {
|
|
5181
5181
|
return {
|
|
@@ -5213,8 +5213,8 @@ const _sfc_main$q = defineComponent({
|
|
|
5213
5213
|
}
|
|
5214
5214
|
}
|
|
5215
5215
|
});
|
|
5216
|
-
const _hoisted_1$
|
|
5217
|
-
function _sfc_render$
|
|
5216
|
+
const _hoisted_1$k = { class: "d-flex align-center justify-space-between w-100" };
|
|
5217
|
+
function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5218
5218
|
const _component_v_icon = resolveComponent("v-icon");
|
|
5219
5219
|
const _component_v_btn = resolveComponent("v-btn");
|
|
5220
5220
|
const _component_v_snackbar = resolveComponent("v-snackbar");
|
|
@@ -5229,7 +5229,7 @@ function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5229
5229
|
color: _ctx.getColor(snack)
|
|
5230
5230
|
}, {
|
|
5231
5231
|
default: withCtx(() => [
|
|
5232
|
-
createElementVNode("div", _hoisted_1$
|
|
5232
|
+
createElementVNode("div", _hoisted_1$k, [
|
|
5233
5233
|
createElementVNode("span", null, toDisplayString(snack.text), 1),
|
|
5234
5234
|
createVNode(_component_v_btn, {
|
|
5235
5235
|
icon: "",
|
|
@@ -5253,8 +5253,8 @@ function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5253
5253
|
}), 128))
|
|
5254
5254
|
]);
|
|
5255
5255
|
}
|
|
5256
|
-
const SnackbarService = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5257
|
-
const _sfc_main$
|
|
5256
|
+
const SnackbarService = /* @__PURE__ */ _export_sfc(_sfc_main$t, [["render", _sfc_render$n]]);
|
|
5257
|
+
const _sfc_main$s = defineComponent({
|
|
5258
5258
|
name: "PaginatingToolbar",
|
|
5259
5259
|
props: {
|
|
5260
5260
|
pages: {
|
|
@@ -5278,12 +5278,12 @@ const _sfc_main$p = defineComponent({
|
|
|
5278
5278
|
},
|
|
5279
5279
|
emits: ["first", "prev", "next", "last", "set-page"]
|
|
5280
5280
|
});
|
|
5281
|
-
const _hoisted_1$
|
|
5281
|
+
const _hoisted_1$j = {
|
|
5282
5282
|
key: 0,
|
|
5283
5283
|
class: "ms-2 text-subtitle-2",
|
|
5284
5284
|
"data-cy": "paginating-toolbar-subtitle"
|
|
5285
5285
|
};
|
|
5286
|
-
function _sfc_render$
|
|
5286
|
+
function _sfc_render$m(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5287
5287
|
const _component_v_toolbar_title = resolveComponent("v-toolbar-title");
|
|
5288
5288
|
const _component_v_spacer = resolveComponent("v-spacer");
|
|
5289
5289
|
const _component_v_icon = resolveComponent("v-icon");
|
|
@@ -5295,7 +5295,7 @@ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5295
5295
|
createVNode(_component_v_toolbar_title, null, {
|
|
5296
5296
|
default: withCtx(() => [
|
|
5297
5297
|
createElementVNode("span", null, toDisplayString(_ctx.title), 1),
|
|
5298
|
-
_ctx.subtitle ? (openBlock(), createElementBlock("span", _hoisted_1$
|
|
5298
|
+
_ctx.subtitle ? (openBlock(), createElementBlock("span", _hoisted_1$j, toDisplayString(_ctx.subtitle), 1)) : createCommentVNode("", true)
|
|
5299
5299
|
]),
|
|
5300
5300
|
_: 1
|
|
5301
5301
|
}),
|
|
@@ -5387,8 +5387,8 @@ function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5387
5387
|
_: 1
|
|
5388
5388
|
});
|
|
5389
5389
|
}
|
|
5390
|
-
const PaginatingToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5391
|
-
const _sfc_main$
|
|
5390
|
+
const PaginatingToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["render", _sfc_render$m], ["__scopeId", "data-v-a75fea7e"]]);
|
|
5391
|
+
const _sfc_main$r = defineComponent({
|
|
5392
5392
|
name: "CardSearch",
|
|
5393
5393
|
emits: {
|
|
5394
5394
|
search: (query) => typeof query === "string"
|
|
@@ -5404,10 +5404,10 @@ const _sfc_main$o = defineComponent({
|
|
|
5404
5404
|
}
|
|
5405
5405
|
}
|
|
5406
5406
|
});
|
|
5407
|
-
const _hoisted_1$
|
|
5408
|
-
function _sfc_render$
|
|
5407
|
+
const _hoisted_1$i = { class: "card-search" };
|
|
5408
|
+
function _sfc_render$l(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5409
5409
|
const _component_v_text_field = resolveComponent("v-text-field");
|
|
5410
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
5410
|
+
return openBlock(), createElementBlock("div", _hoisted_1$i, [
|
|
5411
5411
|
createVNode(_component_v_text_field, {
|
|
5412
5412
|
modelValue: _ctx.query,
|
|
5413
5413
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.query = $event),
|
|
@@ -5418,8 +5418,8 @@ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5418
5418
|
}, null, 8, ["modelValue", "onClick:append", "onKeydown"])
|
|
5419
5419
|
]);
|
|
5420
5420
|
}
|
|
5421
|
-
const CardSearch = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5422
|
-
const _sfc_main$
|
|
5421
|
+
const CardSearch = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["render", _sfc_render$l]]);
|
|
5422
|
+
const _sfc_main$q = defineComponent({
|
|
5423
5423
|
name: "CardSearchResults",
|
|
5424
5424
|
emits: {
|
|
5425
5425
|
"card-selected": (payload) => typeof payload.cardId === "string" && typeof payload.courseId === "string"
|
|
@@ -5497,17 +5497,17 @@ const _sfc_main$n = defineComponent({
|
|
|
5497
5497
|
}
|
|
5498
5498
|
}
|
|
5499
5499
|
});
|
|
5500
|
-
const _hoisted_1$
|
|
5501
|
-
const _hoisted_2$
|
|
5502
|
-
const _hoisted_3$
|
|
5503
|
-
const _hoisted_4$
|
|
5504
|
-
function _sfc_render$
|
|
5500
|
+
const _hoisted_1$h = { class: "card-search-results" };
|
|
5501
|
+
const _hoisted_2$b = { key: 0 };
|
|
5502
|
+
const _hoisted_3$8 = { key: 1 };
|
|
5503
|
+
const _hoisted_4$6 = { key: 2 };
|
|
5504
|
+
function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5505
5505
|
const _component_v_list_item_title = resolveComponent("v-list-item-title");
|
|
5506
5506
|
const _component_v_list_item_subtitle = resolveComponent("v-list-item-subtitle");
|
|
5507
5507
|
const _component_v_list_item = resolveComponent("v-list-item");
|
|
5508
5508
|
const _component_v_list = resolveComponent("v-list");
|
|
5509
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
5510
|
-
_ctx.loading ? (openBlock(), createElementBlock("div", _hoisted_2$
|
|
5509
|
+
return openBlock(), createElementBlock("div", _hoisted_1$h, [
|
|
5510
|
+
_ctx.loading ? (openBlock(), createElementBlock("div", _hoisted_2$b, "Loading...")) : _ctx.error ? (openBlock(), createElementBlock("div", _hoisted_3$8, toDisplayString(_ctx.error), 1)) : (openBlock(), createElementBlock("div", _hoisted_4$6, [
|
|
5511
5511
|
createVNode(_component_v_list, null, {
|
|
5512
5512
|
default: withCtx(() => [
|
|
5513
5513
|
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.cards, (card) => {
|
|
@@ -5539,8 +5539,8 @@ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5539
5539
|
]))
|
|
5540
5540
|
]);
|
|
5541
5541
|
}
|
|
5542
|
-
const CardSearchResults = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5543
|
-
const _sfc_main$
|
|
5542
|
+
const CardSearchResults = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["render", _sfc_render$k], ["__scopeId", "data-v-285e13bd"]]);
|
|
5543
|
+
const _sfc_main$p = defineComponent({
|
|
5544
5544
|
name: "CardHistoryViewer",
|
|
5545
5545
|
props: {
|
|
5546
5546
|
cardId: {
|
|
@@ -5635,15 +5635,15 @@ const _sfc_main$m = defineComponent({
|
|
|
5635
5635
|
}
|
|
5636
5636
|
}
|
|
5637
5637
|
});
|
|
5638
|
-
const _hoisted_1$
|
|
5639
|
-
const _hoisted_2$
|
|
5640
|
-
const _hoisted_3$
|
|
5641
|
-
const _hoisted_4$
|
|
5638
|
+
const _hoisted_1$g = { class: "card-history-viewer" };
|
|
5639
|
+
const _hoisted_2$a = { key: 0 };
|
|
5640
|
+
const _hoisted_3$7 = { key: 1 };
|
|
5641
|
+
const _hoisted_4$5 = {
|
|
5642
5642
|
key: 2,
|
|
5643
5643
|
class: "error-message"
|
|
5644
5644
|
};
|
|
5645
|
-
const _hoisted_5$
|
|
5646
|
-
function _sfc_render$
|
|
5645
|
+
const _hoisted_5$5 = { key: 3 };
|
|
5646
|
+
function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5647
5647
|
const _component_v_card_title = resolveComponent("v-card-title");
|
|
5648
5648
|
const _component_v_list_item_title = resolveComponent("v-list-item-title");
|
|
5649
5649
|
const _component_v_list_item_subtitle = resolveComponent("v-list-item-subtitle");
|
|
@@ -5651,9 +5651,9 @@ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5651
5651
|
const _component_v_list_item = resolveComponent("v-list-item");
|
|
5652
5652
|
const _component_v_card = resolveComponent("v-card");
|
|
5653
5653
|
const _component_v_data_table = resolveComponent("v-data-table");
|
|
5654
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
5655
|
-
_ctx.userId ? (openBlock(), createElementBlock("h3", _hoisted_2$
|
|
5656
|
-
_ctx.loading ? (openBlock(), createElementBlock("div", _hoisted_3$
|
|
5654
|
+
return openBlock(), createElementBlock("div", _hoisted_1$g, [
|
|
5655
|
+
_ctx.userId ? (openBlock(), createElementBlock("h3", _hoisted_2$a, "Card History for User: " + toDisplayString(_ctx.userId), 1)) : createCommentVNode("", true),
|
|
5656
|
+
_ctx.loading ? (openBlock(), createElementBlock("div", _hoisted_3$7, "Loading...")) : _ctx.error ? (openBlock(), createElementBlock("div", _hoisted_4$5, toDisplayString(_ctx.error), 1)) : _ctx.cardHistory ? (openBlock(), createElementBlock("div", _hoisted_5$5, [
|
|
5657
5657
|
createVNode(_component_v_card, { class: "mb-4" }, {
|
|
5658
5658
|
default: withCtx(() => [
|
|
5659
5659
|
createVNode(_component_v_card_title, null, {
|
|
@@ -5739,7 +5739,7 @@ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5739
5739
|
])) : createCommentVNode("", true)
|
|
5740
5740
|
]);
|
|
5741
5741
|
}
|
|
5742
|
-
const CardHistoryViewer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5742
|
+
const CardHistoryViewer = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["render", _sfc_render$j], ["__scopeId", "data-v-a4bdfdfb"]]);
|
|
5743
5743
|
function useViewable(props, emit, componentName) {
|
|
5744
5744
|
const startTime = ref(hooks.utc());
|
|
5745
5745
|
const hotKeys = ref([]);
|
|
@@ -5908,7 +5908,212 @@ class Question extends Displayable {
|
|
|
5908
5908
|
with 7 * 4 = 21
|
|
5909
5909
|
*/
|
|
5910
5910
|
}
|
|
5911
|
-
const
|
|
5911
|
+
const getApiBase = () => {
|
|
5912
|
+
let source = "fallback (empty string)";
|
|
5913
|
+
let result = "";
|
|
5914
|
+
if (!result && typeof window !== "undefined" && window.__SKUILDER_CONFIG__?.apiBase) {
|
|
5915
|
+
const base = window.__SKUILDER_CONFIG__.apiBase;
|
|
5916
|
+
const cleaned = base.replace(/\/$/, "");
|
|
5917
|
+
result = cleaned.startsWith("/") ? cleaned : `/${cleaned}`;
|
|
5918
|
+
source = "window.__SKUILDER_CONFIG__.apiBase";
|
|
5919
|
+
}
|
|
5920
|
+
console.log("[authAPI] getApiBase() called");
|
|
5921
|
+
console.log("[authAPI] source:", source);
|
|
5922
|
+
console.log("[authAPI] result:", result);
|
|
5923
|
+
return result;
|
|
5924
|
+
};
|
|
5925
|
+
async function sendVerificationEmail(username, email, origin) {
|
|
5926
|
+
try {
|
|
5927
|
+
const body = { username, email };
|
|
5928
|
+
if (origin) {
|
|
5929
|
+
body.origin = origin;
|
|
5930
|
+
}
|
|
5931
|
+
const response = await fetch(`${getApiBase()}/auth/send-verification`, {
|
|
5932
|
+
method: "POST",
|
|
5933
|
+
headers: { "Content-Type": "application/json" },
|
|
5934
|
+
credentials: "include",
|
|
5935
|
+
body: JSON.stringify(body)
|
|
5936
|
+
});
|
|
5937
|
+
if (!response.ok) {
|
|
5938
|
+
const errorText = await response.text();
|
|
5939
|
+
console.error("Send verification email error:", errorText);
|
|
5940
|
+
return {
|
|
5941
|
+
ok: false,
|
|
5942
|
+
error: `HTTP ${response.status}: ${response.statusText}`
|
|
5943
|
+
};
|
|
5944
|
+
}
|
|
5945
|
+
return await response.json();
|
|
5946
|
+
} catch (error) {
|
|
5947
|
+
console.error("Send verification email fetch error:", error);
|
|
5948
|
+
return {
|
|
5949
|
+
ok: false,
|
|
5950
|
+
error: error instanceof Error ? error.message : "Network error"
|
|
5951
|
+
};
|
|
5952
|
+
}
|
|
5953
|
+
}
|
|
5954
|
+
async function verifyEmail(token2) {
|
|
5955
|
+
try {
|
|
5956
|
+
const response = await fetch(`${getApiBase()}/auth/verify`, {
|
|
5957
|
+
method: "POST",
|
|
5958
|
+
headers: { "Content-Type": "application/json" },
|
|
5959
|
+
credentials: "include",
|
|
5960
|
+
body: JSON.stringify({ token: token2 })
|
|
5961
|
+
});
|
|
5962
|
+
if (!response.ok) {
|
|
5963
|
+
return {
|
|
5964
|
+
ok: false,
|
|
5965
|
+
error: `HTTP ${response.status}: ${response.statusText}`
|
|
5966
|
+
};
|
|
5967
|
+
}
|
|
5968
|
+
return await response.json();
|
|
5969
|
+
} catch (error) {
|
|
5970
|
+
return {
|
|
5971
|
+
ok: false,
|
|
5972
|
+
error: error instanceof Error ? error.message : "Network error"
|
|
5973
|
+
};
|
|
5974
|
+
}
|
|
5975
|
+
}
|
|
5976
|
+
async function getUserStatus() {
|
|
5977
|
+
try {
|
|
5978
|
+
const response = await fetch(`${getApiBase()}/auth/status`, {
|
|
5979
|
+
method: "GET",
|
|
5980
|
+
headers: { "Content-Type": "application/json" },
|
|
5981
|
+
credentials: "include"
|
|
5982
|
+
});
|
|
5983
|
+
if (!response.ok) {
|
|
5984
|
+
return {
|
|
5985
|
+
ok: false,
|
|
5986
|
+
error: `HTTP ${response.status}: ${response.statusText}`
|
|
5987
|
+
};
|
|
5988
|
+
}
|
|
5989
|
+
return await response.json();
|
|
5990
|
+
} catch (error) {
|
|
5991
|
+
return {
|
|
5992
|
+
ok: false,
|
|
5993
|
+
error: error instanceof Error ? error.message : "Network error"
|
|
5994
|
+
};
|
|
5995
|
+
}
|
|
5996
|
+
}
|
|
5997
|
+
async function requestPasswordReset(email, origin) {
|
|
5998
|
+
try {
|
|
5999
|
+
const body = { email };
|
|
6000
|
+
if (origin) {
|
|
6001
|
+
body.origin = origin;
|
|
6002
|
+
}
|
|
6003
|
+
const response = await fetch(`${getApiBase()}/auth/request-reset`, {
|
|
6004
|
+
method: "POST",
|
|
6005
|
+
headers: { "Content-Type": "application/json" },
|
|
6006
|
+
credentials: "include",
|
|
6007
|
+
body: JSON.stringify(body)
|
|
6008
|
+
});
|
|
6009
|
+
if (!response.ok) {
|
|
6010
|
+
return {
|
|
6011
|
+
ok: false,
|
|
6012
|
+
error: `HTTP ${response.status}: ${response.statusText}`
|
|
6013
|
+
};
|
|
6014
|
+
}
|
|
6015
|
+
return await response.json();
|
|
6016
|
+
} catch (error) {
|
|
6017
|
+
return {
|
|
6018
|
+
ok: false,
|
|
6019
|
+
error: error instanceof Error ? error.message : "Network error"
|
|
6020
|
+
};
|
|
6021
|
+
}
|
|
6022
|
+
}
|
|
6023
|
+
async function resetPassword(token2, newPassword) {
|
|
6024
|
+
try {
|
|
6025
|
+
const response = await fetch(`${getApiBase()}/auth/reset-password`, {
|
|
6026
|
+
method: "POST",
|
|
6027
|
+
headers: { "Content-Type": "application/json" },
|
|
6028
|
+
credentials: "include",
|
|
6029
|
+
body: JSON.stringify({ token: token2, newPassword })
|
|
6030
|
+
});
|
|
6031
|
+
if (!response.ok) {
|
|
6032
|
+
return {
|
|
6033
|
+
ok: false,
|
|
6034
|
+
error: `HTTP ${response.status}: ${response.statusText}`
|
|
6035
|
+
};
|
|
6036
|
+
}
|
|
6037
|
+
return await response.json();
|
|
6038
|
+
} catch (error) {
|
|
6039
|
+
return {
|
|
6040
|
+
ok: false,
|
|
6041
|
+
error: error instanceof Error ? error.message : "Network error"
|
|
6042
|
+
};
|
|
6043
|
+
}
|
|
6044
|
+
}
|
|
6045
|
+
function useEntitlements(courseId) {
|
|
6046
|
+
const entitlements = ref({});
|
|
6047
|
+
const loading = ref(false);
|
|
6048
|
+
const error = ref(null);
|
|
6049
|
+
const trialStatus = computed(() => {
|
|
6050
|
+
const entitlement = entitlements.value[courseId];
|
|
6051
|
+
if (!entitlement) {
|
|
6052
|
+
return {
|
|
6053
|
+
isActive: false,
|
|
6054
|
+
isPaid: false,
|
|
6055
|
+
daysRemaining: null,
|
|
6056
|
+
expiresDate: null
|
|
6057
|
+
};
|
|
6058
|
+
}
|
|
6059
|
+
if (entitlement.status === "paid") {
|
|
6060
|
+
return {
|
|
6061
|
+
isActive: true,
|
|
6062
|
+
isPaid: true,
|
|
6063
|
+
daysRemaining: null,
|
|
6064
|
+
expiresDate: null
|
|
6065
|
+
};
|
|
6066
|
+
}
|
|
6067
|
+
const expiresDate = entitlement.expires;
|
|
6068
|
+
if (!expiresDate) {
|
|
6069
|
+
return {
|
|
6070
|
+
isActive: true,
|
|
6071
|
+
isPaid: false,
|
|
6072
|
+
daysRemaining: null,
|
|
6073
|
+
expiresDate: null
|
|
6074
|
+
};
|
|
6075
|
+
}
|
|
6076
|
+
const expires = new Date(expiresDate);
|
|
6077
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
6078
|
+
const daysLeft = Math.ceil((expires.getTime() - now2.getTime()) / (1e3 * 60 * 60 * 24));
|
|
6079
|
+
return {
|
|
6080
|
+
isActive: daysLeft > 0,
|
|
6081
|
+
isPaid: false,
|
|
6082
|
+
daysRemaining: Math.max(0, daysLeft),
|
|
6083
|
+
expiresDate
|
|
6084
|
+
};
|
|
6085
|
+
});
|
|
6086
|
+
const hasPremiumAccess = computed(() => {
|
|
6087
|
+
return trialStatus.value.isPaid;
|
|
6088
|
+
});
|
|
6089
|
+
async function fetchEntitlements() {
|
|
6090
|
+
loading.value = true;
|
|
6091
|
+
error.value = null;
|
|
6092
|
+
try {
|
|
6093
|
+
const result = await getUserStatus();
|
|
6094
|
+
if (result.ok) {
|
|
6095
|
+
entitlements.value = result.entitlements || {};
|
|
6096
|
+
} else {
|
|
6097
|
+
error.value = result.error || "Failed to fetch entitlements";
|
|
6098
|
+
console.error("[useEntitlements] Error:", error.value);
|
|
6099
|
+
}
|
|
6100
|
+
} catch (e) {
|
|
6101
|
+
error.value = e instanceof Error ? e.message : "Unknown error";
|
|
6102
|
+
console.error("[useEntitlements] Exception:", e);
|
|
6103
|
+
} finally {
|
|
6104
|
+
loading.value = false;
|
|
6105
|
+
}
|
|
6106
|
+
}
|
|
6107
|
+
return {
|
|
6108
|
+
entitlements,
|
|
6109
|
+
trialStatus,
|
|
6110
|
+
hasPremiumAccess,
|
|
6111
|
+
loading,
|
|
6112
|
+
error,
|
|
6113
|
+
fetchEntitlements
|
|
6114
|
+
};
|
|
6115
|
+
}
|
|
6116
|
+
const _sfc_main$o = defineComponent({
|
|
5912
6117
|
name: "StudySessionTimer",
|
|
5913
6118
|
props: {
|
|
5914
6119
|
/**
|
|
@@ -5962,7 +6167,7 @@ const _sfc_main$l = defineComponent({
|
|
|
5962
6167
|
};
|
|
5963
6168
|
}
|
|
5964
6169
|
});
|
|
5965
|
-
function _sfc_render$
|
|
6170
|
+
function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5966
6171
|
const _component_v_icon = resolveComponent("v-icon");
|
|
5967
6172
|
const _component_v_btn = resolveComponent("v-btn");
|
|
5968
6173
|
const _component_v_progress_circular = resolveComponent("v-progress-circular");
|
|
@@ -6016,8 +6221,8 @@ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
6016
6221
|
_: 1
|
|
6017
6222
|
});
|
|
6018
6223
|
}
|
|
6019
|
-
const StudySessionTimer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
6020
|
-
const _sfc_main$
|
|
6224
|
+
const StudySessionTimer = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["render", _sfc_render$i], ["__scopeId", "data-v-5960940a"]]);
|
|
6225
|
+
const _sfc_main$n = defineComponent({
|
|
6021
6226
|
name: "CardViewer",
|
|
6022
6227
|
ref: {},
|
|
6023
6228
|
props: {
|
|
@@ -6071,31 +6276,23 @@ const _sfc_main$k = defineComponent({
|
|
|
6071
6276
|
}
|
|
6072
6277
|
}
|
|
6073
6278
|
});
|
|
6074
|
-
function _sfc_render$
|
|
6279
|
+
function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
|
|
6075
6280
|
const _component_v_card = resolveComponent("v-card");
|
|
6076
6281
|
return openBlock(), createBlock(_component_v_card, { elevation: "12" }, {
|
|
6077
6282
|
default: withCtx(() => [
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6086
|
-
data: _ctx.data,
|
|
6087
|
-
"modify-difficulty": _ctx.user_elo.global.score - _ctx.card_elo,
|
|
6088
|
-
class: "cardView ma-2 pa-2",
|
|
6089
|
-
onEmitResponse: _cache[0] || (_cache[0] = ($event) => _ctx.processResponse($event))
|
|
6090
|
-
}, null, 40, ["data", "modify-difficulty"]))
|
|
6091
|
-
]),
|
|
6092
|
-
_: 1
|
|
6093
|
-
})
|
|
6283
|
+
(openBlock(), createBlock(resolveDynamicComponent(_ctx.view), {
|
|
6284
|
+
ref: "activeView",
|
|
6285
|
+
key: _ctx.course_id + "-" + _ctx.card_id + "-" + _ctx.sessionOrder,
|
|
6286
|
+
data: _ctx.data,
|
|
6287
|
+
"modify-difficulty": _ctx.user_elo.global.score - _ctx.card_elo,
|
|
6288
|
+
class: "cardView ma-2 pa-2",
|
|
6289
|
+
onEmitResponse: _cache[0] || (_cache[0] = ($event) => _ctx.processResponse($event))
|
|
6290
|
+
}, null, 40, ["data", "modify-difficulty"]))
|
|
6094
6291
|
]),
|
|
6095
6292
|
_: 1
|
|
6096
6293
|
});
|
|
6097
6294
|
}
|
|
6098
|
-
const CardViewer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
6295
|
+
const CardViewer = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["render", _sfc_render$h], ["__scopeId", "data-v-318fb94f"]]);
|
|
6099
6296
|
var module$1 = {};
|
|
6100
6297
|
(function main(global, module2, isWorker, workerSize) {
|
|
6101
6298
|
var canUseWorker = !!(global.Worker && global.Blob && global.Promise && global.OffscreenCanvas && global.OffscreenCanvasRenderingContext2D && global.HTMLCanvasElement && global.HTMLCanvasElement.prototype.transferControlToOffscreen && global.URL && global.URL.createObjectURL);
|
|
@@ -6792,7 +6989,7 @@ var module$1 = {};
|
|
|
6792
6989
|
}(), module$1, false);
|
|
6793
6990
|
const confetti = module$1.exports;
|
|
6794
6991
|
module$1.exports.create;
|
|
6795
|
-
const _sfc_main$
|
|
6992
|
+
const _sfc_main$m = defineComponent({
|
|
6796
6993
|
name: "StudySession",
|
|
6797
6994
|
ref: {},
|
|
6798
6995
|
components: {
|
|
@@ -7028,7 +7225,13 @@ const _sfc_main$j = defineComponent({
|
|
|
7028
7225
|
maxSessionViews,
|
|
7029
7226
|
sessionViews
|
|
7030
7227
|
);
|
|
7031
|
-
|
|
7228
|
+
try {
|
|
7229
|
+
this.handleUIFeedback(result);
|
|
7230
|
+
} catch (error) {
|
|
7231
|
+
console.error(`[StudySession] Error handling UI feedback: ${error}.
|
|
7232
|
+
|
|
7233
|
+
Result: ${JSON.stringify(result)}`);
|
|
7234
|
+
}
|
|
7032
7235
|
if (result.shouldLoadNextCard) {
|
|
7033
7236
|
this.loadCard(await this.sessionController.nextCard(result.nextCardAction));
|
|
7034
7237
|
}
|
|
@@ -7131,21 +7334,21 @@ const _sfc_main$j = defineComponent({
|
|
|
7131
7334
|
}
|
|
7132
7335
|
}
|
|
7133
7336
|
});
|
|
7134
|
-
const _hoisted_1$
|
|
7337
|
+
const _hoisted_1$f = {
|
|
7135
7338
|
key: 0,
|
|
7136
7339
|
class: "StudySession"
|
|
7137
7340
|
};
|
|
7138
|
-
const _hoisted_2$
|
|
7341
|
+
const _hoisted_2$9 = {
|
|
7139
7342
|
key: 0,
|
|
7140
7343
|
class: "text-h4"
|
|
7141
7344
|
};
|
|
7142
|
-
const _hoisted_3$
|
|
7143
|
-
const _hoisted_4$
|
|
7345
|
+
const _hoisted_3$6 = { key: 0 };
|
|
7346
|
+
const _hoisted_4$4 = {
|
|
7144
7347
|
key: 1,
|
|
7145
7348
|
ref: "shadowWrapper"
|
|
7146
7349
|
};
|
|
7147
|
-
const _hoisted_5$
|
|
7148
|
-
function _sfc_render$
|
|
7350
|
+
const _hoisted_5$4 = { key: 2 };
|
|
7351
|
+
function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7149
7352
|
const _component_v_spacer = resolveComponent("v-spacer");
|
|
7150
7353
|
const _component_v_progress_circular = resolveComponent("v-progress-circular");
|
|
7151
7354
|
const _component_v_row = resolveComponent("v-row");
|
|
@@ -7154,7 +7357,7 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7154
7357
|
const _component_StudySessionTimer = resolveComponent("StudySessionTimer");
|
|
7155
7358
|
const _component_v_col = resolveComponent("v-col");
|
|
7156
7359
|
const _component_SkMouseTrap = resolveComponent("SkMouseTrap");
|
|
7157
|
-
return _ctx.sessionPrepared ? (openBlock(), createElementBlock("div", _hoisted_1$
|
|
7360
|
+
return _ctx.sessionPrepared ? (openBlock(), createElementBlock("div", _hoisted_1$f, [
|
|
7158
7361
|
createVNode(_component_v_row, { align: "center" }, {
|
|
7159
7362
|
default: withCtx(() => [
|
|
7160
7363
|
createVNode(_component_v_spacer),
|
|
@@ -7169,29 +7372,37 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7169
7372
|
_: 1
|
|
7170
7373
|
}),
|
|
7171
7374
|
_cache[2] || (_cache[2] = createElementVNode("br", null, null, -1)),
|
|
7172
|
-
_ctx.sessionFinished ? (openBlock(), createElementBlock("div", _hoisted_2$
|
|
7375
|
+
_ctx.sessionFinished ? (openBlock(), createElementBlock("div", _hoisted_2$9, [
|
|
7173
7376
|
_cache[1] || (_cache[1] = createElementVNode("p", null, "Study session finished! Great job!", -1)),
|
|
7174
|
-
_ctx.sessionController ? (openBlock(), createElementBlock("p", _hoisted_3$
|
|
7377
|
+
_ctx.sessionController ? (openBlock(), createElementBlock("p", _hoisted_3$6, toDisplayString(_ctx.sessionController.report), 1)) : createCommentVNode("", true),
|
|
7175
7378
|
createVNode(_component_heat_map, {
|
|
7176
7379
|
"activity-records-getter": () => _ctx.user.getActivityRecords()
|
|
7177
7380
|
}, null, 8, ["activity-records-getter"])
|
|
7178
|
-
])) : (openBlock(), createElementBlock("div", _hoisted_4$
|
|
7179
|
-
(
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7381
|
+
])) : (openBlock(), createElementBlock("div", _hoisted_4$4, [
|
|
7382
|
+
createVNode(Transition, {
|
|
7383
|
+
name: "component-fade",
|
|
7384
|
+
mode: "out-in"
|
|
7385
|
+
}, {
|
|
7386
|
+
default: withCtx(() => [
|
|
7387
|
+
(openBlock(), createBlock(_component_card_viewer, {
|
|
7388
|
+
ref: "cardViewer",
|
|
7389
|
+
key: _ctx.cardID,
|
|
7390
|
+
class: normalizeClass(_ctx.loading ? "muted" : ""),
|
|
7391
|
+
view: _ctx.view,
|
|
7392
|
+
data: _ctx.data,
|
|
7393
|
+
card_id: _ctx.cardID,
|
|
7394
|
+
course_id: _ctx.courseID,
|
|
7395
|
+
"session-order": _ctx.cardCount,
|
|
7396
|
+
user_elo: _ctx.user_elo(_ctx.courseID),
|
|
7397
|
+
card_elo: _ctx.card_elo,
|
|
7398
|
+
onEmitResponse: _cache[0] || (_cache[0] = ($event) => _ctx.processResponse($event))
|
|
7399
|
+
}, null, 8, ["class", "view", "data", "card_id", "course_id", "session-order", "user_elo", "card_elo"]))
|
|
7400
|
+
]),
|
|
7401
|
+
_: 1
|
|
7402
|
+
})
|
|
7192
7403
|
], 512)),
|
|
7193
7404
|
_cache[3] || (_cache[3] = createElementVNode("br", null, null, -1)),
|
|
7194
|
-
_ctx.sessionController ? (openBlock(), createElementBlock("div", _hoisted_5$
|
|
7405
|
+
_ctx.sessionController ? (openBlock(), createElementBlock("div", _hoisted_5$4, [
|
|
7195
7406
|
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.sessionController.failedCount, (i) => {
|
|
7196
7407
|
return openBlock(), createElementBlock("span", {
|
|
7197
7408
|
key: i,
|
|
@@ -7232,7 +7443,7 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7232
7443
|
})
|
|
7233
7444
|
])) : createCommentVNode("", true);
|
|
7234
7445
|
}
|
|
7235
|
-
const StudySession = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7446
|
+
const StudySession = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$g], ["__scopeId", "data-v-f4aeb100"]]);
|
|
7236
7447
|
let _pinia = null;
|
|
7237
7448
|
const setPinia = (pinia) => {
|
|
7238
7449
|
_pinia = pinia;
|
|
@@ -7327,7 +7538,7 @@ Exceeded maximum ancestor lookup depth.`;
|
|
|
7327
7538
|
}
|
|
7328
7539
|
}
|
|
7329
7540
|
});
|
|
7330
|
-
const _sfc_main$
|
|
7541
|
+
const _sfc_main$l = defineComponent({
|
|
7331
7542
|
name: "MultipleChoiceOption",
|
|
7332
7543
|
components: {
|
|
7333
7544
|
MarkdownRenderer: defineAsyncComponent(() => Promise.resolve().then(() => MarkdownRenderer$1))
|
|
@@ -7413,7 +7624,7 @@ const _sfc_main$i = defineComponent({
|
|
|
7413
7624
|
}
|
|
7414
7625
|
}
|
|
7415
7626
|
});
|
|
7416
|
-
function _sfc_render$
|
|
7627
|
+
function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7417
7628
|
const _component_markdown_renderer = resolveComponent("markdown-renderer");
|
|
7418
7629
|
const _component_v_card = resolveComponent("v-card");
|
|
7419
7630
|
return openBlock(), createBlock(_component_v_card, {
|
|
@@ -7427,8 +7638,8 @@ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7427
7638
|
_: 1
|
|
7428
7639
|
}, 8, ["class", "onMouseover", "onClick"]);
|
|
7429
7640
|
}
|
|
7430
|
-
const MultipleChoiceOption = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7431
|
-
const _sfc_main$
|
|
7641
|
+
const MultipleChoiceOption = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$f], ["__scopeId", "data-v-96de7172"]]);
|
|
7642
|
+
const _sfc_main$k = defineComponent({
|
|
7432
7643
|
name: "RadioMultipleChoice",
|
|
7433
7644
|
components: {
|
|
7434
7645
|
MultipleChoiceOption
|
|
@@ -7567,13 +7778,13 @@ const _sfc_main$h = defineComponent({
|
|
|
7567
7778
|
// },
|
|
7568
7779
|
}
|
|
7569
7780
|
});
|
|
7570
|
-
const _hoisted_1$
|
|
7781
|
+
const _hoisted_1$e = {
|
|
7571
7782
|
ref: "containerRef",
|
|
7572
7783
|
class: "multipleChoice"
|
|
7573
7784
|
};
|
|
7574
|
-
function _sfc_render$
|
|
7785
|
+
function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7575
7786
|
const _component_MultipleChoiceOption = resolveComponent("MultipleChoiceOption");
|
|
7576
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
7787
|
+
return openBlock(), createElementBlock("div", _hoisted_1$e, [
|
|
7577
7788
|
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.choiceList, (choice, i) => {
|
|
7578
7789
|
return openBlock(), createBlock(_component_MultipleChoiceOption, {
|
|
7579
7790
|
key: i,
|
|
@@ -7587,8 +7798,8 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7587
7798
|
}), 128))
|
|
7588
7799
|
], 512);
|
|
7589
7800
|
}
|
|
7590
|
-
const RadioMultipleChoice = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7591
|
-
const _sfc_main$
|
|
7801
|
+
const RadioMultipleChoice = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$e]]);
|
|
7802
|
+
const _sfc_main$j = defineComponent({
|
|
7592
7803
|
name: "TrueFalse",
|
|
7593
7804
|
components: {
|
|
7594
7805
|
RadioMultipleChoice
|
|
@@ -7604,10 +7815,10 @@ const _sfc_main$g = defineComponent({
|
|
|
7604
7815
|
}
|
|
7605
7816
|
}
|
|
7606
7817
|
});
|
|
7607
|
-
const _hoisted_1$
|
|
7608
|
-
function _sfc_render$
|
|
7818
|
+
const _hoisted_1$d = { "data-viewable": "TrueFalse" };
|
|
7819
|
+
function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7609
7820
|
const _component_RadioMultipleChoice = resolveComponent("RadioMultipleChoice");
|
|
7610
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
7821
|
+
return openBlock(), createElementBlock("div", _hoisted_1$d, [
|
|
7611
7822
|
createVNode(_component_RadioMultipleChoice, {
|
|
7612
7823
|
"choice-list": ["True", "False"],
|
|
7613
7824
|
MouseTrap: _ctx.MouseTrap,
|
|
@@ -7615,8 +7826,8 @@ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7615
7826
|
}, null, 8, ["MouseTrap", "submit"])
|
|
7616
7827
|
]);
|
|
7617
7828
|
}
|
|
7618
|
-
const TrueFalse = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7619
|
-
const _sfc_main$
|
|
7829
|
+
const TrueFalse = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$d]]);
|
|
7830
|
+
const _sfc_main$i = defineComponent({
|
|
7620
7831
|
name: "UserInputNumber",
|
|
7621
7832
|
ref: {},
|
|
7622
7833
|
extends: UserInput,
|
|
@@ -7636,7 +7847,7 @@ const _sfc_main$f = defineComponent({
|
|
|
7636
7847
|
}
|
|
7637
7848
|
}
|
|
7638
7849
|
});
|
|
7639
|
-
function _sfc_render$
|
|
7850
|
+
function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7640
7851
|
const _component_v_text_field = resolveComponent("v-text-field");
|
|
7641
7852
|
const _component_v_container = resolveComponent("v-container");
|
|
7642
7853
|
return openBlock(), createBlock(_component_v_container, { class: "pa-0" }, {
|
|
@@ -7657,8 +7868,8 @@ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7657
7868
|
_: 1
|
|
7658
7869
|
});
|
|
7659
7870
|
}
|
|
7660
|
-
const UserInputNumber = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7661
|
-
const _sfc_main$
|
|
7871
|
+
const UserInputNumber = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$c], ["__scopeId", "data-v-a56dcd1c"]]);
|
|
7872
|
+
const _sfc_main$h = defineComponent({
|
|
7662
7873
|
name: "UserInputString",
|
|
7663
7874
|
extends: UserInput,
|
|
7664
7875
|
props: {
|
|
@@ -7695,10 +7906,10 @@ const _sfc_main$e = defineComponent({
|
|
|
7695
7906
|
// },
|
|
7696
7907
|
}
|
|
7697
7908
|
});
|
|
7698
|
-
const _hoisted_1$
|
|
7699
|
-
const _hoisted_2$
|
|
7700
|
-
function _sfc_render$
|
|
7701
|
-
return openBlock(), createElementBlock("span", _hoisted_1$
|
|
7909
|
+
const _hoisted_1$c = { class: "user-input-container" };
|
|
7910
|
+
const _hoisted_2$8 = ["autofocus"];
|
|
7911
|
+
function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7912
|
+
return openBlock(), createElementBlock("span", _hoisted_1$c, [
|
|
7702
7913
|
withDirectives(createElementVNode("input", {
|
|
7703
7914
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.answer = $event),
|
|
7704
7915
|
autofocus: _ctx.autofocus,
|
|
@@ -7706,13 +7917,13 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7706
7917
|
class: "user-input-string",
|
|
7707
7918
|
ref: "input",
|
|
7708
7919
|
onKeyup: _cache[1] || (_cache[1] = withKeys(($event) => _ctx.submitAnswer(_ctx.answer), ["enter"]))
|
|
7709
|
-
}, null, 40, _hoisted_2$
|
|
7920
|
+
}, null, 40, _hoisted_2$8), [
|
|
7710
7921
|
[vModelText, _ctx.answer]
|
|
7711
7922
|
])
|
|
7712
7923
|
]);
|
|
7713
7924
|
}
|
|
7714
|
-
const UserInputString = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7715
|
-
const _sfc_main$
|
|
7925
|
+
const UserInputString = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$b], ["__scopeId", "data-v-aa14961f"]]);
|
|
7926
|
+
const _sfc_main$g = defineComponent({
|
|
7716
7927
|
name: "FillInInput",
|
|
7717
7928
|
components: {
|
|
7718
7929
|
UserInputString
|
|
@@ -7745,13 +7956,13 @@ const _sfc_main$d = defineComponent({
|
|
|
7745
7956
|
};
|
|
7746
7957
|
}
|
|
7747
7958
|
});
|
|
7748
|
-
const _hoisted_1$
|
|
7959
|
+
const _hoisted_1$b = {
|
|
7749
7960
|
key: 0,
|
|
7750
7961
|
class: "text-h5 underline"
|
|
7751
7962
|
};
|
|
7752
|
-
function _sfc_render$
|
|
7963
|
+
function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7753
7964
|
const _component_user_input_string = resolveComponent("user-input-string");
|
|
7754
|
-
return _ctx.radioType ? (openBlock(), createElementBlock("span", _hoisted_1$
|
|
7965
|
+
return _ctx.radioType ? (openBlock(), createElementBlock("span", _hoisted_1$b, " ")) : (openBlock(), createBlock(_component_user_input_string, {
|
|
7755
7966
|
key: 1,
|
|
7756
7967
|
id: "input",
|
|
7757
7968
|
icon: false,
|
|
@@ -7759,8 +7970,8 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7759
7970
|
value: _ctx.processedText
|
|
7760
7971
|
}, null, 8, ["value"]));
|
|
7761
7972
|
}
|
|
7762
|
-
const FillInInput = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7763
|
-
const _sfc_main$
|
|
7973
|
+
const FillInInput = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$a], ["__scopeId", "data-v-486ac035"]]);
|
|
7974
|
+
const _sfc_main$f = defineComponent({
|
|
7764
7975
|
name: "CardLoader",
|
|
7765
7976
|
components: {
|
|
7766
7977
|
CardViewer
|
|
@@ -7842,7 +8053,7 @@ const _sfc_main$c = defineComponent({
|
|
|
7842
8053
|
}
|
|
7843
8054
|
}
|
|
7844
8055
|
});
|
|
7845
|
-
function _sfc_render$
|
|
8056
|
+
function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7846
8057
|
const _component_card_viewer = resolveComponent("card-viewer");
|
|
7847
8058
|
return !_ctx.loading ? (openBlock(), createBlock(_component_card_viewer, {
|
|
7848
8059
|
key: 0,
|
|
@@ -7855,7 +8066,7 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7855
8066
|
onEmitResponse: _cache[0] || (_cache[0] = ($event) => _ctx.processResponse($event))
|
|
7856
8067
|
}, null, 8, ["class", "view", "data", "card_id", "course_id", "session-order"])) : createCommentVNode("", true);
|
|
7857
8068
|
}
|
|
7858
|
-
const CardLoader = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
8069
|
+
const CardLoader = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$9], ["__scopeId", "data-v-93f758b5"]]);
|
|
7859
8070
|
function _getDefaults() {
|
|
7860
8071
|
return {
|
|
7861
8072
|
async: false,
|
|
@@ -10066,7 +10277,7 @@ function isComponent(token2) {
|
|
|
10066
10277
|
return token2.type === "text" && token2.text.startsWith("{{") && token2.text.endsWith("}}");
|
|
10067
10278
|
}
|
|
10068
10279
|
const playbackGap = 500;
|
|
10069
|
-
const _sfc_main$
|
|
10280
|
+
const _sfc_main$e = /* @__PURE__ */ defineComponent({
|
|
10070
10281
|
__name: "AudioAutoPlayer",
|
|
10071
10282
|
props: {
|
|
10072
10283
|
src: {}
|
|
@@ -10177,7 +10388,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
|
10177
10388
|
};
|
|
10178
10389
|
}
|
|
10179
10390
|
});
|
|
10180
|
-
const AudioAutoPlayer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
10391
|
+
const AudioAutoPlayer = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["__scopeId", "data-v-e1a0f62c"]]);
|
|
10181
10392
|
var core;
|
|
10182
10393
|
var hasRequiredCore;
|
|
10183
10394
|
function requireCore() {
|
|
@@ -15410,12 +15621,12 @@ function python(hljs) {
|
|
|
15410
15621
|
]
|
|
15411
15622
|
};
|
|
15412
15623
|
}
|
|
15413
|
-
const _hoisted_1$
|
|
15414
|
-
const _hoisted_2$
|
|
15624
|
+
const _hoisted_1$a = { class: "code-block-wrapper pa-2" };
|
|
15625
|
+
const _hoisted_2$7 = {
|
|
15415
15626
|
key: 0,
|
|
15416
15627
|
class: "language-indicator"
|
|
15417
15628
|
};
|
|
15418
|
-
const _sfc_main$
|
|
15629
|
+
const _sfc_main$d = /* @__PURE__ */ defineComponent({
|
|
15419
15630
|
__name: "CodeBlockRenderer",
|
|
15420
15631
|
props: {
|
|
15421
15632
|
code: {
|
|
@@ -15446,8 +15657,8 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
|
15446
15657
|
}
|
|
15447
15658
|
return (_ctx, _cache) => {
|
|
15448
15659
|
const _component_highlightjs = resolveComponent("highlightjs");
|
|
15449
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
15450
|
-
__props.language ? (openBlock(), createElementBlock("div", _hoisted_2$
|
|
15660
|
+
return openBlock(), createElementBlock("div", _hoisted_1$a, [
|
|
15661
|
+
__props.language ? (openBlock(), createElementBlock("div", _hoisted_2$7, toDisplayString(__props.language), 1)) : createCommentVNode("", true),
|
|
15451
15662
|
createVNode(_component_highlightjs, {
|
|
15452
15663
|
language: __props.language,
|
|
15453
15664
|
code: __props.code
|
|
@@ -15456,11 +15667,11 @@ const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
|
15456
15667
|
};
|
|
15457
15668
|
}
|
|
15458
15669
|
});
|
|
15459
|
-
const _hoisted_1$
|
|
15460
|
-
const _hoisted_2$
|
|
15461
|
-
const _hoisted_3$
|
|
15462
|
-
const _hoisted_4$
|
|
15463
|
-
const _hoisted_5$
|
|
15670
|
+
const _hoisted_1$9 = { key: 0 };
|
|
15671
|
+
const _hoisted_2$6 = { key: 0 };
|
|
15672
|
+
const _hoisted_3$5 = { key: 0 };
|
|
15673
|
+
const _hoisted_4$3 = { key: 1 };
|
|
15674
|
+
const _hoisted_5$3 = { key: 2 };
|
|
15464
15675
|
const _hoisted_6$1 = { key: 1 };
|
|
15465
15676
|
const _hoisted_7 = { key: 1 };
|
|
15466
15677
|
const _hoisted_8 = {
|
|
@@ -15498,7 +15709,7 @@ const _hoisted_27 = ["innerHTML"];
|
|
|
15498
15709
|
const _hoisted_28 = { key: 16 };
|
|
15499
15710
|
const _hoisted_29 = { key: 17 };
|
|
15500
15711
|
const _hoisted_30 = { key: 18 };
|
|
15501
|
-
const _sfc_main$
|
|
15712
|
+
const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
15502
15713
|
__name: "MdTokenRenderer",
|
|
15503
15714
|
props: {
|
|
15504
15715
|
token: {
|
|
@@ -15565,21 +15776,21 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
15565
15776
|
});
|
|
15566
15777
|
return (_ctx, _cache) => {
|
|
15567
15778
|
const _component_md_token_renderer = resolveComponent("md-token-renderer", true);
|
|
15568
|
-
return isText(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_1$
|
|
15569
|
-
!__props.token.tokens || __props.token.tokens.length === 0 ? (openBlock(), createElementBlock("span", _hoisted_2$
|
|
15570
|
-
isComponent$1(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_3$
|
|
15779
|
+
return isText(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_1$9, [
|
|
15780
|
+
!__props.token.tokens || __props.token.tokens.length === 0 ? (openBlock(), createElementBlock("span", _hoisted_2$6, [
|
|
15781
|
+
isComponent$1(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_3$5, [
|
|
15571
15782
|
!__props.last ? (openBlock(), createBlock(resolveDynamicComponent(getComponent(parsedComponent(__props.token).is)), {
|
|
15572
15783
|
key: 0,
|
|
15573
15784
|
text: parsedComponent(__props.token).text
|
|
15574
15785
|
}, null, 8, ["text"])) : createCommentVNode("", true)
|
|
15575
|
-
])) : containsComponent$1(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_4$
|
|
15786
|
+
])) : containsComponent$1(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_4$3, [
|
|
15576
15787
|
(openBlock(true), createElementBlock(Fragment, null, renderList(splitTextToken$1(__props.token), (subTok, j) => {
|
|
15577
15788
|
return openBlock(), createBlock(_component_md_token_renderer, {
|
|
15578
15789
|
key: j,
|
|
15579
15790
|
token: subTok
|
|
15580
15791
|
}, null, 8, ["token"]);
|
|
15581
15792
|
}), 128))
|
|
15582
|
-
])) : (openBlock(), createElementBlock("span", _hoisted_5$
|
|
15793
|
+
])) : (openBlock(), createElementBlock("span", _hoisted_5$3, toDisplayString(decodeBasicEntities(__props.token.text)), 1))
|
|
15583
15794
|
])) : __props.token.tokens && __props.token.tokens.length !== 0 ? (openBlock(), createElementBlock("span", _hoisted_6$1, [
|
|
15584
15795
|
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.token.tokens, (subTok, j) => {
|
|
15585
15796
|
return openBlock(), createBlock(_component_md_token_renderer, {
|
|
@@ -15712,7 +15923,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
15712
15923
|
], 8, _hoisted_25)) : __props.token.type === "html" ? (openBlock(), createElementBlock("span", {
|
|
15713
15924
|
key: 13,
|
|
15714
15925
|
innerHTML: __props.token.raw
|
|
15715
|
-
}, null, 8, _hoisted_26)) : __props.token.type === "code" ? (openBlock(), createBlock(_sfc_main$
|
|
15926
|
+
}, null, 8, _hoisted_26)) : __props.token.type === "code" ? (openBlock(), createBlock(_sfc_main$d, {
|
|
15716
15927
|
key: 14,
|
|
15717
15928
|
code: __props.token.text,
|
|
15718
15929
|
language: __props.token.lang
|
|
@@ -15738,8 +15949,8 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
|
15738
15949
|
};
|
|
15739
15950
|
}
|
|
15740
15951
|
});
|
|
15741
|
-
const MdTokenRenderer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
15742
|
-
const _sfc_main$
|
|
15952
|
+
const MdTokenRenderer = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["__scopeId", "data-v-047d0fa4"]]);
|
|
15953
|
+
const _sfc_main$b = defineComponent({
|
|
15743
15954
|
name: "MarkdownRenderer",
|
|
15744
15955
|
components: {
|
|
15745
15956
|
MdTokenRenderer,
|
|
@@ -15757,7 +15968,7 @@ const _sfc_main$8 = defineComponent({
|
|
|
15757
15968
|
}
|
|
15758
15969
|
}
|
|
15759
15970
|
});
|
|
15760
|
-
function _sfc_render$
|
|
15971
|
+
function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
|
|
15761
15972
|
const _component_md_token_renderer = resolveComponent("md-token-renderer");
|
|
15762
15973
|
const _component_audio_auto_player = resolveComponent("audio-auto-player");
|
|
15763
15974
|
return openBlock(), createElementBlock("div", null, [
|
|
@@ -15775,7 +15986,7 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
15775
15986
|
}), 128))
|
|
15776
15987
|
]);
|
|
15777
15988
|
}
|
|
15778
|
-
const MarkdownRenderer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
15989
|
+
const MarkdownRenderer = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$8]]);
|
|
15779
15990
|
const MarkdownRenderer$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
15780
15991
|
__proto__: null,
|
|
15781
15992
|
default: MarkdownRenderer
|
|
@@ -15815,11 +16026,14 @@ const useAuthStore = () => {
|
|
|
15815
16026
|
async init() {
|
|
15816
16027
|
try {
|
|
15817
16028
|
this._user = getDataLayer().getUserDB();
|
|
15818
|
-
this.loginAndRegistration.loggedIn = this._user.isLoggedIn();
|
|
16029
|
+
this.loginAndRegistration.loggedIn = this._user ? this._user.isLoggedIn() : false;
|
|
15819
16030
|
this.onLoadComplete = true;
|
|
15820
16031
|
this.loginAndRegistration.init = true;
|
|
15821
16032
|
} catch (e) {
|
|
15822
16033
|
console.error("Failed to initialize auth store:", e);
|
|
16034
|
+
this.loginAndRegistration.loggedIn = false;
|
|
16035
|
+
this.onLoadComplete = true;
|
|
16036
|
+
this.loginAndRegistration.init = true;
|
|
15823
16037
|
}
|
|
15824
16038
|
},
|
|
15825
16039
|
setLoginDialog(open) {
|
|
@@ -15880,29 +16094,43 @@ const useConfigStore = () => {
|
|
|
15880
16094
|
async updateDarkMode(darkMode) {
|
|
15881
16095
|
this.config.darkMode = darkMode;
|
|
15882
16096
|
const user = await getCurrentUser();
|
|
15883
|
-
|
|
15884
|
-
|
|
15885
|
-
|
|
16097
|
+
if (user) {
|
|
16098
|
+
await user.setConfig({
|
|
16099
|
+
darkMode
|
|
16100
|
+
});
|
|
16101
|
+
}
|
|
15886
16102
|
},
|
|
15887
16103
|
async updateLikesConfetti(likesConfetti) {
|
|
15888
16104
|
this.config.likesConfetti = likesConfetti;
|
|
15889
16105
|
const user = await getCurrentUser();
|
|
15890
|
-
|
|
15891
|
-
|
|
15892
|
-
|
|
16106
|
+
if (user) {
|
|
16107
|
+
await user.setConfig({
|
|
16108
|
+
likesConfetti
|
|
16109
|
+
});
|
|
16110
|
+
}
|
|
15893
16111
|
},
|
|
15894
16112
|
async updateSessionTimeLimit(sessionTimeLimit) {
|
|
15895
16113
|
this.config.sessionTimeLimit = sessionTimeLimit;
|
|
15896
16114
|
const user = await getCurrentUser();
|
|
15897
|
-
|
|
15898
|
-
|
|
15899
|
-
|
|
16115
|
+
if (user) {
|
|
16116
|
+
await user.setConfig({
|
|
16117
|
+
sessionTimeLimit
|
|
16118
|
+
});
|
|
16119
|
+
}
|
|
15900
16120
|
},
|
|
15901
16121
|
async hydrate() {
|
|
15902
|
-
|
|
15903
|
-
|
|
15904
|
-
|
|
15905
|
-
|
|
16122
|
+
try {
|
|
16123
|
+
const user = await getCurrentUser();
|
|
16124
|
+
if (user) {
|
|
16125
|
+
const cfg = await user.getConfig();
|
|
16126
|
+
console.log(`user config: ${JSON.stringify(cfg)}`);
|
|
16127
|
+
this.updateConfig(cfg);
|
|
16128
|
+
} else {
|
|
16129
|
+
console.log("No user logged in, using default config");
|
|
16130
|
+
}
|
|
16131
|
+
} catch (e) {
|
|
16132
|
+
console.warn("Failed to hydrate config store, using defaults:", e);
|
|
16133
|
+
}
|
|
15906
16134
|
},
|
|
15907
16135
|
async init() {
|
|
15908
16136
|
await this.hydrate();
|
|
@@ -15964,7 +16192,7 @@ function useAuthUI() {
|
|
|
15964
16192
|
detectSyncStrategy
|
|
15965
16193
|
};
|
|
15966
16194
|
}
|
|
15967
|
-
const _sfc_main$
|
|
16195
|
+
const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
15968
16196
|
__name: "UserChip",
|
|
15969
16197
|
props: {
|
|
15970
16198
|
showLoginButton: { type: Boolean },
|
|
@@ -16277,13 +16505,15 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
|
16277
16505
|
};
|
|
16278
16506
|
}
|
|
16279
16507
|
});
|
|
16280
|
-
const UserChip = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
16281
|
-
const
|
|
16508
|
+
const UserChip = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-9a38a213"]]);
|
|
16509
|
+
const _hoisted_1$8 = { class: "d-flex flex-column align-start" };
|
|
16510
|
+
const _hoisted_2$5 = { class: "mb-2" };
|
|
16511
|
+
const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
16282
16512
|
__name: "UserLogin",
|
|
16283
16513
|
props: {
|
|
16284
16514
|
redirectTo: { default: "/study" }
|
|
16285
16515
|
},
|
|
16286
|
-
emits: ["toggle", "loginSuccess"],
|
|
16516
|
+
emits: ["toggle", "loginSuccess", "forgotPassword"],
|
|
16287
16517
|
setup(__props, { emit: __emit }) {
|
|
16288
16518
|
const props = __props;
|
|
16289
16519
|
const emit = __emit;
|
|
@@ -16347,6 +16577,14 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
|
16347
16577
|
log("Toggling registration / login forms.");
|
|
16348
16578
|
emit("toggle");
|
|
16349
16579
|
};
|
|
16580
|
+
const handleForgotPassword = () => {
|
|
16581
|
+
log("Forgot password clicked");
|
|
16582
|
+
if (loginRoute.value) {
|
|
16583
|
+
router.push("/request-reset");
|
|
16584
|
+
} else {
|
|
16585
|
+
emit("forgotPassword");
|
|
16586
|
+
}
|
|
16587
|
+
};
|
|
16350
16588
|
return (_ctx, _cache) => {
|
|
16351
16589
|
const _component_v_card_title = resolveComponent("v-card-title");
|
|
16352
16590
|
const _component_v_text_field = resolveComponent("v-text-field");
|
|
@@ -16418,68 +16656,96 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
|
16418
16656
|
]),
|
|
16419
16657
|
_: 1
|
|
16420
16658
|
}, 8, ["modelValue", "timeout"]),
|
|
16421
|
-
|
|
16422
|
-
|
|
16423
|
-
|
|
16424
|
-
|
|
16425
|
-
|
|
16426
|
-
|
|
16427
|
-
|
|
16428
|
-
|
|
16429
|
-
default: withCtx(() =>
|
|
16430
|
-
|
|
16431
|
-
|
|
16659
|
+
createElementVNode("div", _hoisted_1$8, [
|
|
16660
|
+
createElementVNode("div", _hoisted_2$5, [
|
|
16661
|
+
createVNode(_component_v_btn, {
|
|
16662
|
+
class: "mr-2",
|
|
16663
|
+
type: "submit",
|
|
16664
|
+
loading: awaitingResponse.value,
|
|
16665
|
+
color: buttonStatus.value.color
|
|
16666
|
+
}, {
|
|
16667
|
+
default: withCtx(() => [
|
|
16668
|
+
createVNode(_component_v_icon, { start: "" }, {
|
|
16669
|
+
default: withCtx(() => _cache[8] || (_cache[8] = [
|
|
16670
|
+
createTextVNode("mdi-lock-open")
|
|
16671
|
+
])),
|
|
16672
|
+
_: 1
|
|
16673
|
+
}),
|
|
16674
|
+
_cache[9] || (_cache[9] = createTextVNode(" Log In "))
|
|
16675
|
+
]),
|
|
16432
16676
|
_: 1
|
|
16433
|
-
}),
|
|
16434
|
-
|
|
16435
|
-
|
|
16436
|
-
|
|
16437
|
-
|
|
16438
|
-
|
|
16439
|
-
|
|
16440
|
-
|
|
16441
|
-
|
|
16442
|
-
|
|
16443
|
-
|
|
16444
|
-
|
|
16677
|
+
}, 8, ["loading", "color"]),
|
|
16678
|
+
loginRoute.value ? (openBlock(), createBlock(_component_router_link, {
|
|
16679
|
+
key: 0,
|
|
16680
|
+
to: "signup"
|
|
16681
|
+
}, {
|
|
16682
|
+
default: withCtx(() => [
|
|
16683
|
+
createVNode(_component_v_btn, { variant: "text" }, {
|
|
16684
|
+
default: withCtx(() => _cache[10] || (_cache[10] = [
|
|
16685
|
+
createTextVNode("Create New Account")
|
|
16686
|
+
])),
|
|
16687
|
+
_: 1
|
|
16688
|
+
})
|
|
16689
|
+
]),
|
|
16690
|
+
_: 1
|
|
16691
|
+
})) : (openBlock(), createBlock(_component_v_btn, {
|
|
16692
|
+
key: 1,
|
|
16693
|
+
variant: "text",
|
|
16694
|
+
onClick: toggle
|
|
16695
|
+
}, {
|
|
16696
|
+
default: withCtx(() => _cache[11] || (_cache[11] = [
|
|
16445
16697
|
createTextVNode("Create New Account")
|
|
16446
16698
|
])),
|
|
16447
16699
|
_: 1
|
|
16448
|
-
})
|
|
16700
|
+
}))
|
|
16449
16701
|
]),
|
|
16450
|
-
|
|
16451
|
-
|
|
16452
|
-
|
|
16453
|
-
|
|
16454
|
-
|
|
16455
|
-
|
|
16456
|
-
|
|
16457
|
-
|
|
16458
|
-
])),
|
|
16459
|
-
_: 1
|
|
16460
|
-
}))
|
|
16702
|
+
renderSlot(_ctx.$slots, "forgot-password", {}, () => [
|
|
16703
|
+
createElementVNode("a", {
|
|
16704
|
+
href: "#",
|
|
16705
|
+
class: "text-caption text-decoration-none",
|
|
16706
|
+
onClick: withModifiers(handleForgotPassword, ["prevent"])
|
|
16707
|
+
}, " Forgot password? ")
|
|
16708
|
+
], true)
|
|
16709
|
+
])
|
|
16461
16710
|
]),
|
|
16462
|
-
_:
|
|
16711
|
+
_: 3
|
|
16463
16712
|
})
|
|
16464
16713
|
]),
|
|
16465
|
-
_:
|
|
16714
|
+
_: 3
|
|
16466
16715
|
})
|
|
16467
16716
|
]),
|
|
16468
|
-
_:
|
|
16717
|
+
_: 3
|
|
16469
16718
|
});
|
|
16470
16719
|
};
|
|
16471
16720
|
}
|
|
16472
16721
|
});
|
|
16473
|
-
const UserLogin = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
16474
|
-
|
|
16722
|
+
const UserLogin = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-563b0048"]]);
|
|
16723
|
+
function validatePassword(password) {
|
|
16724
|
+
if (!password) return "";
|
|
16725
|
+
if (password.length < 6) {
|
|
16726
|
+
return "Password must be at least 6 characters";
|
|
16727
|
+
}
|
|
16728
|
+
const uniqueChars = new Set(password).size;
|
|
16729
|
+
if (uniqueChars < 2) {
|
|
16730
|
+
return "Password must contain at least 2 different characters";
|
|
16731
|
+
}
|
|
16732
|
+
return "";
|
|
16733
|
+
}
|
|
16734
|
+
function isPasswordValid(password) {
|
|
16735
|
+
return validatePassword(password) === "";
|
|
16736
|
+
}
|
|
16737
|
+
const _sfc_main$8 = defineComponent({
|
|
16475
16738
|
name: "UserRegistration",
|
|
16476
|
-
emits: ["toggle"],
|
|
16739
|
+
emits: ["toggle", "signup-success"],
|
|
16477
16740
|
data() {
|
|
16478
16741
|
return {
|
|
16742
|
+
email: "",
|
|
16479
16743
|
username: "",
|
|
16480
16744
|
password: "",
|
|
16481
16745
|
retypedPassword: "",
|
|
16482
16746
|
passwordVisible: false,
|
|
16747
|
+
emailError: false,
|
|
16748
|
+
emailHint: "",
|
|
16483
16749
|
usernameValidationInProgress: false,
|
|
16484
16750
|
usernameError: false,
|
|
16485
16751
|
usernameHint: "",
|
|
@@ -16504,6 +16770,9 @@ const _sfc_main$5 = defineComponent({
|
|
|
16504
16770
|
color: this.badLoginAttempt ? "error" : "success",
|
|
16505
16771
|
text: this.badLoginAttempt ? "Try again" : "Log In"
|
|
16506
16772
|
};
|
|
16773
|
+
},
|
|
16774
|
+
passwordError() {
|
|
16775
|
+
return validatePassword(this.password);
|
|
16507
16776
|
}
|
|
16508
16777
|
},
|
|
16509
16778
|
async created() {
|
|
@@ -16514,11 +16783,29 @@ const _sfc_main$5 = defineComponent({
|
|
|
16514
16783
|
log("Toggling registration / login forms.");
|
|
16515
16784
|
this.$emit("toggle");
|
|
16516
16785
|
},
|
|
16786
|
+
validateEmail() {
|
|
16787
|
+
this.emailError = false;
|
|
16788
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
16789
|
+
if (this.email && !emailRegex.test(this.email)) {
|
|
16790
|
+
this.emailError = true;
|
|
16791
|
+
this.emailHint = "Please enter a valid email address";
|
|
16792
|
+
} else {
|
|
16793
|
+
this.emailHint = "";
|
|
16794
|
+
}
|
|
16795
|
+
},
|
|
16517
16796
|
validateUsername() {
|
|
16518
16797
|
this.usernameError = false;
|
|
16519
16798
|
},
|
|
16520
16799
|
async createUser() {
|
|
16521
16800
|
this.awaitingResponse = true;
|
|
16801
|
+
if (this.passwordError) {
|
|
16802
|
+
alertUser({
|
|
16803
|
+
text: this.passwordError,
|
|
16804
|
+
status: Status.error
|
|
16805
|
+
});
|
|
16806
|
+
this.awaitingResponse = false;
|
|
16807
|
+
return;
|
|
16808
|
+
}
|
|
16522
16809
|
log(`
|
|
16523
16810
|
User creation
|
|
16524
16811
|
-------------
|
|
@@ -16529,13 +16816,36 @@ Teacher: ${this.teacher}
|
|
|
16529
16816
|
Author: ${this.author}
|
|
16530
16817
|
`);
|
|
16531
16818
|
if (this.password === this.retypedPassword) {
|
|
16532
|
-
if (!this.user)
|
|
16819
|
+
if (!this.user) {
|
|
16820
|
+
console.error("ERROR: No user object available");
|
|
16821
|
+
return;
|
|
16822
|
+
}
|
|
16533
16823
|
this.user.createAccount(this.username, this.password).then(async (resp) => {
|
|
16534
16824
|
if (resp.status === Status.ok) {
|
|
16535
16825
|
this.authStore.loginAndRegistration.loggedIn = true;
|
|
16536
16826
|
this.authStore.loginAndRegistration.init = false;
|
|
16537
16827
|
this.authStore.loginAndRegistration.init = true;
|
|
16538
|
-
|
|
16828
|
+
if (this.email) {
|
|
16829
|
+
try {
|
|
16830
|
+
const currentUser = await getCurrentUser();
|
|
16831
|
+
await currentUser.setConfig({ email: this.email });
|
|
16832
|
+
const origin = typeof window !== "undefined" ? window.location.origin : void 0;
|
|
16833
|
+
const verificationResult = await sendVerificationEmail(this.username, this.email, origin);
|
|
16834
|
+
if (verificationResult.ok) {
|
|
16835
|
+
alertUser({
|
|
16836
|
+
text: "Account created! Please check your email to verify your account.",
|
|
16837
|
+
status: Status.ok
|
|
16838
|
+
});
|
|
16839
|
+
} else {
|
|
16840
|
+
log(`Warning: Failed to send verification email: ${verificationResult.error}`);
|
|
16841
|
+
}
|
|
16842
|
+
} catch (emailError) {
|
|
16843
|
+
console.error("Email save/send error:", emailError);
|
|
16844
|
+
log(`Warning: Failed to save email or send verification: ${emailError}`);
|
|
16845
|
+
}
|
|
16846
|
+
}
|
|
16847
|
+
const username = (await getCurrentUser()).getUsername();
|
|
16848
|
+
this.$emit("signup-success", { username });
|
|
16539
16849
|
} else {
|
|
16540
16850
|
if (resp.error === "This username is taken!") {
|
|
16541
16851
|
this.usernameError = true;
|
|
@@ -16553,11 +16863,14 @@ Author: ${this.author}
|
|
|
16553
16863
|
}
|
|
16554
16864
|
}
|
|
16555
16865
|
}).catch((e) => {
|
|
16556
|
-
|
|
16866
|
+
console.error("createAccount error:", e);
|
|
16867
|
+
if (e) {
|
|
16868
|
+
const errorText = e?.message || e?.error || e?.toString() || "Account creation failed";
|
|
16557
16869
|
alertUser({
|
|
16558
|
-
text:
|
|
16870
|
+
text: errorText,
|
|
16559
16871
|
status: Status.error
|
|
16560
16872
|
});
|
|
16873
|
+
}
|
|
16561
16874
|
});
|
|
16562
16875
|
this.awaitingResponse = false;
|
|
16563
16876
|
} else {
|
|
@@ -16570,7 +16883,7 @@ Author: ${this.author}
|
|
|
16570
16883
|
}
|
|
16571
16884
|
}
|
|
16572
16885
|
});
|
|
16573
|
-
function _sfc_render$
|
|
16886
|
+
function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
|
|
16574
16887
|
const _component_v_card_title = resolveComponent("v-card-title");
|
|
16575
16888
|
const _component_v_text_field = resolveComponent("v-text-field");
|
|
16576
16889
|
const _component_v_btn = resolveComponent("v-btn");
|
|
@@ -16586,7 +16899,7 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
16586
16899
|
key: 0,
|
|
16587
16900
|
class: "text-h5 bg-grey-lighten-2"
|
|
16588
16901
|
}, {
|
|
16589
|
-
default: withCtx(() => _cache[
|
|
16902
|
+
default: withCtx(() => _cache[7] || (_cache[7] = [
|
|
16590
16903
|
createTextVNode(" Create an Account ")
|
|
16591
16904
|
])),
|
|
16592
16905
|
_: 1
|
|
@@ -16597,12 +16910,22 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
16597
16910
|
onSubmit: withModifiers(_ctx.createUser, ["prevent"])
|
|
16598
16911
|
}, {
|
|
16599
16912
|
default: withCtx(() => [
|
|
16913
|
+
createVNode(_component_v_text_field, {
|
|
16914
|
+
modelValue: _ctx.email,
|
|
16915
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.email = $event),
|
|
16916
|
+
name: "email",
|
|
16917
|
+
label: "Email address",
|
|
16918
|
+
type: "email",
|
|
16919
|
+
"prepend-icon": "mdi-email",
|
|
16920
|
+
error: _ctx.emailError,
|
|
16921
|
+
hint: _ctx.emailHint,
|
|
16922
|
+
onBlur: _ctx.validateEmail
|
|
16923
|
+
}, null, 8, ["modelValue", "error", "hint", "onBlur"]),
|
|
16600
16924
|
createVNode(_component_v_text_field, {
|
|
16601
16925
|
id: "",
|
|
16602
16926
|
ref: "userNameTextField",
|
|
16603
16927
|
modelValue: _ctx.username,
|
|
16604
|
-
"onUpdate:modelValue": _cache[
|
|
16605
|
-
autofocus: "",
|
|
16928
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.username = $event),
|
|
16606
16929
|
name: "username",
|
|
16607
16930
|
label: "Choose a Username",
|
|
16608
16931
|
"prepend-icon": "mdi-account-circle",
|
|
@@ -16612,20 +16935,21 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
16612
16935
|
}, null, 8, ["modelValue", "error", "hint", "onBlur"]),
|
|
16613
16936
|
createVNode(_component_v_text_field, {
|
|
16614
16937
|
modelValue: _ctx.password,
|
|
16615
|
-
"onUpdate:modelValue": _cache[
|
|
16938
|
+
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => _ctx.password = $event),
|
|
16616
16939
|
"prepend-icon": "mdi-lock",
|
|
16617
16940
|
name: "password",
|
|
16618
16941
|
hover: "Show password",
|
|
16619
16942
|
label: "Create a password",
|
|
16620
|
-
hint:
|
|
16943
|
+
hint: _ctx.passwordError,
|
|
16944
|
+
error: !!_ctx.passwordError,
|
|
16621
16945
|
min: "4",
|
|
16622
16946
|
"append-icon": _ctx.passwordVisible ? "mdi-eye-off" : "mdi-eye",
|
|
16623
16947
|
type: _ctx.passwordVisible ? "text" : "password",
|
|
16624
|
-
"onClick:append": _cache[
|
|
16625
|
-
}, null, 8, ["modelValue", "append-icon", "type"]),
|
|
16948
|
+
"onClick:append": _cache[3] || (_cache[3] = () => _ctx.passwordVisible = !_ctx.passwordVisible)
|
|
16949
|
+
}, null, 8, ["modelValue", "hint", "error", "append-icon", "type"]),
|
|
16626
16950
|
createVNode(_component_v_text_field, {
|
|
16627
16951
|
modelValue: _ctx.retypedPassword,
|
|
16628
|
-
"onUpdate:modelValue": _cache[
|
|
16952
|
+
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => _ctx.retypedPassword = $event),
|
|
16629
16953
|
"prepend-icon": "mdi-lock",
|
|
16630
16954
|
name: "retypedPassword",
|
|
16631
16955
|
hover: "Show password",
|
|
@@ -16636,18 +16960,18 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
16636
16960
|
}, null, 8, ["modelValue", "type"]),
|
|
16637
16961
|
createVNode(_component_v_snackbar, {
|
|
16638
16962
|
modelValue: _ctx.badLoginAttempt,
|
|
16639
|
-
"onUpdate:modelValue": _cache[
|
|
16963
|
+
"onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => _ctx.badLoginAttempt = $event),
|
|
16640
16964
|
location: "bottom right",
|
|
16641
16965
|
timeout: 5e3
|
|
16642
16966
|
}, {
|
|
16643
16967
|
default: withCtx(() => [
|
|
16644
|
-
_cache[
|
|
16968
|
+
_cache[9] || (_cache[9] = createTextVNode(" Username or password was incorrect. ")),
|
|
16645
16969
|
createVNode(_component_v_btn, {
|
|
16646
16970
|
color: "pink",
|
|
16647
16971
|
variant: "text",
|
|
16648
|
-
onClick: _cache[
|
|
16972
|
+
onClick: _cache[5] || (_cache[5] = ($event) => _ctx.badLoginAttempt = false)
|
|
16649
16973
|
}, {
|
|
16650
|
-
default: withCtx(() => _cache[
|
|
16974
|
+
default: withCtx(() => _cache[8] || (_cache[8] = [
|
|
16651
16975
|
createTextVNode(" Close ")
|
|
16652
16976
|
])),
|
|
16653
16977
|
_: 1
|
|
@@ -16659,26 +16983,27 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
16659
16983
|
class: "mr-2",
|
|
16660
16984
|
type: "submit",
|
|
16661
16985
|
loading: _ctx.awaitingResponse,
|
|
16662
|
-
color: _ctx.buttonStatus.color
|
|
16986
|
+
color: _ctx.buttonStatus.color,
|
|
16987
|
+
disabled: !!_ctx.passwordError || _ctx.password !== _ctx.retypedPassword
|
|
16663
16988
|
}, {
|
|
16664
16989
|
default: withCtx(() => [
|
|
16665
16990
|
createVNode(_component_v_icon, { start: "" }, {
|
|
16666
|
-
default: withCtx(() => _cache[
|
|
16991
|
+
default: withCtx(() => _cache[10] || (_cache[10] = [
|
|
16667
16992
|
createTextVNode("mdi-lock-open")
|
|
16668
16993
|
])),
|
|
16669
16994
|
_: 1
|
|
16670
16995
|
}),
|
|
16671
|
-
_cache[
|
|
16996
|
+
_cache[11] || (_cache[11] = createTextVNode(" Create Account "))
|
|
16672
16997
|
]),
|
|
16673
16998
|
_: 1
|
|
16674
|
-
}, 8, ["loading", "color"]),
|
|
16999
|
+
}, 8, ["loading", "color", "disabled"]),
|
|
16675
17000
|
_ctx.registrationRoute ? (openBlock(), createBlock(_component_router_link, {
|
|
16676
17001
|
key: 0,
|
|
16677
17002
|
to: "login"
|
|
16678
17003
|
}, {
|
|
16679
17004
|
default: withCtx(() => [
|
|
16680
17005
|
createVNode(_component_v_btn, { variant: "text" }, {
|
|
16681
|
-
default: withCtx(() => _cache[
|
|
17006
|
+
default: withCtx(() => _cache[12] || (_cache[12] = [
|
|
16682
17007
|
createTextVNode("Log In")
|
|
16683
17008
|
])),
|
|
16684
17009
|
_: 1
|
|
@@ -16690,7 +17015,7 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
16690
17015
|
variant: "text",
|
|
16691
17016
|
onClick: _ctx.toggle
|
|
16692
17017
|
}, {
|
|
16693
|
-
default: withCtx(() => _cache[
|
|
17018
|
+
default: withCtx(() => _cache[13] || (_cache[13] = [
|
|
16694
17019
|
createTextVNode(" Log In ")
|
|
16695
17020
|
])),
|
|
16696
17021
|
_: 1
|
|
@@ -16705,17 +17030,178 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
16705
17030
|
_: 1
|
|
16706
17031
|
});
|
|
16707
17032
|
}
|
|
16708
|
-
const UserRegistration = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
16709
|
-
const
|
|
16710
|
-
|
|
16711
|
-
|
|
16712
|
-
|
|
17033
|
+
const UserRegistration = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$7]]);
|
|
17034
|
+
const _sfc_main$7 = defineComponent({
|
|
17035
|
+
name: "RequestPasswordReset",
|
|
17036
|
+
emits: ["cancel", "success"],
|
|
17037
|
+
data() {
|
|
17038
|
+
return {
|
|
17039
|
+
email: "",
|
|
17040
|
+
emailError: false,
|
|
17041
|
+
emailHint: "",
|
|
17042
|
+
isSubmitting: false,
|
|
17043
|
+
requestSent: false
|
|
17044
|
+
};
|
|
17045
|
+
},
|
|
17046
|
+
methods: {
|
|
17047
|
+
validateEmail() {
|
|
17048
|
+
this.emailError = false;
|
|
17049
|
+
this.emailHint = "";
|
|
17050
|
+
if (!this.email) return;
|
|
17051
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
17052
|
+
if (!emailRegex.test(this.email)) {
|
|
17053
|
+
this.emailError = true;
|
|
17054
|
+
this.emailHint = "Please enter a valid email address";
|
|
17055
|
+
}
|
|
17056
|
+
},
|
|
17057
|
+
async handleSubmit() {
|
|
17058
|
+
this.validateEmail();
|
|
17059
|
+
if (this.emailError || !this.email) {
|
|
17060
|
+
return;
|
|
17061
|
+
}
|
|
17062
|
+
this.isSubmitting = true;
|
|
17063
|
+
try {
|
|
17064
|
+
const origin = typeof window !== "undefined" ? window.location.origin : void 0;
|
|
17065
|
+
const result = await requestPasswordReset(this.email, origin);
|
|
17066
|
+
if (result.ok) {
|
|
17067
|
+
this.requestSent = true;
|
|
17068
|
+
this.$emit("success", this.email);
|
|
17069
|
+
} else {
|
|
17070
|
+
alertUser({
|
|
17071
|
+
text: result.error || "Failed to send reset email",
|
|
17072
|
+
status: Status.error
|
|
17073
|
+
});
|
|
17074
|
+
}
|
|
17075
|
+
} catch (error) {
|
|
17076
|
+
alertUser({
|
|
17077
|
+
text: "An unexpected error occurred",
|
|
17078
|
+
status: Status.error
|
|
17079
|
+
});
|
|
17080
|
+
} finally {
|
|
17081
|
+
this.isSubmitting = false;
|
|
17082
|
+
}
|
|
17083
|
+
}
|
|
17084
|
+
}
|
|
17085
|
+
});
|
|
17086
|
+
const _hoisted_1$7 = {
|
|
17087
|
+
key: 1,
|
|
17088
|
+
class: "text-center"
|
|
17089
|
+
};
|
|
17090
|
+
function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
|
|
17091
|
+
const _component_v_card_title = resolveComponent("v-card-title");
|
|
17092
|
+
const _component_v_text_field = resolveComponent("v-text-field");
|
|
17093
|
+
const _component_v_icon = resolveComponent("v-icon");
|
|
17094
|
+
const _component_v_btn = resolveComponent("v-btn");
|
|
17095
|
+
const _component_v_form = resolveComponent("v-form");
|
|
17096
|
+
const _component_v_card_text = resolveComponent("v-card-text");
|
|
17097
|
+
const _component_v_spacer = resolveComponent("v-spacer");
|
|
17098
|
+
const _component_v_card_actions = resolveComponent("v-card-actions");
|
|
17099
|
+
const _component_v_card = resolveComponent("v-card");
|
|
17100
|
+
return openBlock(), createBlock(_component_v_card, null, {
|
|
17101
|
+
default: withCtx(() => [
|
|
17102
|
+
createVNode(_component_v_card_title, { class: "text-h5 bg-grey-lighten-2" }, {
|
|
17103
|
+
default: withCtx(() => _cache[2] || (_cache[2] = [
|
|
17104
|
+
createTextVNode(" Reset Password ")
|
|
17105
|
+
])),
|
|
17106
|
+
_: 1
|
|
17107
|
+
}),
|
|
17108
|
+
createVNode(_component_v_card_text, { class: "pa-6" }, {
|
|
17109
|
+
default: withCtx(() => [
|
|
17110
|
+
!_ctx.requestSent ? (openBlock(), createBlock(_component_v_form, {
|
|
17111
|
+
key: 0,
|
|
17112
|
+
onSubmit: withModifiers(_ctx.handleSubmit, ["prevent"])
|
|
17113
|
+
}, {
|
|
17114
|
+
default: withCtx(() => [
|
|
17115
|
+
_cache[5] || (_cache[5] = createElementVNode("p", { class: "mb-4" }, " Enter your email address and we'll send you a link to reset your password. ", -1)),
|
|
17116
|
+
createVNode(_component_v_text_field, {
|
|
17117
|
+
modelValue: _ctx.email,
|
|
17118
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.email = $event),
|
|
17119
|
+
name: "email",
|
|
17120
|
+
label: "Email address",
|
|
17121
|
+
type: "email",
|
|
17122
|
+
"prepend-icon": "mdi-email",
|
|
17123
|
+
error: _ctx.emailError,
|
|
17124
|
+
hint: _ctx.emailHint,
|
|
17125
|
+
disabled: _ctx.isSubmitting,
|
|
17126
|
+
onBlur: _ctx.validateEmail
|
|
17127
|
+
}, null, 8, ["modelValue", "error", "hint", "disabled", "onBlur"]),
|
|
17128
|
+
createVNode(_component_v_btn, {
|
|
17129
|
+
type: "submit",
|
|
17130
|
+
color: "primary",
|
|
17131
|
+
class: "mt-4",
|
|
17132
|
+
loading: _ctx.isSubmitting,
|
|
17133
|
+
disabled: !_ctx.email || _ctx.emailError,
|
|
17134
|
+
block: ""
|
|
17135
|
+
}, {
|
|
17136
|
+
default: withCtx(() => [
|
|
17137
|
+
createVNode(_component_v_icon, { start: "" }, {
|
|
17138
|
+
default: withCtx(() => _cache[3] || (_cache[3] = [
|
|
17139
|
+
createTextVNode("mdi-email-send")
|
|
17140
|
+
])),
|
|
17141
|
+
_: 1
|
|
17142
|
+
}),
|
|
17143
|
+
_cache[4] || (_cache[4] = createTextVNode(" Send Reset Link "))
|
|
17144
|
+
]),
|
|
17145
|
+
_: 1
|
|
17146
|
+
}, 8, ["loading", "disabled"])
|
|
17147
|
+
]),
|
|
17148
|
+
_: 1
|
|
17149
|
+
}, 8, ["onSubmit"])) : (openBlock(), createElementBlock("div", _hoisted_1$7, [
|
|
17150
|
+
createVNode(_component_v_icon, {
|
|
17151
|
+
color: "success",
|
|
17152
|
+
size: "64",
|
|
17153
|
+
class: "mb-4"
|
|
17154
|
+
}, {
|
|
17155
|
+
default: withCtx(() => _cache[6] || (_cache[6] = [
|
|
17156
|
+
createTextVNode("mdi-email-check")
|
|
17157
|
+
])),
|
|
17158
|
+
_: 1
|
|
17159
|
+
}),
|
|
17160
|
+
_cache[9] || (_cache[9] = createElementVNode("h3", { class: "mb-2" }, "Check Your Email", -1)),
|
|
17161
|
+
createElementVNode("p", null, [
|
|
17162
|
+
_cache[7] || (_cache[7] = createTextVNode(" If an account exists with ")),
|
|
17163
|
+
createElementVNode("strong", null, toDisplayString(_ctx.email), 1),
|
|
17164
|
+
_cache[8] || (_cache[8] = createTextVNode(", you will receive a password reset link shortly. "))
|
|
17165
|
+
]),
|
|
17166
|
+
_cache[10] || (_cache[10] = createElementVNode("p", { class: "text-caption mt-4" }, "Didn't receive an email? Check your spam folder.", -1))
|
|
17167
|
+
]))
|
|
17168
|
+
]),
|
|
17169
|
+
_: 1
|
|
17170
|
+
}),
|
|
17171
|
+
!_ctx.requestSent ? (openBlock(), createBlock(_component_v_card_actions, { key: 0 }, {
|
|
17172
|
+
default: withCtx(() => [
|
|
17173
|
+
renderSlot(_ctx.$slots, "back-action", {}, () => [
|
|
17174
|
+
createVNode(_component_v_btn, {
|
|
17175
|
+
variant: "text",
|
|
17176
|
+
onClick: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("cancel"))
|
|
17177
|
+
}, {
|
|
17178
|
+
default: withCtx(() => _cache[11] || (_cache[11] = [
|
|
17179
|
+
createTextVNode(" Cancel ")
|
|
17180
|
+
])),
|
|
17181
|
+
_: 1
|
|
17182
|
+
})
|
|
17183
|
+
]),
|
|
17184
|
+
createVNode(_component_v_spacer)
|
|
17185
|
+
]),
|
|
17186
|
+
_: 3
|
|
17187
|
+
})) : createCommentVNode("", true)
|
|
17188
|
+
]),
|
|
17189
|
+
_: 3
|
|
17190
|
+
});
|
|
17191
|
+
}
|
|
17192
|
+
const RequestPasswordReset = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$6]]);
|
|
17193
|
+
const _hoisted_1$6 = { key: 0 };
|
|
17194
|
+
const _hoisted_2$4 = { key: "login-buttons" };
|
|
17195
|
+
const _hoisted_3$4 = { key: "user-chip" };
|
|
17196
|
+
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
16713
17197
|
__name: "UserLoginAndRegistrationContainer",
|
|
16714
17198
|
props: {
|
|
16715
17199
|
showLoginButton: { type: Boolean },
|
|
16716
|
-
redirectToPath: {}
|
|
17200
|
+
redirectToPath: {},
|
|
17201
|
+
showRegistration: { type: Boolean }
|
|
16717
17202
|
},
|
|
16718
17203
|
setup(__props) {
|
|
17204
|
+
const props = __props;
|
|
16719
17205
|
const route = useRoute();
|
|
16720
17206
|
const authStore = useAuthStore();
|
|
16721
17207
|
const authUI = useAuthUI();
|
|
@@ -16736,12 +17222,18 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
16736
17222
|
}
|
|
16737
17223
|
return !authStore.loginAndRegistration.loggedIn;
|
|
16738
17224
|
});
|
|
16739
|
-
const authUIConfig = computed(() =>
|
|
16740
|
-
|
|
16741
|
-
|
|
16742
|
-
|
|
16743
|
-
|
|
16744
|
-
|
|
17225
|
+
const authUIConfig = computed(() => {
|
|
17226
|
+
const baseConfig2 = authUI.config.value || {
|
|
17227
|
+
showLoginRegistration: true,
|
|
17228
|
+
showLogout: true,
|
|
17229
|
+
showResetData: false,
|
|
17230
|
+
logoutLabel: "Log out",
|
|
17231
|
+
resetLabel: ""
|
|
17232
|
+
};
|
|
17233
|
+
return {
|
|
17234
|
+
...baseConfig2,
|
|
17235
|
+
...props.showRegistration !== void 0 && { showLoginRegistration: props.showRegistration }
|
|
17236
|
+
};
|
|
16745
17237
|
});
|
|
16746
17238
|
const regDialog = computed({
|
|
16747
17239
|
get: () => authStore.loginAndRegistration.regDialogOpen,
|
|
@@ -16755,6 +17247,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
16755
17247
|
authStore.loginAndRegistration.loginDialogOpen = value;
|
|
16756
17248
|
}
|
|
16757
17249
|
});
|
|
17250
|
+
const resetDialog = ref(false);
|
|
16758
17251
|
const toggle = () => {
|
|
16759
17252
|
if (regDialog.value && loginDialog.value) {
|
|
16760
17253
|
throw new Error("Registration / Login dialogs both activated.");
|
|
@@ -16765,17 +17258,25 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
16765
17258
|
loginDialog.value = !loginDialog.value;
|
|
16766
17259
|
}
|
|
16767
17260
|
};
|
|
17261
|
+
const openResetDialog = () => {
|
|
17262
|
+
loginDialog.value = false;
|
|
17263
|
+
resetDialog.value = true;
|
|
17264
|
+
};
|
|
17265
|
+
const closeResetDialog = () => {
|
|
17266
|
+
resetDialog.value = false;
|
|
17267
|
+
};
|
|
16768
17268
|
return (_ctx, _cache) => {
|
|
16769
17269
|
const _component_v_btn = resolveComponent("v-btn");
|
|
16770
17270
|
const _component_v_dialog = resolveComponent("v-dialog");
|
|
16771
|
-
return userReady.value && display.value ? (openBlock(), createElementBlock("div", _hoisted_1$
|
|
17271
|
+
return userReady.value && display.value ? (openBlock(), createElementBlock("div", _hoisted_1$6, [
|
|
16772
17272
|
createVNode(Transition, {
|
|
16773
17273
|
name: "component-fade",
|
|
16774
17274
|
mode: "out-in"
|
|
16775
17275
|
}, {
|
|
16776
17276
|
default: withCtx(() => [
|
|
16777
|
-
guestMode.value
|
|
16778
|
-
|
|
17277
|
+
guestMode.value ? (openBlock(), createElementBlock("div", _hoisted_2$4, [
|
|
17278
|
+
authUIConfig.value.showLoginRegistration ? (openBlock(), createBlock(_component_v_dialog, {
|
|
17279
|
+
key: 0,
|
|
16779
17280
|
modelValue: regDialog.value,
|
|
16780
17281
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => regDialog.value = $event),
|
|
16781
17282
|
width: "500px"
|
|
@@ -16786,7 +17287,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
16786
17287
|
size: "small",
|
|
16787
17288
|
color: "success"
|
|
16788
17289
|
}, props2), {
|
|
16789
|
-
default: withCtx(() => _cache[
|
|
17290
|
+
default: withCtx(() => _cache[3] || (_cache[3] = [
|
|
16790
17291
|
createTextVNode("Sign Up")
|
|
16791
17292
|
])),
|
|
16792
17293
|
_: 2
|
|
@@ -16796,7 +17297,7 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
16796
17297
|
createVNode(UserRegistration, { onToggle: toggle })
|
|
16797
17298
|
]),
|
|
16798
17299
|
_: 1
|
|
16799
|
-
}, 8, ["modelValue"]),
|
|
17300
|
+
}, 8, ["modelValue"])) : createCommentVNode("", true),
|
|
16800
17301
|
createVNode(_component_v_dialog, {
|
|
16801
17302
|
modelValue: loginDialog.value,
|
|
16802
17303
|
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => loginDialog.value = $event),
|
|
@@ -16807,18 +17308,34 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
16807
17308
|
size: "small",
|
|
16808
17309
|
color: "success"
|
|
16809
17310
|
}, props2), {
|
|
16810
|
-
default: withCtx(() => _cache[
|
|
17311
|
+
default: withCtx(() => _cache[4] || (_cache[4] = [
|
|
16811
17312
|
createTextVNode("Log In")
|
|
16812
17313
|
])),
|
|
16813
17314
|
_: 2
|
|
16814
17315
|
}, 1040)
|
|
16815
17316
|
]),
|
|
16816
17317
|
default: withCtx(() => [
|
|
16817
|
-
createVNode(UserLogin, {
|
|
17318
|
+
createVNode(UserLogin, {
|
|
17319
|
+
onToggle: toggle,
|
|
17320
|
+
onForgotPassword: openResetDialog
|
|
17321
|
+
})
|
|
17322
|
+
]),
|
|
17323
|
+
_: 1
|
|
17324
|
+
}, 8, ["modelValue"]),
|
|
17325
|
+
createVNode(_component_v_dialog, {
|
|
17326
|
+
modelValue: resetDialog.value,
|
|
17327
|
+
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => resetDialog.value = $event),
|
|
17328
|
+
width: "500px"
|
|
17329
|
+
}, {
|
|
17330
|
+
default: withCtx(() => [
|
|
17331
|
+
createVNode(RequestPasswordReset, {
|
|
17332
|
+
onCancel: closeResetDialog,
|
|
17333
|
+
onSuccess: closeResetDialog
|
|
17334
|
+
})
|
|
16818
17335
|
]),
|
|
16819
17336
|
_: 1
|
|
16820
17337
|
}, 8, ["modelValue"])
|
|
16821
|
-
])) : (openBlock(), createElementBlock("div", _hoisted_3$
|
|
17338
|
+
])) : (openBlock(), createElementBlock("div", _hoisted_3$4, [
|
|
16822
17339
|
createVNode(UserChip)
|
|
16823
17340
|
]))
|
|
16824
17341
|
]),
|
|
@@ -16828,7 +17345,453 @@ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
|
16828
17345
|
};
|
|
16829
17346
|
}
|
|
16830
17347
|
});
|
|
16831
|
-
const UserLoginAndRegistrationContainer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
17348
|
+
const UserLoginAndRegistrationContainer = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-efb42c02"]]);
|
|
17349
|
+
const _sfc_main$5 = defineComponent({
|
|
17350
|
+
name: "VerifyEmail",
|
|
17351
|
+
emits: ["verified", "error"],
|
|
17352
|
+
props: {
|
|
17353
|
+
/**
|
|
17354
|
+
* Verification token. If not provided, will try to read from URL query params.
|
|
17355
|
+
*/
|
|
17356
|
+
token: {
|
|
17357
|
+
type: String,
|
|
17358
|
+
default: null
|
|
17359
|
+
}
|
|
17360
|
+
},
|
|
17361
|
+
data() {
|
|
17362
|
+
return {
|
|
17363
|
+
isVerifying: false,
|
|
17364
|
+
verificationStatus: null,
|
|
17365
|
+
errorMessage: "",
|
|
17366
|
+
username: ""
|
|
17367
|
+
};
|
|
17368
|
+
},
|
|
17369
|
+
async mounted() {
|
|
17370
|
+
await this.performVerification();
|
|
17371
|
+
},
|
|
17372
|
+
methods: {
|
|
17373
|
+
async performVerification() {
|
|
17374
|
+
const token2 = this.token || this.getTokenFromURL();
|
|
17375
|
+
if (!token2) {
|
|
17376
|
+
this.verificationStatus = "error";
|
|
17377
|
+
this.errorMessage = "No verification token provided";
|
|
17378
|
+
return;
|
|
17379
|
+
}
|
|
17380
|
+
this.isVerifying = true;
|
|
17381
|
+
try {
|
|
17382
|
+
const result = await verifyEmail(token2);
|
|
17383
|
+
if (result.ok) {
|
|
17384
|
+
this.verificationStatus = "success";
|
|
17385
|
+
this.username = result.username || "";
|
|
17386
|
+
alertUser({
|
|
17387
|
+
text: "Email verified successfully!",
|
|
17388
|
+
status: Status.ok
|
|
17389
|
+
});
|
|
17390
|
+
} else {
|
|
17391
|
+
this.verificationStatus = "error";
|
|
17392
|
+
this.errorMessage = result.error || "Verification failed";
|
|
17393
|
+
alertUser({
|
|
17394
|
+
text: result.error || "Verification failed",
|
|
17395
|
+
status: Status.error
|
|
17396
|
+
});
|
|
17397
|
+
}
|
|
17398
|
+
} catch (error) {
|
|
17399
|
+
this.verificationStatus = "error";
|
|
17400
|
+
this.errorMessage = "An unexpected error occurred";
|
|
17401
|
+
alertUser({
|
|
17402
|
+
text: "An unexpected error occurred",
|
|
17403
|
+
status: Status.error
|
|
17404
|
+
});
|
|
17405
|
+
} finally {
|
|
17406
|
+
this.isVerifying = false;
|
|
17407
|
+
}
|
|
17408
|
+
},
|
|
17409
|
+
getTokenFromURL() {
|
|
17410
|
+
if (typeof window === "undefined") return null;
|
|
17411
|
+
const params = new URLSearchParams(window.location.search);
|
|
17412
|
+
return params.get("token");
|
|
17413
|
+
}
|
|
17414
|
+
}
|
|
17415
|
+
});
|
|
17416
|
+
const _hoisted_1$5 = {
|
|
17417
|
+
key: 0,
|
|
17418
|
+
class: "text-center"
|
|
17419
|
+
};
|
|
17420
|
+
const _hoisted_2$3 = {
|
|
17421
|
+
key: 1,
|
|
17422
|
+
class: "text-center"
|
|
17423
|
+
};
|
|
17424
|
+
const _hoisted_3$3 = { key: 0 };
|
|
17425
|
+
const _hoisted_4$2 = {
|
|
17426
|
+
key: 2,
|
|
17427
|
+
class: "text-center"
|
|
17428
|
+
};
|
|
17429
|
+
const _hoisted_5$2 = {
|
|
17430
|
+
key: 3,
|
|
17431
|
+
class: "text-center"
|
|
17432
|
+
};
|
|
17433
|
+
function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
|
|
17434
|
+
const _component_v_card_title = resolveComponent("v-card-title");
|
|
17435
|
+
const _component_v_progress_circular = resolveComponent("v-progress-circular");
|
|
17436
|
+
const _component_v_icon = resolveComponent("v-icon");
|
|
17437
|
+
const _component_v_card_text = resolveComponent("v-card-text");
|
|
17438
|
+
const _component_v_spacer = resolveComponent("v-spacer");
|
|
17439
|
+
const _component_v_btn = resolveComponent("v-btn");
|
|
17440
|
+
const _component_v_card_actions = resolveComponent("v-card-actions");
|
|
17441
|
+
const _component_v_card = resolveComponent("v-card");
|
|
17442
|
+
const _component_v_col = resolveComponent("v-col");
|
|
17443
|
+
const _component_v_row = resolveComponent("v-row");
|
|
17444
|
+
const _component_v_container = resolveComponent("v-container");
|
|
17445
|
+
return openBlock(), createBlock(_component_v_container, {
|
|
17446
|
+
class: "fill-height",
|
|
17447
|
+
fluid: ""
|
|
17448
|
+
}, {
|
|
17449
|
+
default: withCtx(() => [
|
|
17450
|
+
createVNode(_component_v_row, {
|
|
17451
|
+
align: "center",
|
|
17452
|
+
justify: "center"
|
|
17453
|
+
}, {
|
|
17454
|
+
default: withCtx(() => [
|
|
17455
|
+
createVNode(_component_v_col, {
|
|
17456
|
+
cols: "12",
|
|
17457
|
+
sm: "8",
|
|
17458
|
+
md: "6"
|
|
17459
|
+
}, {
|
|
17460
|
+
default: withCtx(() => [
|
|
17461
|
+
createVNode(_component_v_card, null, {
|
|
17462
|
+
default: withCtx(() => [
|
|
17463
|
+
createVNode(_component_v_card_title, { class: "text-h5 bg-grey-lighten-2" }, {
|
|
17464
|
+
default: withCtx(() => _cache[2] || (_cache[2] = [
|
|
17465
|
+
createTextVNode(" Email Verification ")
|
|
17466
|
+
])),
|
|
17467
|
+
_: 1
|
|
17468
|
+
}),
|
|
17469
|
+
createVNode(_component_v_card_text, { class: "pa-6" }, {
|
|
17470
|
+
default: withCtx(() => [
|
|
17471
|
+
_ctx.isVerifying ? (openBlock(), createElementBlock("div", _hoisted_1$5, [
|
|
17472
|
+
createVNode(_component_v_progress_circular, {
|
|
17473
|
+
indeterminate: "",
|
|
17474
|
+
color: "primary",
|
|
17475
|
+
size: "64",
|
|
17476
|
+
class: "mb-4"
|
|
17477
|
+
}),
|
|
17478
|
+
_cache[3] || (_cache[3] = createElementVNode("p", null, "Verifying your email...", -1))
|
|
17479
|
+
])) : _ctx.verificationStatus === "success" ? (openBlock(), createElementBlock("div", _hoisted_2$3, [
|
|
17480
|
+
createVNode(_component_v_icon, {
|
|
17481
|
+
color: "success",
|
|
17482
|
+
size: "64",
|
|
17483
|
+
class: "mb-4"
|
|
17484
|
+
}, {
|
|
17485
|
+
default: withCtx(() => _cache[4] || (_cache[4] = [
|
|
17486
|
+
createTextVNode("mdi-check-circle")
|
|
17487
|
+
])),
|
|
17488
|
+
_: 1
|
|
17489
|
+
}),
|
|
17490
|
+
_cache[5] || (_cache[5] = createElementVNode("h3", { class: "mb-2" }, "Email Verified!", -1)),
|
|
17491
|
+
_cache[6] || (_cache[6] = createElementVNode("p", null, "Your account has been successfully verified.", -1)),
|
|
17492
|
+
_ctx.username ? (openBlock(), createElementBlock("p", _hoisted_3$3, "Welcome, " + toDisplayString(_ctx.username) + "!", 1)) : createCommentVNode("", true)
|
|
17493
|
+
])) : _ctx.verificationStatus === "error" ? (openBlock(), createElementBlock("div", _hoisted_4$2, [
|
|
17494
|
+
createVNode(_component_v_icon, {
|
|
17495
|
+
color: "error",
|
|
17496
|
+
size: "64",
|
|
17497
|
+
class: "mb-4"
|
|
17498
|
+
}, {
|
|
17499
|
+
default: withCtx(() => _cache[7] || (_cache[7] = [
|
|
17500
|
+
createTextVNode("mdi-alert-circle")
|
|
17501
|
+
])),
|
|
17502
|
+
_: 1
|
|
17503
|
+
}),
|
|
17504
|
+
_cache[8] || (_cache[8] = createElementVNode("h3", { class: "mb-2" }, "Verification Failed", -1)),
|
|
17505
|
+
createElementVNode("p", null, toDisplayString(_ctx.errorMessage), 1)
|
|
17506
|
+
])) : (openBlock(), createElementBlock("div", _hoisted_5$2, [
|
|
17507
|
+
createVNode(_component_v_icon, {
|
|
17508
|
+
color: "warning",
|
|
17509
|
+
size: "64",
|
|
17510
|
+
class: "mb-4"
|
|
17511
|
+
}, {
|
|
17512
|
+
default: withCtx(() => _cache[9] || (_cache[9] = [
|
|
17513
|
+
createTextVNode("mdi-help-circle")
|
|
17514
|
+
])),
|
|
17515
|
+
_: 1
|
|
17516
|
+
}),
|
|
17517
|
+
_cache[10] || (_cache[10] = createElementVNode("h3", { class: "mb-2" }, "No Verification Token", -1)),
|
|
17518
|
+
_cache[11] || (_cache[11] = createElementVNode("p", null, "Please use the link from your verification email.", -1))
|
|
17519
|
+
]))
|
|
17520
|
+
]),
|
|
17521
|
+
_: 1
|
|
17522
|
+
}),
|
|
17523
|
+
createVNode(_component_v_card_actions, null, {
|
|
17524
|
+
default: withCtx(() => [
|
|
17525
|
+
createVNode(_component_v_spacer),
|
|
17526
|
+
renderSlot(_ctx.$slots, "actions", {
|
|
17527
|
+
status: _ctx.verificationStatus,
|
|
17528
|
+
username: _ctx.username
|
|
17529
|
+
}, () => [
|
|
17530
|
+
_ctx.verificationStatus === "success" ? (openBlock(), createBlock(_component_v_btn, {
|
|
17531
|
+
key: 0,
|
|
17532
|
+
color: "primary",
|
|
17533
|
+
onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("verified", _ctx.username))
|
|
17534
|
+
}, {
|
|
17535
|
+
default: withCtx(() => _cache[12] || (_cache[12] = [
|
|
17536
|
+
createTextVNode(" Continue ")
|
|
17537
|
+
])),
|
|
17538
|
+
_: 1
|
|
17539
|
+
})) : _ctx.verificationStatus === "error" ? (openBlock(), createBlock(_component_v_btn, {
|
|
17540
|
+
key: 1,
|
|
17541
|
+
variant: "text",
|
|
17542
|
+
onClick: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("error", _ctx.errorMessage))
|
|
17543
|
+
}, {
|
|
17544
|
+
default: withCtx(() => _cache[13] || (_cache[13] = [
|
|
17545
|
+
createTextVNode(" Close ")
|
|
17546
|
+
])),
|
|
17547
|
+
_: 1
|
|
17548
|
+
})) : createCommentVNode("", true)
|
|
17549
|
+
])
|
|
17550
|
+
]),
|
|
17551
|
+
_: 3
|
|
17552
|
+
})
|
|
17553
|
+
]),
|
|
17554
|
+
_: 3
|
|
17555
|
+
})
|
|
17556
|
+
]),
|
|
17557
|
+
_: 3
|
|
17558
|
+
})
|
|
17559
|
+
]),
|
|
17560
|
+
_: 3
|
|
17561
|
+
})
|
|
17562
|
+
]),
|
|
17563
|
+
_: 3
|
|
17564
|
+
});
|
|
17565
|
+
}
|
|
17566
|
+
const VerifyEmail = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$5]]);
|
|
17567
|
+
const _sfc_main$4 = defineComponent({
|
|
17568
|
+
name: "ResetPassword",
|
|
17569
|
+
emits: ["complete", "error"],
|
|
17570
|
+
props: {
|
|
17571
|
+
/**
|
|
17572
|
+
* Reset token. If not provided, will try to read from URL query params.
|
|
17573
|
+
*/
|
|
17574
|
+
token: {
|
|
17575
|
+
type: String,
|
|
17576
|
+
default: null
|
|
17577
|
+
}
|
|
17578
|
+
},
|
|
17579
|
+
data() {
|
|
17580
|
+
return {
|
|
17581
|
+
password: "",
|
|
17582
|
+
confirmPassword: "",
|
|
17583
|
+
passwordVisible: false,
|
|
17584
|
+
confirmPasswordError: false,
|
|
17585
|
+
confirmPasswordHint: "",
|
|
17586
|
+
isSubmitting: false,
|
|
17587
|
+
isComplete: false
|
|
17588
|
+
};
|
|
17589
|
+
},
|
|
17590
|
+
computed: {
|
|
17591
|
+
canSubmit() {
|
|
17592
|
+
return this.password.length >= 4 && this.confirmPassword.length >= 4 && this.password === this.confirmPassword && !this.confirmPasswordError;
|
|
17593
|
+
}
|
|
17594
|
+
},
|
|
17595
|
+
methods: {
|
|
17596
|
+
validateConfirmPassword() {
|
|
17597
|
+
this.confirmPasswordError = false;
|
|
17598
|
+
this.confirmPasswordHint = "";
|
|
17599
|
+
if (!this.confirmPassword) return;
|
|
17600
|
+
if (this.password !== this.confirmPassword) {
|
|
17601
|
+
this.confirmPasswordError = true;
|
|
17602
|
+
this.confirmPasswordHint = "Passwords do not match";
|
|
17603
|
+
}
|
|
17604
|
+
},
|
|
17605
|
+
async handleSubmit() {
|
|
17606
|
+
this.validateConfirmPassword();
|
|
17607
|
+
if (!this.canSubmit) {
|
|
17608
|
+
return;
|
|
17609
|
+
}
|
|
17610
|
+
const token2 = this.token || this.getTokenFromURL();
|
|
17611
|
+
if (!token2) {
|
|
17612
|
+
alertUser({
|
|
17613
|
+
text: "No reset token provided. Please use the link from your email.",
|
|
17614
|
+
status: Status.error
|
|
17615
|
+
});
|
|
17616
|
+
this.$emit("error", "No token");
|
|
17617
|
+
return;
|
|
17618
|
+
}
|
|
17619
|
+
this.isSubmitting = true;
|
|
17620
|
+
try {
|
|
17621
|
+
const result = await resetPassword(token2, this.password);
|
|
17622
|
+
if (result.ok) {
|
|
17623
|
+
this.isComplete = true;
|
|
17624
|
+
alertUser({
|
|
17625
|
+
text: "Password reset successfully!",
|
|
17626
|
+
status: Status.ok
|
|
17627
|
+
});
|
|
17628
|
+
} else {
|
|
17629
|
+
alertUser({
|
|
17630
|
+
text: result.error || "Failed to reset password",
|
|
17631
|
+
status: Status.error
|
|
17632
|
+
});
|
|
17633
|
+
this.$emit("error", result.error);
|
|
17634
|
+
}
|
|
17635
|
+
} catch (error) {
|
|
17636
|
+
alertUser({
|
|
17637
|
+
text: "An unexpected error occurred",
|
|
17638
|
+
status: Status.error
|
|
17639
|
+
});
|
|
17640
|
+
this.$emit("error", "Unexpected error");
|
|
17641
|
+
} finally {
|
|
17642
|
+
this.isSubmitting = false;
|
|
17643
|
+
}
|
|
17644
|
+
},
|
|
17645
|
+
getTokenFromURL() {
|
|
17646
|
+
if (typeof window === "undefined") return null;
|
|
17647
|
+
const params = new URLSearchParams(window.location.search);
|
|
17648
|
+
return params.get("token");
|
|
17649
|
+
}
|
|
17650
|
+
}
|
|
17651
|
+
});
|
|
17652
|
+
const _hoisted_1$4 = {
|
|
17653
|
+
key: 1,
|
|
17654
|
+
class: "text-center"
|
|
17655
|
+
};
|
|
17656
|
+
function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
17657
|
+
const _component_v_card_title = resolveComponent("v-card-title");
|
|
17658
|
+
const _component_v_text_field = resolveComponent("v-text-field");
|
|
17659
|
+
const _component_v_icon = resolveComponent("v-icon");
|
|
17660
|
+
const _component_v_btn = resolveComponent("v-btn");
|
|
17661
|
+
const _component_v_form = resolveComponent("v-form");
|
|
17662
|
+
const _component_v_card_text = resolveComponent("v-card-text");
|
|
17663
|
+
const _component_v_spacer = resolveComponent("v-spacer");
|
|
17664
|
+
const _component_v_card_actions = resolveComponent("v-card-actions");
|
|
17665
|
+
const _component_v_card = resolveComponent("v-card");
|
|
17666
|
+
const _component_v_col = resolveComponent("v-col");
|
|
17667
|
+
const _component_v_row = resolveComponent("v-row");
|
|
17668
|
+
const _component_v_container = resolveComponent("v-container");
|
|
17669
|
+
return openBlock(), createBlock(_component_v_container, {
|
|
17670
|
+
class: "fill-height",
|
|
17671
|
+
fluid: ""
|
|
17672
|
+
}, {
|
|
17673
|
+
default: withCtx(() => [
|
|
17674
|
+
createVNode(_component_v_row, {
|
|
17675
|
+
align: "center",
|
|
17676
|
+
justify: "center"
|
|
17677
|
+
}, {
|
|
17678
|
+
default: withCtx(() => [
|
|
17679
|
+
createVNode(_component_v_col, {
|
|
17680
|
+
cols: "12",
|
|
17681
|
+
sm: "8",
|
|
17682
|
+
md: "6"
|
|
17683
|
+
}, {
|
|
17684
|
+
default: withCtx(() => [
|
|
17685
|
+
createVNode(_component_v_card, null, {
|
|
17686
|
+
default: withCtx(() => [
|
|
17687
|
+
createVNode(_component_v_card_title, { class: "text-h5 bg-grey-lighten-2" }, {
|
|
17688
|
+
default: withCtx(() => _cache[4] || (_cache[4] = [
|
|
17689
|
+
createTextVNode(" Set New Password ")
|
|
17690
|
+
])),
|
|
17691
|
+
_: 1
|
|
17692
|
+
}),
|
|
17693
|
+
createVNode(_component_v_card_text, { class: "pa-6" }, {
|
|
17694
|
+
default: withCtx(() => [
|
|
17695
|
+
!_ctx.isComplete ? (openBlock(), createBlock(_component_v_form, {
|
|
17696
|
+
key: 0,
|
|
17697
|
+
onSubmit: withModifiers(_ctx.handleSubmit, ["prevent"])
|
|
17698
|
+
}, {
|
|
17699
|
+
default: withCtx(() => [
|
|
17700
|
+
_cache[7] || (_cache[7] = createElementVNode("p", { class: "mb-4" }, "Enter your new password below.", -1)),
|
|
17701
|
+
createVNode(_component_v_text_field, {
|
|
17702
|
+
modelValue: _ctx.password,
|
|
17703
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.password = $event),
|
|
17704
|
+
"prepend-icon": "mdi-lock",
|
|
17705
|
+
name: "password",
|
|
17706
|
+
label: "New password",
|
|
17707
|
+
min: "4",
|
|
17708
|
+
"append-icon": _ctx.passwordVisible ? "mdi-eye-off" : "mdi-eye",
|
|
17709
|
+
type: _ctx.passwordVisible ? "text" : "password",
|
|
17710
|
+
disabled: _ctx.isSubmitting,
|
|
17711
|
+
"onClick:append": _cache[1] || (_cache[1] = () => _ctx.passwordVisible = !_ctx.passwordVisible)
|
|
17712
|
+
}, null, 8, ["modelValue", "append-icon", "type", "disabled"]),
|
|
17713
|
+
createVNode(_component_v_text_field, {
|
|
17714
|
+
modelValue: _ctx.confirmPassword,
|
|
17715
|
+
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => _ctx.confirmPassword = $event),
|
|
17716
|
+
"prepend-icon": "mdi-lock",
|
|
17717
|
+
name: "confirmPassword",
|
|
17718
|
+
label: "Confirm new password",
|
|
17719
|
+
min: "4",
|
|
17720
|
+
type: _ctx.passwordVisible ? "text" : "password",
|
|
17721
|
+
error: _ctx.confirmPasswordError,
|
|
17722
|
+
hint: _ctx.confirmPasswordHint,
|
|
17723
|
+
disabled: _ctx.isSubmitting,
|
|
17724
|
+
onBlur: _ctx.validateConfirmPassword
|
|
17725
|
+
}, null, 8, ["modelValue", "type", "error", "hint", "disabled", "onBlur"]),
|
|
17726
|
+
createVNode(_component_v_btn, {
|
|
17727
|
+
type: "submit",
|
|
17728
|
+
color: "primary",
|
|
17729
|
+
class: "mt-4",
|
|
17730
|
+
loading: _ctx.isSubmitting,
|
|
17731
|
+
disabled: !_ctx.canSubmit,
|
|
17732
|
+
block: ""
|
|
17733
|
+
}, {
|
|
17734
|
+
default: withCtx(() => [
|
|
17735
|
+
createVNode(_component_v_icon, { start: "" }, {
|
|
17736
|
+
default: withCtx(() => _cache[5] || (_cache[5] = [
|
|
17737
|
+
createTextVNode("mdi-lock-reset")
|
|
17738
|
+
])),
|
|
17739
|
+
_: 1
|
|
17740
|
+
}),
|
|
17741
|
+
_cache[6] || (_cache[6] = createTextVNode(" Reset Password "))
|
|
17742
|
+
]),
|
|
17743
|
+
_: 1
|
|
17744
|
+
}, 8, ["loading", "disabled"])
|
|
17745
|
+
]),
|
|
17746
|
+
_: 1
|
|
17747
|
+
}, 8, ["onSubmit"])) : (openBlock(), createElementBlock("div", _hoisted_1$4, [
|
|
17748
|
+
createVNode(_component_v_icon, {
|
|
17749
|
+
color: "success",
|
|
17750
|
+
size: "64",
|
|
17751
|
+
class: "mb-4"
|
|
17752
|
+
}, {
|
|
17753
|
+
default: withCtx(() => _cache[8] || (_cache[8] = [
|
|
17754
|
+
createTextVNode("mdi-check-circle")
|
|
17755
|
+
])),
|
|
17756
|
+
_: 1
|
|
17757
|
+
}),
|
|
17758
|
+
_cache[9] || (_cache[9] = createElementVNode("h3", { class: "mb-2" }, "Password Reset Successful!", -1)),
|
|
17759
|
+
_cache[10] || (_cache[10] = createElementVNode("p", null, "Your password has been updated. You can now log in with your new password.", -1))
|
|
17760
|
+
]))
|
|
17761
|
+
]),
|
|
17762
|
+
_: 1
|
|
17763
|
+
}),
|
|
17764
|
+
_ctx.isComplete ? (openBlock(), createBlock(_component_v_card_actions, { key: 0 }, {
|
|
17765
|
+
default: withCtx(() => [
|
|
17766
|
+
createVNode(_component_v_spacer),
|
|
17767
|
+
renderSlot(_ctx.$slots, "success-action", {}, () => [
|
|
17768
|
+
createVNode(_component_v_btn, {
|
|
17769
|
+
color: "primary",
|
|
17770
|
+
onClick: _cache[3] || (_cache[3] = ($event) => _ctx.$emit("complete"))
|
|
17771
|
+
}, {
|
|
17772
|
+
default: withCtx(() => _cache[11] || (_cache[11] = [
|
|
17773
|
+
createTextVNode(" Continue to Login ")
|
|
17774
|
+
])),
|
|
17775
|
+
_: 1
|
|
17776
|
+
})
|
|
17777
|
+
])
|
|
17778
|
+
]),
|
|
17779
|
+
_: 3
|
|
17780
|
+
})) : createCommentVNode("", true)
|
|
17781
|
+
]),
|
|
17782
|
+
_: 3
|
|
17783
|
+
})
|
|
17784
|
+
]),
|
|
17785
|
+
_: 3
|
|
17786
|
+
})
|
|
17787
|
+
]),
|
|
17788
|
+
_: 3
|
|
17789
|
+
})
|
|
17790
|
+
]),
|
|
17791
|
+
_: 3
|
|
17792
|
+
});
|
|
17793
|
+
}
|
|
17794
|
+
const ResetPassword = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]);
|
|
16832
17795
|
const _sfc_main$3 = defineComponent({
|
|
16833
17796
|
name: "SkTagsInput",
|
|
16834
17797
|
components: {
|
|
@@ -17844,7 +18807,7 @@ export {
|
|
|
17844
18807
|
CardSearch,
|
|
17845
18808
|
CardSearchResults,
|
|
17846
18809
|
CardViewer,
|
|
17847
|
-
_sfc_main$
|
|
18810
|
+
_sfc_main$d as CodeBlockRenderer,
|
|
17848
18811
|
CourseCardBrowser,
|
|
17849
18812
|
CourseInformation,
|
|
17850
18813
|
Displayable,
|
|
@@ -17856,6 +18819,8 @@ export {
|
|
|
17856
18819
|
PaginatingToolbar,
|
|
17857
18820
|
Question,
|
|
17858
18821
|
RadioMultipleChoice,
|
|
18822
|
+
RequestPasswordReset,
|
|
18823
|
+
ResetPassword,
|
|
17859
18824
|
SkMouseTrap,
|
|
17860
18825
|
SkMouseTrapToolTip,
|
|
17861
18826
|
SkldrMouseTrap,
|
|
@@ -17870,20 +18835,29 @@ export {
|
|
|
17870
18835
|
UserLogin,
|
|
17871
18836
|
UserLoginAndRegistrationContainer,
|
|
17872
18837
|
UserRegistration,
|
|
18838
|
+
VerifyEmail,
|
|
17873
18839
|
alertUser,
|
|
17874
18840
|
containsComponent,
|
|
17875
18841
|
getCurrentUser,
|
|
18842
|
+
getUserStatus,
|
|
17876
18843
|
isComponent,
|
|
17877
18844
|
isDefineComponent,
|
|
18845
|
+
isPasswordValid,
|
|
17878
18846
|
isQuestionView,
|
|
17879
18847
|
piniaPlugin,
|
|
18848
|
+
requestPasswordReset,
|
|
18849
|
+
resetPassword,
|
|
18850
|
+
sendVerificationEmail,
|
|
17880
18851
|
splitByDelimiters,
|
|
17881
18852
|
splitParagraphToken,
|
|
17882
18853
|
splitTextToken,
|
|
17883
18854
|
useAuthStore,
|
|
17884
18855
|
useCardPreviewModeStore,
|
|
17885
18856
|
useConfigStore,
|
|
18857
|
+
useEntitlements,
|
|
17886
18858
|
useQuestionView,
|
|
17887
|
-
useViewable
|
|
18859
|
+
useViewable,
|
|
18860
|
+
validatePassword,
|
|
18861
|
+
verifyEmail
|
|
17888
18862
|
};
|
|
17889
18863
|
//# sourceMappingURL=common-ui.es.js.map
|