@vue-skuilder/common-ui 0.2.34 → 0.2.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_@oxc-project_runtime@0.115.0/helpers/defineProperty.mjs +13 -0
- package/dist/_virtual/_@oxc-project_runtime@0.115.0/helpers/toPrimitive.mjs +15 -0
- package/dist/_virtual/_@oxc-project_runtime@0.115.0/helpers/toPropertyKey.mjs +10 -0
- package/dist/_virtual/_@oxc-project_runtime@0.115.0/helpers/typeof.mjs +12 -0
- package/dist/_virtual/_plugin-vue_export-helper.mjs +9 -0
- package/dist/_virtual/_rolldown/runtime.mjs +7 -0
- package/dist/admin/admin.css +1 -1
- package/dist/admin/common-ui-admin.es.js +1074 -473
- package/dist/admin/common-ui-admin.es.js.map +1 -1
- package/dist/admin/components/EChart.vue.d.ts +14 -0
- package/dist/admin/components/EChart.vue.d.ts.map +1 -0
- package/dist/admin/components/LearnerDiagnostics.vue.d.ts +3 -3
- package/dist/admin/components/LearnerDiagnostics.vue.d.ts.map +1 -1
- package/dist/admin/components/LearnerTagElo.vue.d.ts +14 -0
- package/dist/admin/components/LearnerTagElo.vue.d.ts.map +1 -0
- package/dist/admin/index.d.ts +1 -0
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/assets/index.css +2 -1
- package/dist/components/CardBrowser.mjs +63 -0
- package/dist/components/CardBrowser.mjs.map +1 -0
- package/dist/components/CardBrowser.vue_vue_type_script_lang.mjs +50 -0
- package/dist/components/CardBrowser.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/CardHistoryViewer.mjs +70 -0
- package/dist/components/CardHistoryViewer.mjs.map +1 -0
- package/dist/components/CardHistoryViewer.vue_vue_type_script_lang.mjs +108 -0
- package/dist/components/CardHistoryViewer.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/CardSearch.mjs +26 -0
- package/dist/components/CardSearch.mjs.map +1 -0
- package/dist/components/CardSearch.vue_vue_type_script_lang.mjs +17 -0
- package/dist/components/CardSearch.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/CardSearchResults.mjs +32 -0
- package/dist/components/CardSearchResults.mjs.map +1 -0
- package/dist/components/CardSearchResults.vue_vue_type_script_lang.mjs +71 -0
- package/dist/components/CardSearchResults.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/CourseCardBrowser.mjs +175 -0
- package/dist/components/CourseCardBrowser.mjs.map +1 -0
- package/dist/components/CourseCardBrowser.vue.d.ts +3 -3
- package/dist/components/CourseCardBrowser.vue_vue_type_script_lang.mjs +173 -0
- package/dist/components/CourseCardBrowser.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/CourseInformation.mjs +132 -0
- package/dist/components/CourseInformation.mjs.map +1 -0
- package/dist/components/CourseInformation.vue.d.ts +3 -3
- package/dist/components/CourseInformation.vue_vue_type_script_lang.mjs +56 -0
- package/dist/components/CourseInformation.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/CourseTagFilterWidget.mjs +114 -0
- package/dist/components/CourseTagFilterWidget.mjs.map +1 -0
- package/dist/components/CourseTagFilterWidget.vue_vue_type_script_lang.mjs +65 -0
- package/dist/components/CourseTagFilterWidget.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/HeatMap.mjs +40 -0
- package/dist/components/HeatMap.mjs.map +1 -0
- package/dist/components/HeatMap.vue_vue_type_script_lang.mjs +211 -0
- package/dist/components/HeatMap.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/PaginatingToolbar.mjs +94 -0
- package/dist/components/PaginatingToolbar.mjs.map +1 -0
- package/dist/components/PaginatingToolbar.vue.d.ts +3 -3
- package/dist/components/PaginatingToolbar.vue_vue_type_script_lang.mjs +36 -0
- package/dist/components/PaginatingToolbar.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/SessionControllerDebug.mjs +130 -0
- package/dist/components/SessionControllerDebug.mjs.map +1 -0
- package/dist/components/SessionControllerDebug.vue_vue_type_script_lang.mjs +45 -0
- package/dist/components/SessionControllerDebug.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/SkMouseTrap.mjs +66 -0
- package/dist/components/SkMouseTrap.mjs.map +1 -0
- package/dist/components/SkMouseTrap.vue_vue_type_script_lang.mjs +31 -0
- package/dist/components/SkMouseTrap.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/SkMouseTrapToolTip.mjs +28 -0
- package/dist/components/SkMouseTrapToolTip.mjs.map +1 -0
- package/dist/components/SkMouseTrapToolTip.vue.d.ts +1 -1
- package/dist/components/SkMouseTrapToolTip.vue_vue_type_script_lang.mjs +91 -0
- package/dist/components/SkMouseTrapToolTip.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/SnackbarService.mjs +24 -0
- package/dist/components/SnackbarService.mjs.map +1 -0
- package/dist/components/SnackbarService.vue_vue_type_script_lang.mjs +34 -0
- package/dist/components/SnackbarService.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/SnackbarService2.mjs +40 -0
- package/dist/components/SnackbarService2.mjs.map +1 -0
- package/dist/components/StudySession.mjs +123 -0
- package/dist/components/StudySession.mjs.map +1 -0
- package/dist/components/StudySession.vue_vue_type_script_lang.mjs +280 -0
- package/dist/components/StudySession.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/StudySessionTimer.mjs +50 -0
- package/dist/components/StudySessionTimer.mjs.map +1 -0
- package/dist/components/StudySessionTimer.vue_vue_type_script_lang.mjs +43 -0
- package/dist/components/StudySessionTimer.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/TagsInput.mjs +45 -0
- package/dist/components/TagsInput.mjs.map +1 -0
- package/dist/components/TagsInput.vue_vue_type_script_lang.mjs +117 -0
- package/dist/components/TagsInput.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/UserTagPreferences.mjs +205 -0
- package/dist/components/UserTagPreferences.mjs.map +1 -0
- package/dist/components/UserTagPreferences.vue_vue_type_script_lang.mjs +139 -0
- package/dist/components/UserTagPreferences.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/auth/RequestPasswordReset.mjs +96 -0
- package/dist/components/auth/RequestPasswordReset.mjs.map +1 -0
- package/dist/components/auth/RequestPasswordReset.vue_vue_type_script_lang.mjs +47 -0
- package/dist/components/auth/RequestPasswordReset.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/auth/ResetPassword.mjs +129 -0
- package/dist/components/auth/ResetPassword.mjs.map +1 -0
- package/dist/components/auth/ResetPassword.vue_vue_type_script_lang.mjs +69 -0
- package/dist/components/auth/ResetPassword.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/auth/UserChip.mjs +9 -0
- package/dist/components/auth/UserChip.mjs.map +1 -0
- package/dist/components/auth/UserChip.vue_vue_type_script_setup_true_lang.mjs +213 -0
- package/dist/components/auth/UserChip.vue_vue_type_script_setup_true_lang.mjs.map +1 -0
- package/dist/components/auth/UserLogin.mjs +9 -0
- package/dist/components/auth/UserLogin.mjs.map +1 -0
- package/dist/components/auth/UserLogin.vue_vue_type_script_setup_true_lang.mjs +155 -0
- package/dist/components/auth/UserLogin.vue_vue_type_script_setup_true_lang.mjs.map +1 -0
- package/dist/components/auth/UserLoginAndRegistrationContainer.mjs +9 -0
- package/dist/components/auth/UserLoginAndRegistrationContainer.mjs.map +1 -0
- package/dist/components/auth/UserLoginAndRegistrationContainer.vue_vue_type_script_setup_true_lang.mjs +126 -0
- package/dist/components/auth/UserLoginAndRegistrationContainer.vue_vue_type_script_setup_true_lang.mjs.map +1 -0
- package/dist/components/auth/UserRegistration.mjs +147 -0
- package/dist/components/auth/UserRegistration.mjs.map +1 -0
- package/dist/components/auth/UserRegistration.vue_vue_type_script_lang.mjs +130 -0
- package/dist/components/auth/UserRegistration.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/auth/VerifyEmail.mjs +118 -0
- package/dist/components/auth/VerifyEmail.mjs.map +1 -0
- package/dist/components/auth/VerifyEmail.vue_vue_type_script_lang.mjs +59 -0
- package/dist/components/auth/VerifyEmail.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/cardRendering/AudioAutoPlayer.mjs +9 -0
- package/dist/components/cardRendering/AudioAutoPlayer.mjs.map +1 -0
- package/dist/components/cardRendering/AudioAutoPlayer.vue_vue_type_script_setup_true_lang.mjs +69 -0
- package/dist/components/cardRendering/AudioAutoPlayer.vue_vue_type_script_setup_true_lang.mjs.map +1 -0
- package/dist/components/cardRendering/CardLoader.mjs +31 -0
- package/dist/components/cardRendering/CardLoader.mjs.map +1 -0
- package/dist/components/cardRendering/CardLoader.vue_vue_type_script_lang.mjs +75 -0
- package/dist/components/cardRendering/CardLoader.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/cardRendering/CardViewer.mjs +39 -0
- package/dist/components/cardRendering/CardViewer.mjs.map +1 -0
- package/dist/components/cardRendering/CardViewer.vue_vue_type_script_lang.mjs +66 -0
- package/dist/components/cardRendering/CardViewer.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/cardRendering/CodeBlockRenderer.mjs +8 -0
- package/dist/components/cardRendering/CodeBlockRenderer.mjs.map +1 -0
- package/dist/components/cardRendering/CodeBlockRenderer.vue_vue_type_script_setup_true_lang.mjs +44 -0
- package/dist/components/cardRendering/CodeBlockRenderer.vue_vue_type_script_setup_true_lang.mjs.map +1 -0
- package/dist/components/cardRendering/MarkdownRenderer.mjs +21 -0
- package/dist/components/cardRendering/MarkdownRenderer.mjs.map +1 -0
- package/dist/components/cardRendering/MarkdownRenderer.vue_vue_type_script_lang.mjs +24 -0
- package/dist/components/cardRendering/MarkdownRenderer.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/cardRendering/MarkdownRendererHelpers.mjs +79 -0
- package/dist/components/cardRendering/MarkdownRendererHelpers.mjs.map +1 -0
- package/dist/components/cardRendering/MdTokenRenderer.mjs +9 -0
- package/dist/components/cardRendering/MdTokenRenderer.mjs.map +1 -0
- package/dist/components/cardRendering/MdTokenRenderer.vue_vue_type_script_setup_true_lang.mjs +176 -0
- package/dist/components/cardRendering/MdTokenRenderer.vue_vue_type_script_setup_true_lang.mjs.map +1 -0
- package/dist/components/studentInputs/BaseUserInput.mjs +54 -0
- package/dist/components/studentInputs/BaseUserInput.mjs.map +1 -0
- package/dist/components/studentInputs/MultipleChoiceOption.mjs +26 -0
- package/dist/components/studentInputs/MultipleChoiceOption.mjs.map +1 -0
- package/dist/components/studentInputs/MultipleChoiceOption.vue_vue_type_script_lang.mjs +76 -0
- package/dist/components/studentInputs/MultipleChoiceOption.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/studentInputs/RadioMultipleChoice.mjs +33 -0
- package/dist/components/studentInputs/RadioMultipleChoice.mjs.map +1 -0
- package/dist/components/studentInputs/RadioMultipleChoice.vue_vue_type_script_lang.mjs +105 -0
- package/dist/components/studentInputs/RadioMultipleChoice.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/studentInputs/TrueFalse.mjs +19 -0
- package/dist/components/studentInputs/TrueFalse.mjs.map +1 -0
- package/dist/components/studentInputs/TrueFalse.vue_vue_type_script_lang.mjs +21 -0
- package/dist/components/studentInputs/TrueFalse.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/studentInputs/UserInputNumber.mjs +33 -0
- package/dist/components/studentInputs/UserInputNumber.mjs.map +1 -0
- package/dist/components/studentInputs/UserInputNumber.vue_vue_type_script_lang.mjs +25 -0
- package/dist/components/studentInputs/UserInputNumber.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/studentInputs/UserInputString.mjs +22 -0
- package/dist/components/studentInputs/UserInputString.mjs.map +1 -0
- package/dist/components/studentInputs/UserInputString.vue_vue_type_script_lang.mjs +23 -0
- package/dist/components/studentInputs/UserInputString.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/components/studentInputs/fillInInput.mjs +25 -0
- package/dist/components/studentInputs/fillInInput.mjs.map +1 -0
- package/dist/components/studentInputs/fillInInput.vue_vue_type_script_lang.mjs +26 -0
- package/dist/components/studentInputs/fillInInput.vue_vue_type_script_lang.mjs.map +1 -0
- package/dist/composables/CompositionViewable.mjs +65 -0
- package/dist/composables/CompositionViewable.mjs.map +1 -0
- package/dist/composables/Displayable.mjs +36 -0
- package/dist/composables/Displayable.mjs.map +1 -0
- package/dist/composables/useAuthUI.mjs +38 -0
- package/dist/composables/useAuthUI.mjs.map +1 -0
- package/dist/composables/useEntitlements.mjs +58 -0
- package/dist/composables/useEntitlements.mjs.map +1 -0
- package/dist/index.mjs +49 -0
- package/dist/plugins/pinia.mjs +12 -0
- package/dist/plugins/pinia.mjs.map +1 -0
- package/dist/services/authAPI.mjs +159 -0
- package/dist/services/authAPI.mjs.map +1 -0
- package/dist/stores/useAuthStore.mjs +68 -0
- package/dist/stores/useAuthStore.mjs.map +1 -0
- package/dist/stores/useCardPreviewModeStore.mjs +20 -0
- package/dist/stores/useCardPreviewModeStore.mjs.map +1 -0
- package/dist/stores/useConfigStore.mjs +60 -0
- package/dist/stores/useConfigStore.mjs.map +1 -0
- package/dist/utils/SkldrMouseTrap.mjs +48 -0
- package/dist/utils/SkldrMouseTrap.mjs.map +1 -0
- package/dist/utils/passwordValidation.mjs +12 -0
- package/dist/utils/passwordValidation.mjs.map +1 -0
- package/package.json +8 -8
- package/src/admin/components/EChart.vue +59 -0
- package/src/admin/components/LearnerDiagnostics.vue +8 -4
- package/src/admin/components/LearnerTagElo.vue +563 -0
- package/src/admin/index.ts +1 -0
- package/dist/MarkdownRenderer-U_iPiA2x.mjs +0 -4966
- package/dist/MarkdownRenderer-U_iPiA2x.mjs.map +0 -1
- package/dist/assets/MarkdownRenderer.css +0 -1
- package/dist/common-ui.es.js +0 -5090
- package/dist/common-ui.es.js.map +0 -1
- package/dist/common-ui.umd.js +0 -77
- package/dist/common-ui.umd.js.map +0 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import "../../_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import e from "../../_virtual/_plugin-vue_export-helper.mjs";
|
|
3
|
+
import t from "./RequestPasswordReset.vue_vue_type_script_lang.mjs";
|
|
4
|
+
import { createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createTextVNode as o, createVNode as s, openBlock as c, renderSlot as l, resolveComponent as u, toDisplayString as d, withCtx as f, withModifiers as p } from "vue";
|
|
5
|
+
//#region src/components/auth/RequestPasswordReset.vue
|
|
6
|
+
var m = {
|
|
7
|
+
key: 1,
|
|
8
|
+
class: "text-center"
|
|
9
|
+
};
|
|
10
|
+
function _sfc_render(e, t, h, g, _, v) {
|
|
11
|
+
let y = u("v-card-title"), b = u("v-text-field"), x = u("v-icon"), S = u("v-btn"), C = u("v-form"), w = u("v-card-text"), T = u("v-spacer"), E = u("v-card-actions"), D = u("v-card");
|
|
12
|
+
return c(), n(D, null, {
|
|
13
|
+
default: f(() => [
|
|
14
|
+
s(y, { class: "text-h5 bg-grey-lighten-2" }, {
|
|
15
|
+
default: f(() => t[2] || (t[2] = [o(" Reset Password ")])),
|
|
16
|
+
_: 1
|
|
17
|
+
}),
|
|
18
|
+
s(w, { class: "pa-6" }, {
|
|
19
|
+
default: f(() => [e.requestSent ? (c(), i("div", m, [
|
|
20
|
+
s(x, {
|
|
21
|
+
color: "success",
|
|
22
|
+
size: "64",
|
|
23
|
+
class: "mb-4"
|
|
24
|
+
}, {
|
|
25
|
+
default: f(() => t[6] || (t[6] = [o("mdi-email-check")])),
|
|
26
|
+
_: 1
|
|
27
|
+
}),
|
|
28
|
+
t[9] || (t[9] = a("h3", { class: "mb-2" }, "Check Your Email", -1)),
|
|
29
|
+
a("p", null, [
|
|
30
|
+
t[7] || (t[7] = o(" If an account exists with ")),
|
|
31
|
+
a("strong", null, d(e.email), 1),
|
|
32
|
+
t[8] || (t[8] = o(", you will receive a password reset link shortly. "))
|
|
33
|
+
]),
|
|
34
|
+
t[10] || (t[10] = a("p", { class: "text-caption mt-4" }, "Didn't receive an email? Check your spam folder.", -1))
|
|
35
|
+
])) : (c(), n(C, {
|
|
36
|
+
key: 0,
|
|
37
|
+
onSubmit: p(e.handleSubmit, ["prevent"])
|
|
38
|
+
}, {
|
|
39
|
+
default: f(() => [
|
|
40
|
+
t[5] || (t[5] = a("p", { class: "mb-4" }, " Enter your email address and we'll send you a link to reset your password. ", -1)),
|
|
41
|
+
s(b, {
|
|
42
|
+
modelValue: e.email,
|
|
43
|
+
"onUpdate:modelValue": t[0] || (t[0] = (t) => e.email = t),
|
|
44
|
+
name: "email",
|
|
45
|
+
label: "Email address",
|
|
46
|
+
type: "email",
|
|
47
|
+
"prepend-icon": "mdi-email",
|
|
48
|
+
error: e.emailError,
|
|
49
|
+
hint: e.emailHint,
|
|
50
|
+
disabled: e.isSubmitting,
|
|
51
|
+
onBlur: e.validateEmail
|
|
52
|
+
}, null, 8, [
|
|
53
|
+
"modelValue",
|
|
54
|
+
"error",
|
|
55
|
+
"hint",
|
|
56
|
+
"disabled",
|
|
57
|
+
"onBlur"
|
|
58
|
+
]),
|
|
59
|
+
s(S, {
|
|
60
|
+
type: "submit",
|
|
61
|
+
color: "primary",
|
|
62
|
+
class: "mt-4",
|
|
63
|
+
loading: e.isSubmitting,
|
|
64
|
+
disabled: !e.email || e.emailError,
|
|
65
|
+
block: ""
|
|
66
|
+
}, {
|
|
67
|
+
default: f(() => [s(x, { start: "" }, {
|
|
68
|
+
default: f(() => t[3] || (t[3] = [o("mdi-email-send")])),
|
|
69
|
+
_: 1
|
|
70
|
+
}), t[4] || (t[4] = o(" Send Reset Link "))]),
|
|
71
|
+
_: 1
|
|
72
|
+
}, 8, ["loading", "disabled"])
|
|
73
|
+
]),
|
|
74
|
+
_: 1
|
|
75
|
+
}, 8, ["onSubmit"]))]),
|
|
76
|
+
_: 1
|
|
77
|
+
}),
|
|
78
|
+
e.requestSent ? r("", !0) : (c(), n(E, { key: 0 }, {
|
|
79
|
+
default: f(() => [l(e.$slots, "back-action", {}, () => [s(S, {
|
|
80
|
+
variant: "text",
|
|
81
|
+
onClick: t[1] || (t[1] = (t) => e.$emit("cancel"))
|
|
82
|
+
}, {
|
|
83
|
+
default: f(() => t[11] || (t[11] = [o(" Cancel ")])),
|
|
84
|
+
_: 1
|
|
85
|
+
})]), s(T)]),
|
|
86
|
+
_: 3
|
|
87
|
+
}))
|
|
88
|
+
]),
|
|
89
|
+
_: 3
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
var h = /* @__PURE__ */ e(t, [["render", _sfc_render]]);
|
|
93
|
+
//#endregion
|
|
94
|
+
export { h as default };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=RequestPasswordReset.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RequestPasswordReset.mjs","names":[],"sources":["../../../src/components/auth/RequestPasswordReset.vue"],"sourcesContent":["<template>\n <v-card>\n <v-card-title class=\"text-h5 bg-grey-lighten-2\">\n Reset Password\n </v-card-title>\n\n <v-card-text class=\"pa-6\">\n <v-form v-if=\"!requestSent\" @submit.prevent=\"handleSubmit\">\n <p class=\"mb-4\">\n Enter your email address and we'll send you a link to reset your password.\n </p>\n\n <v-text-field\n v-model=\"email\"\n name=\"email\"\n label=\"Email address\"\n type=\"email\"\n prepend-icon=\"mdi-email\"\n :error=\"emailError\"\n :hint=\"emailHint\"\n :disabled=\"isSubmitting\"\n @blur=\"validateEmail\"\n ></v-text-field>\n\n <v-btn\n type=\"submit\"\n color=\"primary\"\n class=\"mt-4\"\n :loading=\"isSubmitting\"\n :disabled=\"!email || emailError\"\n block\n >\n <v-icon start>mdi-email-send</v-icon>\n Send Reset Link\n </v-btn>\n </v-form>\n\n <!-- Success message -->\n <div v-else class=\"text-center\">\n <v-icon color=\"success\" size=\"64\" class=\"mb-4\">mdi-email-check</v-icon>\n <h3 class=\"mb-2\">Check Your Email</h3>\n <p>\n If an account exists with <strong>{{ email }}</strong>, you will receive a password\n reset link shortly.\n </p>\n <p class=\"text-caption mt-4\">Didn't receive an email? Check your spam folder.</p>\n </div>\n </v-card-text>\n\n <v-card-actions v-if=\"!requestSent\">\n <slot name=\"back-action\">\n <!-- External apps can provide their own back button -->\n <v-btn variant=\"text\" @click=\"$emit('cancel')\">\n Cancel\n </v-btn>\n </slot>\n <v-spacer></v-spacer>\n </v-card-actions>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport { requestPasswordReset } from '../../services/authAPI';\nimport { alertUser } from '../SnackbarService';\nimport { Status } from '@vue-skuilder/common';\n\nexport default defineComponent({\n name: 'RequestPasswordReset',\n\n emits: ['cancel', 'success'],\n\n data() {\n return {\n email: '',\n emailError: false,\n emailHint: '',\n isSubmitting: false,\n requestSent: false,\n };\n },\n\n methods: {\n validateEmail() {\n this.emailError = false;\n this.emailHint = '';\n\n if (!this.email) return;\n\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(this.email)) {\n this.emailError = true;\n this.emailHint = 'Please enter a valid email address';\n }\n },\n\n async handleSubmit() {\n this.validateEmail();\n\n if (this.emailError || !this.email) {\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n // Pass current origin for correct reset link in email\n const origin = typeof window !== 'undefined' ? window.location.origin : undefined;\n const result = await requestPasswordReset(this.email, origin);\n\n if (result.ok) {\n this.requestSent = true;\n this.$emit('success', this.email);\n } else {\n alertUser({\n text: result.error || 'Failed to send reset email',\n status: Status.error,\n });\n }\n } catch (error) {\n alertUser({\n text: 'An unexpected error occurred',\n status: Status.error,\n });\n } finally {\n this.isSubmitting = false;\n }\n },\n },\n});\n</script>\n"],"mappings":";;;;;;CAAA,KAAA;CAsCkB,OAAM;;;;aArCtB,EAyDS,GAAA,MAAA;EA1DX,SAAA,QAImB;GAFf,EAEe,GAAA,EAFD,OAAM,6BAA2B,EAAA;IAFnD,SAAA,QAII,EAAA,OAAA,EAAA,KAAA,CAJJ,EAEoD,mBAEhD,CAAA,EAAA;IAJJ,GAAA;;GAMI,EAyCc,GAAA,EAzCD,OAAM,QAAM,EAAA;IAN7B,SAAA,QAmCe,CA5BM,EAAA,oBA+Bf,EAQM,OARN,GAQM;KAPJ,EAAuE,GAAA;MAA/D,OAAM;MAAU,MAAK;MAAK,OAAM;;MAvChD,SAAA,QAuCsE,EAAA,OAAA,EAAA,KAAA,CAvCtE,EAuCuD,kBAAe,CAAA,EAAA;MAvCtE,GAAA;;qBAwCQ,EAAsC,MAAA,EAAlC,OAAM,QAAM,EAAC,oBAAgB,GAAA;KACjC,EAGI,KAAA,MAAA;sBA5CZ,EAyCW,8BACyB;MAAA,EAA4B,UAAA,MAAA,EAAjB,EAAA,MAAK,EAAA,EAAA;sBA1CpD,EA0CgE,qDAExD;;uBACA,EAAiF,KAAA,EAA9E,OAAM,qBAAmB,EAAC,oDAAgD,GAAA;WAtChE,GAAA,EAAf,EA4BS,GAAA;KAnCf,KAAA;KAOmC,UAPnC,EAOmD,EAAA,cAAY,CAAA,UAAA,CAAA;;KAP/D,SAAA,QAUY;sBAFJ,EAEI,KAAA,EAFD,OAAM,QAAM,EAAC,gFAEhB,GAAA;MAEA,EAUgB,GAAA;OAtBxB,YAamB,EAAA;OAbnB,uBAAA,EAAA,OAAA,EAAA,MAAA,MAAA,EAamB,QAAK;OACd,MAAK;OACL,OAAM;OACN,MAAK;OACL,gBAAa;OACZ,OAAO,EAAA;OACP,MAAM,EAAA;OACN,UAAU,EAAA;OACV,QAAM,EAAA;;;;;;;;MAGT,EAUQ,GAAA;OATN,MAAK;OACL,OAAM;OACN,OAAM;OACL,SAAS,EAAA;OACT,UAAQ,CAAG,EAAA,SAAS,EAAA;OACrB,OAAA;;OA9BV,SAAA,QAgC+C,CAArC,EAAqC,GAAA,EAA7B,OAAA,IAAK,EAAA;QAhCvB,SAAA,QAgCsC,EAAA,OAAA,EAAA,KAAA,CAhCtC,EAgCwB,iBAAc,CAAA,EAAA;QAhCtC,GAAA;2BAAA,EAgC+C,oBAEvC,EAAA,CAAA;OAlCR,GAAA;;;KAAA,GAAA;;IAAA,GAAA;;GAiD2B,EAAA,cAjD3B,EAAA,IAAA,GAAA,IAiD2B,GAAA,EAAvB,EAQiB,GAAA,EAzDrB,KAAA,GAAA,EAAA;IAAA,SAAA,QAuDa,CALP,EAKO,EAAA,QAAA,eAAA,EAAA,QAAA,CAHL,EAEQ,GAAA;KAFD,SAAQ;KAAQ,SAAK,EAAA,OAAA,EAAA,MAAA,MAAE,EAAA,MAAK,SAAA;;KApD3C,SAAA,QAsDQ,EAAA,QAAA,EAAA,MAAA,CAtDR,EAoDuD,WAE/C,CAAA,EAAA;KAtDR,GAAA;UAwDM,EAAqB,EAAA,CAAA,CAAA;IAxD3B,GAAA;;;EAAA,GAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import "../../_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { alertUser as e } from "../SnackbarService.mjs";
|
|
3
|
+
import { requestPasswordReset as t } from "../../services/authAPI.mjs";
|
|
4
|
+
import { defineComponent as n } from "vue";
|
|
5
|
+
import { Status as r } from "@vue-skuilder/common";
|
|
6
|
+
//#region src/components/auth/RequestPasswordReset.vue?vue&type=script&lang.ts
|
|
7
|
+
var i = n({
|
|
8
|
+
name: "RequestPasswordReset",
|
|
9
|
+
emits: ["cancel", "success"],
|
|
10
|
+
data() {
|
|
11
|
+
return {
|
|
12
|
+
email: "",
|
|
13
|
+
emailError: !1,
|
|
14
|
+
emailHint: "",
|
|
15
|
+
isSubmitting: !1,
|
|
16
|
+
requestSent: !1
|
|
17
|
+
};
|
|
18
|
+
},
|
|
19
|
+
methods: {
|
|
20
|
+
validateEmail() {
|
|
21
|
+
this.emailError = !1, this.emailHint = "", this.email && (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email) || (this.emailError = !0, this.emailHint = "Please enter a valid email address"));
|
|
22
|
+
},
|
|
23
|
+
async handleSubmit() {
|
|
24
|
+
if (this.validateEmail(), !(this.emailError || !this.email)) {
|
|
25
|
+
this.isSubmitting = !0;
|
|
26
|
+
try {
|
|
27
|
+
let n = typeof window < "u" ? window.location.origin : void 0, i = await t(this.email, n);
|
|
28
|
+
i.ok ? (this.requestSent = !0, this.$emit("success", this.email)) : e({
|
|
29
|
+
text: i.error || "Failed to send reset email",
|
|
30
|
+
status: r.error
|
|
31
|
+
});
|
|
32
|
+
} catch {
|
|
33
|
+
e({
|
|
34
|
+
text: "An unexpected error occurred",
|
|
35
|
+
status: r.error
|
|
36
|
+
});
|
|
37
|
+
} finally {
|
|
38
|
+
this.isSubmitting = !1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
//#endregion
|
|
45
|
+
export { i as default };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=RequestPasswordReset.vue_vue_type_script_lang.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RequestPasswordReset.vue_vue_type_script_lang.mjs","names":[],"sources":["../../../src/components/auth/RequestPasswordReset.vue"],"sourcesContent":["<template>\n <v-card>\n <v-card-title class=\"text-h5 bg-grey-lighten-2\">\n Reset Password\n </v-card-title>\n\n <v-card-text class=\"pa-6\">\n <v-form v-if=\"!requestSent\" @submit.prevent=\"handleSubmit\">\n <p class=\"mb-4\">\n Enter your email address and we'll send you a link to reset your password.\n </p>\n\n <v-text-field\n v-model=\"email\"\n name=\"email\"\n label=\"Email address\"\n type=\"email\"\n prepend-icon=\"mdi-email\"\n :error=\"emailError\"\n :hint=\"emailHint\"\n :disabled=\"isSubmitting\"\n @blur=\"validateEmail\"\n ></v-text-field>\n\n <v-btn\n type=\"submit\"\n color=\"primary\"\n class=\"mt-4\"\n :loading=\"isSubmitting\"\n :disabled=\"!email || emailError\"\n block\n >\n <v-icon start>mdi-email-send</v-icon>\n Send Reset Link\n </v-btn>\n </v-form>\n\n <!-- Success message -->\n <div v-else class=\"text-center\">\n <v-icon color=\"success\" size=\"64\" class=\"mb-4\">mdi-email-check</v-icon>\n <h3 class=\"mb-2\">Check Your Email</h3>\n <p>\n If an account exists with <strong>{{ email }}</strong>, you will receive a password\n reset link shortly.\n </p>\n <p class=\"text-caption mt-4\">Didn't receive an email? Check your spam folder.</p>\n </div>\n </v-card-text>\n\n <v-card-actions v-if=\"!requestSent\">\n <slot name=\"back-action\">\n <!-- External apps can provide their own back button -->\n <v-btn variant=\"text\" @click=\"$emit('cancel')\">\n Cancel\n </v-btn>\n </slot>\n <v-spacer></v-spacer>\n </v-card-actions>\n </v-card>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport { requestPasswordReset } from '../../services/authAPI';\nimport { alertUser } from '../SnackbarService';\nimport { Status } from '@vue-skuilder/common';\n\nexport default defineComponent({\n name: 'RequestPasswordReset',\n\n emits: ['cancel', 'success'],\n\n data() {\n return {\n email: '',\n emailError: false,\n emailHint: '',\n isSubmitting: false,\n requestSent: false,\n };\n },\n\n methods: {\n validateEmail() {\n this.emailError = false;\n this.emailHint = '';\n\n if (!this.email) return;\n\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (!emailRegex.test(this.email)) {\n this.emailError = true;\n this.emailHint = 'Please enter a valid email address';\n }\n },\n\n async handleSubmit() {\n this.validateEmail();\n\n if (this.emailError || !this.email) {\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n // Pass current origin for correct reset link in email\n const origin = typeof window !== 'undefined' ? window.location.origin : undefined;\n const result = await requestPasswordReset(this.email, origin);\n\n if (result.ok) {\n this.requestSent = true;\n this.$emit('success', this.email);\n } else {\n alertUser({\n text: result.error || 'Failed to send reset email',\n status: Status.error,\n });\n }\n } catch (error) {\n alertUser({\n text: 'An unexpected error occurred',\n status: Status.error,\n });\n } finally {\n this.isSubmitting = false;\n }\n },\n },\n});\n</script>\n"],"mappings":";;;;;;AAmEA,IAAA,IAAe,EAAgB;CAC7B,MAAM;CAEN,OAAO,CAAC,UAAU,UAAU;CAE5B,OAAO;AACL,SAAO;GACL,OAAO;GACP,YAAY;GACZ,WAAW;GACX,cAAc;GACd,aAAa;GACd;;CAGH,SAAS;EACP,gBAAgB;AACd,QAAK,aAAa,IAClB,KAAK,YAAY,IAEZ,KAAK,UAES,6BACH,KAAK,KAAK,MAAM,KAC9B,KAAK,aAAa,IAClB,KAAK,YAAY;;EAIrB,MAAM,eAAe;AACnB,YAAK,eAAe,EAEhB,OAAK,cAAc,CAAC,KAAK,QAI7B;SAAK,eAAe;AAEpB,QAAI;KAEF,IAAM,IAAS,OAAO,SAAW,MAAc,OAAO,SAAS,SAAS,KAAA,GAClE,IAAS,MAAM,EAAqB,KAAK,OAAO,EAAO;AAE7D,KAAI,EAAO,MACT,KAAK,cAAc,IACnB,KAAK,MAAM,WAAW,KAAK,MAAM,IAEjC,EAAU;MACR,MAAM,EAAO,SAAS;MACtB,QAAQ,EAAO;MAChB,CAAC;YAEU;AACd,OAAU;MACR,MAAM;MACN,QAAQ,EAAO;MAChB,CAAC;cACM;AACR,UAAK,eAAe;;;;EAGzB;CACF,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import "../../_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import e from "../../_virtual/_plugin-vue_export-helper.mjs";
|
|
3
|
+
import t from "./ResetPassword.vue_vue_type_script_lang.mjs";
|
|
4
|
+
import { createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createTextVNode as o, createVNode as s, openBlock as c, renderSlot as l, resolveComponent as u, withCtx as d, withModifiers as f } from "vue";
|
|
5
|
+
//#region src/components/auth/ResetPassword.vue
|
|
6
|
+
var p = {
|
|
7
|
+
key: 1,
|
|
8
|
+
class: "text-center"
|
|
9
|
+
};
|
|
10
|
+
function _sfc_render(e, t, m, h, g, _) {
|
|
11
|
+
let v = u("v-card-title"), y = u("v-text-field"), b = u("v-icon"), x = u("v-btn"), S = u("v-form"), C = u("v-card-text"), w = u("v-spacer"), T = u("v-card-actions"), E = u("v-card"), D = u("v-col"), O = u("v-row"), k = u("v-container");
|
|
12
|
+
return c(), n(k, {
|
|
13
|
+
class: "fill-height",
|
|
14
|
+
fluid: ""
|
|
15
|
+
}, {
|
|
16
|
+
default: d(() => [s(O, {
|
|
17
|
+
align: "center",
|
|
18
|
+
justify: "center"
|
|
19
|
+
}, {
|
|
20
|
+
default: d(() => [s(D, {
|
|
21
|
+
cols: "12",
|
|
22
|
+
sm: "8",
|
|
23
|
+
md: "6"
|
|
24
|
+
}, {
|
|
25
|
+
default: d(() => [s(E, null, {
|
|
26
|
+
default: d(() => [
|
|
27
|
+
s(v, { class: "text-h5 bg-grey-lighten-2" }, {
|
|
28
|
+
default: d(() => t[4] || (t[4] = [o(" Set New Password ")])),
|
|
29
|
+
_: 1
|
|
30
|
+
}),
|
|
31
|
+
s(C, { class: "pa-6" }, {
|
|
32
|
+
default: d(() => [e.isComplete ? (c(), i("div", p, [
|
|
33
|
+
s(b, {
|
|
34
|
+
color: "success",
|
|
35
|
+
size: "64",
|
|
36
|
+
class: "mb-4"
|
|
37
|
+
}, {
|
|
38
|
+
default: d(() => t[8] || (t[8] = [o("mdi-check-circle")])),
|
|
39
|
+
_: 1
|
|
40
|
+
}),
|
|
41
|
+
t[9] || (t[9] = a("h3", { class: "mb-2" }, "Password Reset Successful!", -1)),
|
|
42
|
+
t[10] || (t[10] = a("p", null, "Your password has been updated. You can now log in with your new password.", -1))
|
|
43
|
+
])) : (c(), n(S, {
|
|
44
|
+
key: 0,
|
|
45
|
+
onSubmit: f(e.handleSubmit, ["prevent"])
|
|
46
|
+
}, {
|
|
47
|
+
default: d(() => [
|
|
48
|
+
t[7] || (t[7] = a("p", { class: "mb-4" }, "Enter your new password below.", -1)),
|
|
49
|
+
s(y, {
|
|
50
|
+
modelValue: e.password,
|
|
51
|
+
"onUpdate:modelValue": t[0] || (t[0] = (t) => e.password = t),
|
|
52
|
+
"prepend-icon": "mdi-lock",
|
|
53
|
+
name: "password",
|
|
54
|
+
label: "New password",
|
|
55
|
+
min: "4",
|
|
56
|
+
"append-icon": e.passwordVisible ? "mdi-eye-off" : "mdi-eye",
|
|
57
|
+
type: e.passwordVisible ? "text" : "password",
|
|
58
|
+
disabled: e.isSubmitting,
|
|
59
|
+
"onClick:append": t[1] || (t[1] = () => e.passwordVisible = !e.passwordVisible)
|
|
60
|
+
}, null, 8, [
|
|
61
|
+
"modelValue",
|
|
62
|
+
"append-icon",
|
|
63
|
+
"type",
|
|
64
|
+
"disabled"
|
|
65
|
+
]),
|
|
66
|
+
s(y, {
|
|
67
|
+
modelValue: e.confirmPassword,
|
|
68
|
+
"onUpdate:modelValue": t[2] || (t[2] = (t) => e.confirmPassword = t),
|
|
69
|
+
"prepend-icon": "mdi-lock",
|
|
70
|
+
name: "confirmPassword",
|
|
71
|
+
label: "Confirm new password",
|
|
72
|
+
min: "4",
|
|
73
|
+
type: e.passwordVisible ? "text" : "password",
|
|
74
|
+
error: e.confirmPasswordError,
|
|
75
|
+
hint: e.confirmPasswordHint,
|
|
76
|
+
disabled: e.isSubmitting,
|
|
77
|
+
onBlur: e.validateConfirmPassword
|
|
78
|
+
}, null, 8, [
|
|
79
|
+
"modelValue",
|
|
80
|
+
"type",
|
|
81
|
+
"error",
|
|
82
|
+
"hint",
|
|
83
|
+
"disabled",
|
|
84
|
+
"onBlur"
|
|
85
|
+
]),
|
|
86
|
+
s(x, {
|
|
87
|
+
type: "submit",
|
|
88
|
+
color: "primary",
|
|
89
|
+
class: "mt-4",
|
|
90
|
+
loading: e.isSubmitting,
|
|
91
|
+
disabled: !e.canSubmit,
|
|
92
|
+
block: ""
|
|
93
|
+
}, {
|
|
94
|
+
default: d(() => [s(b, { start: "" }, {
|
|
95
|
+
default: d(() => t[5] || (t[5] = [o("mdi-lock-reset")])),
|
|
96
|
+
_: 1
|
|
97
|
+
}), t[6] || (t[6] = o(" Reset Password "))]),
|
|
98
|
+
_: 1
|
|
99
|
+
}, 8, ["loading", "disabled"])
|
|
100
|
+
]),
|
|
101
|
+
_: 1
|
|
102
|
+
}, 8, ["onSubmit"]))]),
|
|
103
|
+
_: 1
|
|
104
|
+
}),
|
|
105
|
+
e.isComplete ? (c(), n(T, { key: 0 }, {
|
|
106
|
+
default: d(() => [s(w), l(e.$slots, "success-action", {}, () => [s(x, {
|
|
107
|
+
color: "primary",
|
|
108
|
+
onClick: t[3] || (t[3] = (t) => e.$emit("complete"))
|
|
109
|
+
}, {
|
|
110
|
+
default: d(() => t[11] || (t[11] = [o(" Continue to Login ")])),
|
|
111
|
+
_: 1
|
|
112
|
+
})])]),
|
|
113
|
+
_: 3
|
|
114
|
+
})) : r("", !0)
|
|
115
|
+
]),
|
|
116
|
+
_: 3
|
|
117
|
+
})]),
|
|
118
|
+
_: 3
|
|
119
|
+
})]),
|
|
120
|
+
_: 3
|
|
121
|
+
})]),
|
|
122
|
+
_: 3
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
var m = /* @__PURE__ */ e(t, [["render", _sfc_render]]);
|
|
126
|
+
//#endregion
|
|
127
|
+
export { m as default };
|
|
128
|
+
|
|
129
|
+
//# sourceMappingURL=ResetPassword.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResetPassword.mjs","names":[],"sources":["../../../src/components/auth/ResetPassword.vue"],"sourcesContent":["<template>\n <v-container class=\"fill-height\" fluid>\n <v-row align=\"center\" justify=\"center\">\n <v-col cols=\"12\" sm=\"8\" md=\"6\">\n <v-card>\n <v-card-title class=\"text-h5 bg-grey-lighten-2\">\n Set New Password\n </v-card-title>\n\n <v-card-text class=\"pa-6\">\n <v-form v-if=\"!isComplete\" @submit.prevent=\"handleSubmit\">\n <p class=\"mb-4\">Enter your new password below.</p>\n\n <v-text-field\n v-model=\"password\"\n prepend-icon=\"mdi-lock\"\n name=\"password\"\n label=\"New password\"\n min=\"4\"\n :append-icon=\"passwordVisible ? 'mdi-eye-off' : 'mdi-eye'\"\n :type=\"passwordVisible ? 'text' : 'password'\"\n :disabled=\"isSubmitting\"\n @click:append=\"() => (passwordVisible = !passwordVisible)\"\n ></v-text-field>\n\n <v-text-field\n v-model=\"confirmPassword\"\n prepend-icon=\"mdi-lock\"\n name=\"confirmPassword\"\n label=\"Confirm new password\"\n min=\"4\"\n :type=\"passwordVisible ? 'text' : 'password'\"\n :error=\"confirmPasswordError\"\n :hint=\"confirmPasswordHint\"\n :disabled=\"isSubmitting\"\n @blur=\"validateConfirmPassword\"\n ></v-text-field>\n\n <v-btn\n type=\"submit\"\n color=\"primary\"\n class=\"mt-4\"\n :loading=\"isSubmitting\"\n :disabled=\"!canSubmit\"\n block\n >\n <v-icon start>mdi-lock-reset</v-icon>\n Reset Password\n </v-btn>\n </v-form>\n\n <!-- Success state -->\n <div v-else class=\"text-center\">\n <v-icon color=\"success\" size=\"64\" class=\"mb-4\">mdi-check-circle</v-icon>\n <h3 class=\"mb-2\">Password Reset Successful!</h3>\n <p>Your password has been updated. You can now log in with your new password.</p>\n </div>\n </v-card-text>\n\n <v-card-actions v-if=\"isComplete\">\n <v-spacer></v-spacer>\n <slot name=\"success-action\">\n <!-- External apps can provide their own navigation -->\n <v-btn color=\"primary\" @click=\"$emit('complete')\">\n Continue to Login\n </v-btn>\n </slot>\n </v-card-actions>\n </v-card>\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport { resetPassword } from '../../services/authAPI';\nimport { alertUser } from '../SnackbarService';\nimport { Status } from '@vue-skuilder/common';\n\nexport default defineComponent({\n name: 'ResetPassword',\n\n emits: ['complete', 'error'],\n\n props: {\n /**\n * Reset token. If not provided, will try to read from URL query params.\n */\n token: {\n type: String,\n default: null,\n },\n },\n\n data() {\n return {\n password: '',\n confirmPassword: '',\n passwordVisible: false,\n confirmPasswordError: false,\n confirmPasswordHint: '',\n isSubmitting: false,\n isComplete: false,\n };\n },\n\n computed: {\n canSubmit(): boolean {\n return (\n this.password.length >= 4 &&\n this.confirmPassword.length >= 4 &&\n this.password === this.confirmPassword &&\n !this.confirmPasswordError\n );\n },\n },\n\n methods: {\n validateConfirmPassword() {\n this.confirmPasswordError = false;\n this.confirmPasswordHint = '';\n\n if (!this.confirmPassword) return;\n\n if (this.password !== this.confirmPassword) {\n this.confirmPasswordError = true;\n this.confirmPasswordHint = 'Passwords do not match';\n }\n },\n\n async handleSubmit() {\n this.validateConfirmPassword();\n\n if (!this.canSubmit) {\n return;\n }\n\n // Get token from prop or URL query params\n const token = this.token || this.getTokenFromURL();\n\n if (!token) {\n alertUser({\n text: 'No reset token provided. Please use the link from your email.',\n status: Status.error,\n });\n this.$emit('error', 'No token');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n const result = await resetPassword(token, this.password);\n\n if (result.ok) {\n this.isComplete = true;\n alertUser({\n text: 'Password reset successfully!',\n status: Status.ok,\n });\n } else {\n alertUser({\n text: result.error || 'Failed to reset password',\n status: Status.error,\n });\n this.$emit('error', result.error);\n }\n } catch (error) {\n alertUser({\n text: 'An unexpected error occurred',\n status: Status.error,\n });\n this.$emit('error', 'Unexpected error');\n } finally {\n this.isSubmitting = false;\n }\n },\n\n getTokenFromURL(): string | null {\n if (typeof window === 'undefined') return null;\n\n const params = new URLSearchParams(window.location.search);\n return params.get('token');\n },\n },\n});\n</script>\n"],"mappings":";;;;;;CAAA,KAAA;CAoDwB,OAAM;;;;aAnD5B,EAsEc,GAAA;EAtED,OAAM;EAAc,OAAA;;EADnC,SAAA,QAsEY,CApER,EAoEQ,GAAA;GApED,OAAM;GAAS,SAAQ;;GAFlC,SAAA,QAqEc,CAlER,EAkEQ,GAAA;IAlED,MAAK;IAAK,IAAG;IAAI,IAAG;;IAHjC,SAAA,QAoEiB,CAhET,EAgES,GAAA,MAAA;KApEjB,SAAA,QAOyB;MAFf,EAEe,GAAA,EAFD,OAAM,6BAA2B,EAAA;OALzD,SAAA,QAOU,EAAA,OAAA,EAAA,KAAA,CAPV,EAK0D,qBAEhD,CAAA,EAAA;OAPV,GAAA;;MASU,EAgDc,GAAA,EAhDD,OAAM,QAAM,EAAA;OATnC,SAAA,QAiDqB,CAvCM,EAAA,mBA0Cf,EAIM,OAJN,GAIM;QAHJ,EAAwE,GAAA;SAAhE,OAAM;SAAU,MAAK;SAAK,OAAM;;SArDtD,SAAA,QAqD6E,EAAA,OAAA,EAAA,KAAA,CArD7E,EAqD6D,mBAAgB,CAAA,EAAA;SArD7E,GAAA;;wBAsDc,EAAgD,MAAA,EAA5C,OAAM,QAAM,EAAC,8BAA0B,GAAA;0BAC3C,EAAiF,KAAA,MAA9E,8EAA0E,GAAA;cA7ChE,GAAA,EAAf,EAuCS,GAAA;QAjDrB,KAAA;QAUwC,UAVxC,EAUwD,EAAA,cAAY,CAAA,UAAA,CAAA;;QAVpE,SAAA,QAWgE;yBAAlD,EAAkD,KAAA,EAA/C,OAAM,QAAM,EAAC,kCAA8B,GAAA;SAE9C,EAUgB,GAAA;UAvB9B,YAcyB,EAAA;UAdzB,uBAAA,EAAA,OAAA,EAAA,MAAA,MAAA,EAcyB,WAAQ;UACjB,gBAAa;UACb,MAAK;UACL,OAAM;UACN,KAAI;UACH,eAAa,EAAA,kBAAe,gBAAA;UAC5B,MAAM,EAAA,kBAAe,SAAA;UACrB,UAAU,EAAA;UACV,kBAAY,EAAA,OAAA,EAAA,WAAS,EAAA,kBAAe,CAAI,EAAA;;;;;;;SAG3C,EAWgB,GAAA;UApC9B,YA0ByB,EAAA;UA1BzB,uBAAA,EAAA,OAAA,EAAA,MAAA,MAAA,EA0ByB,kBAAe;UACxB,gBAAa;UACb,MAAK;UACL,OAAM;UACN,KAAI;UACH,MAAM,EAAA,kBAAe,SAAA;UACrB,OAAO,EAAA;UACP,MAAM,EAAA;UACN,UAAU,EAAA;UACV,QAAM,EAAA;;;;;;;;;SAGT,EAUQ,GAAA;UATN,MAAK;UACL,OAAM;UACN,OAAM;UACL,SAAS,EAAA;UACT,UAAQ,CAAG,EAAA;UACZ,OAAA;;UA5ChB,SAAA,QA8CqD,CAArC,EAAqC,GAAA,EAA7B,OAAA,IAAK,EAAA;WA9C7B,SAAA,QA8C4C,EAAA,OAAA,EAAA,KAAA,CA9C5C,EA8C8B,iBAAc,CAAA,EAAA;WA9C5C,GAAA;8BAAA,EA8CqD,mBAEvC,EAAA,CAAA;UAhDd,GAAA;;;QAAA,GAAA;;OAAA,GAAA;;MA2DgC,EAAA,cAAA,GAAA,EAAtB,EAQiB,GAAA,EAnE3B,KAAA,GAAA,EAAA;OAAA,SAAA,QA4DiC,CAArB,EAAqB,EAAA,EACrB,EAKO,EAAA,QAAA,kBAAA,EAAA,QAAA,CAHL,EAEQ,GAAA;QAFD,OAAM;QAAW,SAAK,EAAA,OAAA,EAAA,MAAA,MAAE,EAAA,MAAK,WAAA;;QA/DlD,SAAA,QAiEc,EAAA,QAAA,EAAA,MAAA,CAjEd,EA+DgE,sBAElD,CAAA,EAAA;QAjEd,GAAA;;OAAA,GAAA;YAAA,EAAA,IAAA,GAAA;;KAAA,GAAA;;IAAA,GAAA;;GAAA,GAAA;;EAAA,GAAA"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import "../../_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { alertUser as e } from "../SnackbarService.mjs";
|
|
3
|
+
import { resetPassword as t } from "../../services/authAPI.mjs";
|
|
4
|
+
import { defineComponent as n } from "vue";
|
|
5
|
+
import { Status as r } from "@vue-skuilder/common";
|
|
6
|
+
//#region src/components/auth/ResetPassword.vue?vue&type=script&lang.ts
|
|
7
|
+
var i = n({
|
|
8
|
+
name: "ResetPassword",
|
|
9
|
+
emits: ["complete", "error"],
|
|
10
|
+
props: { token: {
|
|
11
|
+
type: String,
|
|
12
|
+
default: null
|
|
13
|
+
} },
|
|
14
|
+
data() {
|
|
15
|
+
return {
|
|
16
|
+
password: "",
|
|
17
|
+
confirmPassword: "",
|
|
18
|
+
passwordVisible: !1,
|
|
19
|
+
confirmPasswordError: !1,
|
|
20
|
+
confirmPasswordHint: "",
|
|
21
|
+
isSubmitting: !1,
|
|
22
|
+
isComplete: !1
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
computed: { canSubmit() {
|
|
26
|
+
return this.password.length >= 4 && this.confirmPassword.length >= 4 && this.password === this.confirmPassword && !this.confirmPasswordError;
|
|
27
|
+
} },
|
|
28
|
+
methods: {
|
|
29
|
+
validateConfirmPassword() {
|
|
30
|
+
this.confirmPasswordError = !1, this.confirmPasswordHint = "", this.confirmPassword && this.password !== this.confirmPassword && (this.confirmPasswordError = !0, this.confirmPasswordHint = "Passwords do not match");
|
|
31
|
+
},
|
|
32
|
+
async handleSubmit() {
|
|
33
|
+
if (this.validateConfirmPassword(), !this.canSubmit) return;
|
|
34
|
+
let n = this.token || this.getTokenFromURL();
|
|
35
|
+
if (!n) {
|
|
36
|
+
e({
|
|
37
|
+
text: "No reset token provided. Please use the link from your email.",
|
|
38
|
+
status: r.error
|
|
39
|
+
}), this.$emit("error", "No token");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.isSubmitting = !0;
|
|
43
|
+
try {
|
|
44
|
+
let i = await t(n, this.password);
|
|
45
|
+
i.ok ? (this.isComplete = !0, e({
|
|
46
|
+
text: "Password reset successfully!",
|
|
47
|
+
status: r.ok
|
|
48
|
+
})) : (e({
|
|
49
|
+
text: i.error || "Failed to reset password",
|
|
50
|
+
status: r.error
|
|
51
|
+
}), this.$emit("error", i.error));
|
|
52
|
+
} catch {
|
|
53
|
+
e({
|
|
54
|
+
text: "An unexpected error occurred",
|
|
55
|
+
status: r.error
|
|
56
|
+
}), this.$emit("error", "Unexpected error");
|
|
57
|
+
} finally {
|
|
58
|
+
this.isSubmitting = !1;
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
getTokenFromURL() {
|
|
62
|
+
return typeof window > "u" ? null : new URLSearchParams(window.location.search).get("token");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
//#endregion
|
|
67
|
+
export { i as default };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=ResetPassword.vue_vue_type_script_lang.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResetPassword.vue_vue_type_script_lang.mjs","names":[],"sources":["../../../src/components/auth/ResetPassword.vue"],"sourcesContent":["<template>\n <v-container class=\"fill-height\" fluid>\n <v-row align=\"center\" justify=\"center\">\n <v-col cols=\"12\" sm=\"8\" md=\"6\">\n <v-card>\n <v-card-title class=\"text-h5 bg-grey-lighten-2\">\n Set New Password\n </v-card-title>\n\n <v-card-text class=\"pa-6\">\n <v-form v-if=\"!isComplete\" @submit.prevent=\"handleSubmit\">\n <p class=\"mb-4\">Enter your new password below.</p>\n\n <v-text-field\n v-model=\"password\"\n prepend-icon=\"mdi-lock\"\n name=\"password\"\n label=\"New password\"\n min=\"4\"\n :append-icon=\"passwordVisible ? 'mdi-eye-off' : 'mdi-eye'\"\n :type=\"passwordVisible ? 'text' : 'password'\"\n :disabled=\"isSubmitting\"\n @click:append=\"() => (passwordVisible = !passwordVisible)\"\n ></v-text-field>\n\n <v-text-field\n v-model=\"confirmPassword\"\n prepend-icon=\"mdi-lock\"\n name=\"confirmPassword\"\n label=\"Confirm new password\"\n min=\"4\"\n :type=\"passwordVisible ? 'text' : 'password'\"\n :error=\"confirmPasswordError\"\n :hint=\"confirmPasswordHint\"\n :disabled=\"isSubmitting\"\n @blur=\"validateConfirmPassword\"\n ></v-text-field>\n\n <v-btn\n type=\"submit\"\n color=\"primary\"\n class=\"mt-4\"\n :loading=\"isSubmitting\"\n :disabled=\"!canSubmit\"\n block\n >\n <v-icon start>mdi-lock-reset</v-icon>\n Reset Password\n </v-btn>\n </v-form>\n\n <!-- Success state -->\n <div v-else class=\"text-center\">\n <v-icon color=\"success\" size=\"64\" class=\"mb-4\">mdi-check-circle</v-icon>\n <h3 class=\"mb-2\">Password Reset Successful!</h3>\n <p>Your password has been updated. You can now log in with your new password.</p>\n </div>\n </v-card-text>\n\n <v-card-actions v-if=\"isComplete\">\n <v-spacer></v-spacer>\n <slot name=\"success-action\">\n <!-- External apps can provide their own navigation -->\n <v-btn color=\"primary\" @click=\"$emit('complete')\">\n Continue to Login\n </v-btn>\n </slot>\n </v-card-actions>\n </v-card>\n </v-col>\n </v-row>\n </v-container>\n</template>\n\n<script lang=\"ts\">\nimport { defineComponent } from 'vue';\nimport { resetPassword } from '../../services/authAPI';\nimport { alertUser } from '../SnackbarService';\nimport { Status } from '@vue-skuilder/common';\n\nexport default defineComponent({\n name: 'ResetPassword',\n\n emits: ['complete', 'error'],\n\n props: {\n /**\n * Reset token. If not provided, will try to read from URL query params.\n */\n token: {\n type: String,\n default: null,\n },\n },\n\n data() {\n return {\n password: '',\n confirmPassword: '',\n passwordVisible: false,\n confirmPasswordError: false,\n confirmPasswordHint: '',\n isSubmitting: false,\n isComplete: false,\n };\n },\n\n computed: {\n canSubmit(): boolean {\n return (\n this.password.length >= 4 &&\n this.confirmPassword.length >= 4 &&\n this.password === this.confirmPassword &&\n !this.confirmPasswordError\n );\n },\n },\n\n methods: {\n validateConfirmPassword() {\n this.confirmPasswordError = false;\n this.confirmPasswordHint = '';\n\n if (!this.confirmPassword) return;\n\n if (this.password !== this.confirmPassword) {\n this.confirmPasswordError = true;\n this.confirmPasswordHint = 'Passwords do not match';\n }\n },\n\n async handleSubmit() {\n this.validateConfirmPassword();\n\n if (!this.canSubmit) {\n return;\n }\n\n // Get token from prop or URL query params\n const token = this.token || this.getTokenFromURL();\n\n if (!token) {\n alertUser({\n text: 'No reset token provided. Please use the link from your email.',\n status: Status.error,\n });\n this.$emit('error', 'No token');\n return;\n }\n\n this.isSubmitting = true;\n\n try {\n const result = await resetPassword(token, this.password);\n\n if (result.ok) {\n this.isComplete = true;\n alertUser({\n text: 'Password reset successfully!',\n status: Status.ok,\n });\n } else {\n alertUser({\n text: result.error || 'Failed to reset password',\n status: Status.error,\n });\n this.$emit('error', result.error);\n }\n } catch (error) {\n alertUser({\n text: 'An unexpected error occurred',\n status: Status.error,\n });\n this.$emit('error', 'Unexpected error');\n } finally {\n this.isSubmitting = false;\n }\n },\n\n getTokenFromURL(): string | null {\n if (typeof window === 'undefined') return null;\n\n const params = new URLSearchParams(window.location.search);\n return params.get('token');\n },\n },\n});\n</script>\n"],"mappings":";;;;;;AAgFA,IAAA,IAAe,EAAgB;CAC7B,MAAM;CAEN,OAAO,CAAC,YAAY,QAAQ;CAE5B,OAAO,EAIL,OAAO;EACL,MAAM;EACN,SAAS;EACV,EACF;CAED,OAAO;AACL,SAAO;GACL,UAAU;GACV,iBAAiB;GACjB,iBAAiB;GACjB,sBAAsB;GACtB,qBAAqB;GACrB,cAAc;GACd,YAAY;GACb;;CAGH,UAAU,EACR,YAAqB;AACnB,SACE,KAAK,SAAS,UAAU,KACxB,KAAK,gBAAgB,UAAU,KAC/B,KAAK,aAAa,KAAK,mBACvB,CAAC,KAAK;IAGX;CAED,SAAS;EACP,0BAA0B;AACxB,QAAK,uBAAuB,IAC5B,KAAK,sBAAsB,IAEtB,KAAK,mBAEN,KAAK,aAAa,KAAK,oBACzB,KAAK,uBAAuB,IAC5B,KAAK,sBAAsB;;EAI/B,MAAM,eAAe;AAGnB,OAFA,KAAK,yBAAyB,EAE1B,CAAC,KAAK,UACR;GAIF,IAAM,IAAQ,KAAK,SAAS,KAAK,iBAAiB;AAElD,OAAI,CAAC,GAAO;AAKV,IAJA,EAAU;KACR,MAAM;KACN,QAAQ,EAAO;KAChB,CAAC,EACF,KAAK,MAAM,SAAS,WAAW;AAC/B;;AAGF,QAAK,eAAe;AAEpB,OAAI;IACF,IAAM,IAAS,MAAM,EAAc,GAAO,KAAK,SAAS;AAExD,IAAI,EAAO,MACT,KAAK,aAAa,IAClB,EAAU;KACR,MAAM;KACN,QAAQ,EAAO;KAChB,CAAC,KAEF,EAAU;KACR,MAAM,EAAO,SAAS;KACtB,QAAQ,EAAO;KAChB,CAAC,EACF,KAAK,MAAM,SAAS,EAAO,MAAM;WAErB;AAKd,IAJA,EAAU;KACR,MAAM;KACN,QAAQ,EAAO;KAChB,CAAC,EACF,KAAK,MAAM,SAAS,mBAAmB;aAC/B;AACR,SAAK,eAAe;;;EAIxB,kBAAiC;AAI/B,UAHI,OAAO,SAAW,MAAoB,OAE3B,IAAI,gBAAgB,OAAO,SAAS,OAAO,CAC5C,IAAI,QAAQ;;EAE7B;CACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import e from "../../_virtual/_plugin-vue_export-helper.mjs";
|
|
2
|
+
import t from "./UserChip.vue_vue_type_script_setup_true_lang.mjs";
|
|
3
|
+
/* empty css */
|
|
4
|
+
//#region src/components/auth/UserChip.vue
|
|
5
|
+
var n = /* @__PURE__ */ e(t, [["__scopeId", "data-v-9a38a213"]]);
|
|
6
|
+
//#endregion
|
|
7
|
+
export { n as default };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=UserChip.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserChip.mjs","names":[],"sources":["../../../src/components/auth/UserChip.vue"],"sourcesContent":["<template>\n <v-badge :content=\"items.length\" :model-value=\"hasNewItems\" color=\"accent\" location=\"end top\">\n <v-menu location=\"bottom end\" transition=\"scale-transition\">\n <template #activator=\"{ props }\">\n <v-chip v-bind=\"props\" class=\"ma-2\">\n <v-avatar start class=\"bg-primary\">\n <v-icon>mdi-school</v-icon>\n </v-avatar>\n {{ username }}\n </v-chip>\n </template>\n\n <v-list>\n <v-list-item v-for=\"item in items\" :key=\"item\" @click=\"dismiss(item)\">\n <v-list-item-title>{{ item }}</v-list-item-title>\n </v-list-item>\n\n <v-divider v-if=\"items.length\" />\n\n <v-list-item @click=\"gotoStats\">\n <template #prepend>\n <v-icon>mdi-trending-up</v-icon>\n </template>\n <v-list-item-title>Stats</v-list-item-title>\n </v-list-item>\n\n <v-list-item @click=\"gotoSettings\">\n <template #prepend>\n <v-icon>mdi-cog</v-icon>\n </template>\n <v-list-item-title>Settings</v-list-item-title>\n </v-list-item>\n\n <v-list-item v-if=\"authUIConfig.showLogout\" @click=\"logout\">\n <template #prepend>\n <v-icon>mdi-logout</v-icon>\n </template>\n <v-list-item-title>{{ authUIConfig.logoutLabel }}</v-list-item-title>\n </v-list-item>\n\n <v-list-item v-if=\"authUIConfig.showResetData\" @click=\"showResetDialog = true\">\n <template #prepend>\n <v-icon>mdi-delete-sweep</v-icon>\n </template>\n <v-list-item-title>{{ authUIConfig.resetLabel }}</v-list-item-title>\n </v-list-item>\n </v-list>\n </v-menu>\n </v-badge>\n\n <!-- Reset Confirmation Dialog -->\n <v-dialog v-model=\"showResetDialog\" max-width=\"500px\" persistent>\n <v-card>\n <v-card-title class=\"text-h5 d-flex align-center\">\n <v-icon color=\"warning\" class=\"mr-3\">mdi-alert-circle</v-icon>\n Reset All User Data\n </v-card-title>\n \n <v-card-text>\n <p class=\"mb-4\">This will permanently delete:</p>\n <ul class=\"mb-4\">\n <li>All course progress and history</li>\n <li>Scheduled card reviews</li>\n <li>Course registrations</li>\n <li>User preferences</li>\n </ul>\n <p class=\"mb-4 text-error font-weight-bold\">This cannot be undone.</p>\n \n <v-text-field\n v-model=\"confirmationText\"\n label='Type \"reset\" to confirm'\n outlined\n dense\n @keyup.enter=\"isConfirmationValid && executeReset()\"\n />\n </v-card-text>\n \n <v-card-actions>\n <v-spacer />\n <v-btn text @click=\"resetDialogState\">Cancel</v-btn>\n <v-btn \n color=\"error\" \n :disabled=\"!isConfirmationValid\"\n @click=\"executeReset\"\n >\n Reset All Data\n </v-btn>\n </v-card-actions>\n </v-card>\n </v-dialog>\n</template>\n\n<script lang=\"ts\" setup>\nimport { ref, computed, onMounted } from 'vue';\nimport { useRouter } from 'vue-router';\nimport { getCurrentUser, useAuthStore } from '../../stores/useAuthStore';\nimport { useConfigStore } from '../../stores/useConfigStore';\nimport { useAuthUI } from '../../composables/useAuthUI';\n\n// Define props (even if not used, prevents warnings)\ndefineProps<{\n showLoginButton?: boolean;\n redirectToPath?: string;\n}>();\n\nconst router = useRouter();\nconst authStore = useAuthStore();\nconst configStore = useConfigStore();\nconst authUI = useAuthUI();\n\nconst username = ref('');\nconst items = ref<string[]>([]);\n\n// Reset confirmation dialog state\nconst showResetDialog = ref(false);\nconst confirmationText = ref('');\n\nconst isConfirmationValid = computed(() => confirmationText.value === 'reset');\n\nconst resetDialogState = () => {\n confirmationText.value = '';\n showResetDialog.value = false;\n};\n\nconst hasNewItems = computed(() => items.value.length > 0);\n\nconst authUIConfig = computed(() => {\n const configValue = authUI.config.value;\n const fallback = {\n showLoginRegistration: true,\n showLogout: true,\n showResetData: false,\n logoutLabel: 'Log out',\n resetLabel: '',\n };\n \n return configValue || fallback;\n});\n\nonMounted(async () => {\n const user = await getCurrentUser();\n username.value = user.getUsername();\n \n // Detect sync strategy for conditional UI\n await authUI.detectSyncStrategy();\n});\n\nconst gotoSettings = async () => {\n router.push(`/u/${(await getCurrentUser()).getUsername()}`);\n};\n\nconst gotoStats = async () => {\n router.push(`/u/${(await getCurrentUser()).getUsername()}/stats`);\n};\n\nconst dismiss = (item: string) => {\n const index = items.value.indexOf(item);\n items.value.splice(index, 1);\n};\n\nconst logout = async () => {\n const res = await authStore._user!.logout();\n if (res.ok) {\n authStore.loginAndRegistration = {\n init: true,\n loggedIn: false,\n regDialogOpen: false,\n loginDialogOpen: false,\n };\n\n configStore.resetDefaults();\n router.push('/home');\n }\n};\n\nconst executeReset = async () => {\n try {\n await authStore.resetUserData();\n configStore.resetDefaults();\n \n // Close dialog and navigate to home\n resetDialogState();\n router.push('/home');\n } catch (error) {\n console.error('Failed to reset user data:', error);\n // Could add a snackbar notification here\n }\n};\n</script>\n\n<style scoped>\n.component-fade-enter-active,\n.component-fade-leave-active {\n transition: opacity 0.5s ease;\n}\n.component-fade-enter,\n.component-fade-leave-to {\n opacity: 0;\n}\n</style>"],"mappings":""}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import "../../_virtual/_rolldown/runtime.mjs";
|
|
2
|
+
import { getCurrentUser as e, useAuthStore as t } from "../../stores/useAuthStore.mjs";
|
|
3
|
+
import { useConfigStore as n } from "../../stores/useConfigStore.mjs";
|
|
4
|
+
import { useAuthUI as r } from "../../composables/useAuthUI.mjs";
|
|
5
|
+
import { Fragment as i, computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, createVNode as d, defineComponent as f, mergeProps as p, onMounted as m, openBlock as h, ref as g, renderList as _, resolveComponent as v, toDisplayString as y, withCtx as b, withKeys as x } from "vue";
|
|
6
|
+
import { useRouter as S } from "vue-router";
|
|
7
|
+
//#region src/components/auth/UserChip.vue?vue&type=script&setup=true&lang.ts
|
|
8
|
+
var C = /* @__PURE__ */ f({
|
|
9
|
+
__name: "UserChip",
|
|
10
|
+
props: {
|
|
11
|
+
showLoginButton: { type: Boolean },
|
|
12
|
+
redirectToPath: {}
|
|
13
|
+
},
|
|
14
|
+
setup(f) {
|
|
15
|
+
let C = S(), w = t(), T = n(), E = r(), D = g(""), O = g([]), k = g(!1), A = g(""), j = a(() => A.value === "reset"), resetDialogState = () => {
|
|
16
|
+
A.value = "", k.value = !1;
|
|
17
|
+
}, M = a(() => O.value.length > 0), N = a(() => E.config.value || {
|
|
18
|
+
showLoginRegistration: !0,
|
|
19
|
+
showLogout: !0,
|
|
20
|
+
showResetData: !1,
|
|
21
|
+
logoutLabel: "Log out",
|
|
22
|
+
resetLabel: ""
|
|
23
|
+
});
|
|
24
|
+
m(async () => {
|
|
25
|
+
D.value = (await e()).getUsername(), await E.detectSyncStrategy();
|
|
26
|
+
});
|
|
27
|
+
let gotoSettings = async () => {
|
|
28
|
+
C.push(`/u/${(await e()).getUsername()}`);
|
|
29
|
+
}, gotoStats = async () => {
|
|
30
|
+
C.push(`/u/${(await e()).getUsername()}/stats`);
|
|
31
|
+
}, dismiss = (e) => {
|
|
32
|
+
let t = O.value.indexOf(e);
|
|
33
|
+
O.value.splice(t, 1);
|
|
34
|
+
}, logout = async () => {
|
|
35
|
+
(await w._user.logout()).ok && (w.loginAndRegistration = {
|
|
36
|
+
init: !0,
|
|
37
|
+
loggedIn: !1,
|
|
38
|
+
regDialogOpen: !1,
|
|
39
|
+
loginDialogOpen: !1
|
|
40
|
+
}, T.resetDefaults(), C.push("/home"));
|
|
41
|
+
}, executeReset = async () => {
|
|
42
|
+
try {
|
|
43
|
+
await w.resetUserData(), T.resetDefaults(), resetDialogState(), C.push("/home");
|
|
44
|
+
} catch (e) {
|
|
45
|
+
console.error("Failed to reset user data:", e);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return (e, t) => {
|
|
49
|
+
let n = v("v-icon"), r = v("v-avatar"), a = v("v-chip"), f = v("v-list-item-title"), m = v("v-list-item"), g = v("v-divider"), S = v("v-list"), C = v("v-menu"), w = v("v-badge"), T = v("v-card-title"), E = v("v-text-field"), P = v("v-card-text"), F = v("v-spacer"), I = v("v-btn"), L = v("v-card-actions"), R = v("v-card"), z = v("v-dialog");
|
|
50
|
+
return h(), c(i, null, [d(w, {
|
|
51
|
+
content: O.value.length,
|
|
52
|
+
"model-value": M.value,
|
|
53
|
+
color: "accent",
|
|
54
|
+
location: "end top"
|
|
55
|
+
}, {
|
|
56
|
+
default: b(() => [d(C, {
|
|
57
|
+
location: "bottom end",
|
|
58
|
+
transition: "scale-transition"
|
|
59
|
+
}, {
|
|
60
|
+
activator: b(({ props: e }) => [d(a, p(e, { class: "ma-2" }), {
|
|
61
|
+
default: b(() => [d(r, {
|
|
62
|
+
start: "",
|
|
63
|
+
class: "bg-primary"
|
|
64
|
+
}, {
|
|
65
|
+
default: b(() => [d(n, null, {
|
|
66
|
+
default: b(() => t[4] || (t[4] = [u("mdi-school")])),
|
|
67
|
+
_: 1
|
|
68
|
+
})]),
|
|
69
|
+
_: 1
|
|
70
|
+
}), u(" " + y(D.value), 1)]),
|
|
71
|
+
_: 2
|
|
72
|
+
}, 1040)]),
|
|
73
|
+
default: b(() => [d(S, null, {
|
|
74
|
+
default: b(() => [
|
|
75
|
+
(h(!0), c(i, null, _(O.value, (e) => (h(), o(m, {
|
|
76
|
+
key: e,
|
|
77
|
+
onClick: (t) => dismiss(e)
|
|
78
|
+
}, {
|
|
79
|
+
default: b(() => [d(f, null, {
|
|
80
|
+
default: b(() => [u(y(e), 1)]),
|
|
81
|
+
_: 2
|
|
82
|
+
}, 1024)]),
|
|
83
|
+
_: 2
|
|
84
|
+
}, 1032, ["onClick"]))), 128)),
|
|
85
|
+
O.value.length ? (h(), o(g, { key: 0 })) : s("", !0),
|
|
86
|
+
d(m, { onClick: gotoStats }, {
|
|
87
|
+
prepend: b(() => [d(n, null, {
|
|
88
|
+
default: b(() => t[5] || (t[5] = [u("mdi-trending-up")])),
|
|
89
|
+
_: 1
|
|
90
|
+
})]),
|
|
91
|
+
default: b(() => [d(f, null, {
|
|
92
|
+
default: b(() => t[6] || (t[6] = [u("Stats")])),
|
|
93
|
+
_: 1
|
|
94
|
+
})]),
|
|
95
|
+
_: 1
|
|
96
|
+
}),
|
|
97
|
+
d(m, { onClick: gotoSettings }, {
|
|
98
|
+
prepend: b(() => [d(n, null, {
|
|
99
|
+
default: b(() => t[7] || (t[7] = [u("mdi-cog")])),
|
|
100
|
+
_: 1
|
|
101
|
+
})]),
|
|
102
|
+
default: b(() => [d(f, null, {
|
|
103
|
+
default: b(() => t[8] || (t[8] = [u("Settings")])),
|
|
104
|
+
_: 1
|
|
105
|
+
})]),
|
|
106
|
+
_: 1
|
|
107
|
+
}),
|
|
108
|
+
N.value.showLogout ? (h(), o(m, {
|
|
109
|
+
key: 1,
|
|
110
|
+
onClick: logout
|
|
111
|
+
}, {
|
|
112
|
+
prepend: b(() => [d(n, null, {
|
|
113
|
+
default: b(() => t[9] || (t[9] = [u("mdi-logout")])),
|
|
114
|
+
_: 1
|
|
115
|
+
})]),
|
|
116
|
+
default: b(() => [d(f, null, {
|
|
117
|
+
default: b(() => [u(y(N.value.logoutLabel), 1)]),
|
|
118
|
+
_: 1
|
|
119
|
+
})]),
|
|
120
|
+
_: 1
|
|
121
|
+
})) : s("", !0),
|
|
122
|
+
N.value.showResetData ? (h(), o(m, {
|
|
123
|
+
key: 2,
|
|
124
|
+
onClick: t[0] || (t[0] = (e) => k.value = !0)
|
|
125
|
+
}, {
|
|
126
|
+
prepend: b(() => [d(n, null, {
|
|
127
|
+
default: b(() => t[10] || (t[10] = [u("mdi-delete-sweep")])),
|
|
128
|
+
_: 1
|
|
129
|
+
})]),
|
|
130
|
+
default: b(() => [d(f, null, {
|
|
131
|
+
default: b(() => [u(y(N.value.resetLabel), 1)]),
|
|
132
|
+
_: 1
|
|
133
|
+
})]),
|
|
134
|
+
_: 1
|
|
135
|
+
})) : s("", !0)
|
|
136
|
+
]),
|
|
137
|
+
_: 1
|
|
138
|
+
})]),
|
|
139
|
+
_: 1
|
|
140
|
+
})]),
|
|
141
|
+
_: 1
|
|
142
|
+
}, 8, ["content", "model-value"]), d(z, {
|
|
143
|
+
modelValue: k.value,
|
|
144
|
+
"onUpdate:modelValue": t[3] || (t[3] = (e) => k.value = e),
|
|
145
|
+
"max-width": "500px",
|
|
146
|
+
persistent: ""
|
|
147
|
+
}, {
|
|
148
|
+
default: b(() => [d(R, null, {
|
|
149
|
+
default: b(() => [
|
|
150
|
+
d(T, { class: "text-h5 d-flex align-center" }, {
|
|
151
|
+
default: b(() => [d(n, {
|
|
152
|
+
color: "warning",
|
|
153
|
+
class: "mr-3"
|
|
154
|
+
}, {
|
|
155
|
+
default: b(() => t[11] || (t[11] = [u("mdi-alert-circle")])),
|
|
156
|
+
_: 1
|
|
157
|
+
}), t[12] || (t[12] = u(" Reset All User Data "))]),
|
|
158
|
+
_: 1
|
|
159
|
+
}),
|
|
160
|
+
d(P, null, {
|
|
161
|
+
default: b(() => [
|
|
162
|
+
t[13] || (t[13] = l("p", { class: "mb-4" }, "This will permanently delete:", -1)),
|
|
163
|
+
t[14] || (t[14] = l("ul", { class: "mb-4" }, [
|
|
164
|
+
l("li", null, "All course progress and history"),
|
|
165
|
+
l("li", null, "Scheduled card reviews"),
|
|
166
|
+
l("li", null, "Course registrations"),
|
|
167
|
+
l("li", null, "User preferences")
|
|
168
|
+
], -1)),
|
|
169
|
+
t[15] || (t[15] = l("p", { class: "mb-4 text-error font-weight-bold" }, "This cannot be undone.", -1)),
|
|
170
|
+
d(E, {
|
|
171
|
+
modelValue: A.value,
|
|
172
|
+
"onUpdate:modelValue": t[1] || (t[1] = (e) => A.value = e),
|
|
173
|
+
label: "Type \"reset\" to confirm",
|
|
174
|
+
outlined: "",
|
|
175
|
+
dense: "",
|
|
176
|
+
onKeyup: t[2] || (t[2] = x((e) => j.value && executeReset(), ["enter"]))
|
|
177
|
+
}, null, 8, ["modelValue"])
|
|
178
|
+
]),
|
|
179
|
+
_: 1
|
|
180
|
+
}),
|
|
181
|
+
d(L, null, {
|
|
182
|
+
default: b(() => [
|
|
183
|
+
d(F),
|
|
184
|
+
d(I, {
|
|
185
|
+
text: "",
|
|
186
|
+
onClick: resetDialogState
|
|
187
|
+
}, {
|
|
188
|
+
default: b(() => t[16] || (t[16] = [u("Cancel")])),
|
|
189
|
+
_: 1
|
|
190
|
+
}),
|
|
191
|
+
d(I, {
|
|
192
|
+
color: "error",
|
|
193
|
+
disabled: !j.value,
|
|
194
|
+
onClick: executeReset
|
|
195
|
+
}, {
|
|
196
|
+
default: b(() => t[17] || (t[17] = [u(" Reset All Data ")])),
|
|
197
|
+
_: 1
|
|
198
|
+
}, 8, ["disabled"])
|
|
199
|
+
]),
|
|
200
|
+
_: 1
|
|
201
|
+
})
|
|
202
|
+
]),
|
|
203
|
+
_: 1
|
|
204
|
+
})]),
|
|
205
|
+
_: 1
|
|
206
|
+
}, 8, ["modelValue"])], 64);
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
//#endregion
|
|
211
|
+
export { C as default };
|
|
212
|
+
|
|
213
|
+
//# sourceMappingURL=UserChip.vue_vue_type_script_setup_true_lang.mjs.map
|