@abraca/nuxt 2.0.0 → 2.0.3
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/module.d.mts +18 -7
- package/dist/module.json +1 -1
- package/dist/module.mjs +21 -5
- package/dist/runtime/assets/aware-tokens.css +1 -0
- package/dist/runtime/components/AAccountSwitcherModal.d.vue.ts +16 -1
- package/dist/runtime/components/AAccountSwitcherModal.vue +33 -4
- package/dist/runtime/components/AAccountSwitcherModal.vue.d.ts +16 -1
- package/dist/runtime/components/AAuthLinkLanding.d.vue.ts +3 -0
- package/dist/runtime/components/AAuthLinkLanding.vue +85 -0
- package/dist/runtime/components/AAuthLinkLanding.vue.d.ts +3 -0
- package/dist/runtime/components/AClaimAccountModal.d.vue.ts +7 -1
- package/dist/runtime/components/AClaimAccountModal.vue +28 -13
- package/dist/runtime/components/AClaimAccountModal.vue.d.ts +7 -1
- package/dist/runtime/components/AEditor.vue +5 -0
- package/dist/runtime/components/AEmailVerifyConfirmModal.d.vue.ts +30 -0
- package/dist/runtime/components/AEmailVerifyConfirmModal.vue +100 -0
- package/dist/runtime/components/AEmailVerifyConfirmModal.vue.d.ts +30 -0
- package/dist/runtime/components/AEmailVerifyRequestCard.d.vue.ts +22 -0
- package/dist/runtime/components/AEmailVerifyRequestCard.vue +65 -0
- package/dist/runtime/components/AEmailVerifyRequestCard.vue.d.ts +22 -0
- package/dist/runtime/components/AMnemonicLoginModal.d.vue.ts +1 -1
- package/dist/runtime/components/AMnemonicLoginModal.vue.d.ts +1 -1
- package/dist/runtime/components/ANodePanel.vue +2 -0
- package/dist/runtime/components/ANotificationBell.d.vue.ts +2 -2
- package/dist/runtime/components/ANotificationBell.vue.d.ts +2 -2
- package/dist/runtime/components/APasswordChangeModal.d.vue.ts +28 -0
- package/dist/runtime/components/APasswordChangeModal.vue +178 -0
- package/dist/runtime/components/APasswordChangeModal.vue.d.ts +28 -0
- package/dist/runtime/components/APasswordLoginModal.d.vue.ts +42 -0
- package/dist/runtime/components/APasswordLoginModal.vue +177 -0
- package/dist/runtime/components/APasswordLoginModal.vue.d.ts +42 -0
- package/dist/runtime/components/APasswordRegisterModal.d.vue.ts +49 -0
- package/dist/runtime/components/APasswordRegisterModal.vue +262 -0
- package/dist/runtime/components/APasswordRegisterModal.vue.d.ts +49 -0
- package/dist/runtime/components/APasswordResetConfirmModal.d.vue.ts +31 -0
- package/dist/runtime/components/APasswordResetConfirmModal.vue +154 -0
- package/dist/runtime/components/APasswordResetConfirmModal.vue.d.ts +31 -0
- package/dist/runtime/components/APasswordResetRequestModal.d.vue.ts +35 -0
- package/dist/runtime/components/APasswordResetRequestModal.vue +113 -0
- package/dist/runtime/components/APasswordResetRequestModal.vue.d.ts +35 -0
- package/dist/runtime/components/ASetPasswordCard.d.vue.ts +26 -0
- package/dist/runtime/components/ASetPasswordCard.vue +139 -0
- package/dist/runtime/components/ASetPasswordCard.vue.d.ts +26 -0
- package/dist/runtime/components/ASubPageList.d.vue.ts +66 -0
- package/dist/runtime/components/ASubPageList.vue +147 -0
- package/dist/runtime/components/ASubPageList.vue.d.ts +66 -0
- package/dist/runtime/components/aware/AAccordion.d.vue.ts +2 -0
- package/dist/runtime/components/aware/AAccordion.vue +11 -1
- package/dist/runtime/components/aware/AAccordion.vue.d.ts +2 -0
- package/dist/runtime/components/aware/AButton.vue +3 -3
- package/dist/runtime/components/aware/ACollapsible.d.vue.ts +2 -0
- package/dist/runtime/components/aware/ACollapsible.vue +9 -1
- package/dist/runtime/components/aware/ACollapsible.vue.d.ts +2 -0
- package/dist/runtime/components/aware/AGlobalFocusLayer.vue +1 -1
- package/dist/runtime/components/aware/AHoverItem.vue +28 -3
- package/dist/runtime/components/aware/AMedia.d.vue.ts +1 -1
- package/dist/runtime/components/aware/AMedia.vue.d.ts +1 -1
- package/dist/runtime/components/aware/AModal.d.vue.ts +2 -0
- package/dist/runtime/components/aware/AModal.vue +9 -1
- package/dist/runtime/components/aware/AModal.vue.d.ts +2 -0
- package/dist/runtime/components/aware/APresenceBlobs.vue +1 -1
- package/dist/runtime/components/aware/APresenceCursors.vue +1 -1
- package/dist/runtime/components/aware/AScroll.d.vue.ts +2 -0
- package/dist/runtime/components/aware/AScroll.vue +13 -3
- package/dist/runtime/components/aware/AScroll.vue.d.ts +2 -0
- package/dist/runtime/components/aware/ASlideover.d.vue.ts +2 -0
- package/dist/runtime/components/aware/ASlideover.vue +9 -1
- package/dist/runtime/components/aware/ASlideover.vue.d.ts +2 -0
- package/dist/runtime/components/aware/ASlider.vue +1 -0
- package/dist/runtime/components/aware/ATabs.d.vue.ts +2 -0
- package/dist/runtime/components/aware/ATabs.vue +9 -1
- package/dist/runtime/components/aware/ATabs.vue.d.ts +2 -0
- package/dist/runtime/components/chat/ANodeChatPanel.vue +1 -0
- package/dist/runtime/components/editor/AEditorRedoButton.d.vue.ts +2 -2
- package/dist/runtime/components/editor/AEditorRedoButton.vue.d.ts +2 -2
- package/dist/runtime/components/editor/AEditorUndoButton.d.vue.ts +2 -2
- package/dist/runtime/components/editor/AEditorUndoButton.vue.d.ts +2 -2
- package/dist/runtime/components/renderers/calendar/ACalendarToolbar.d.vue.ts +4 -4
- package/dist/runtime/components/renderers/calendar/ACalendarToolbar.vue.d.ts +4 -4
- package/dist/runtime/components/renderers/media/MediaTransportBar.d.vue.ts +2 -2
- package/dist/runtime/components/renderers/media/MediaTransportBar.vue.d.ts +2 -2
- package/dist/runtime/components/shell/AUserProfilePopover.d.vue.ts +1 -1
- package/dist/runtime/components/shell/AUserProfilePopover.vue.d.ts +1 -1
- package/dist/runtime/composables/useAAField.js +7 -4
- package/dist/runtime/composables/useAAFocus.js +10 -5
- package/dist/runtime/composables/useAAFollowAnchor.js +68 -34
- package/dist/runtime/composables/useAAFollowPeer.d.ts +7 -4
- package/dist/runtime/composables/useAAFollowPeer.js +60 -11
- package/dist/runtime/composables/useAAViewport.d.ts +1 -1
- package/dist/runtime/composables/useAbracadabraAuth.d.ts +2 -0
- package/dist/runtime/composables/useAbracadabraAuth.js +2 -0
- package/dist/runtime/composables/useEditorSuggestions.js +2 -1
- package/dist/runtime/composables/useEmailVerification.d.ts +40 -26
- package/dist/runtime/composables/useEmailVerification.js +95 -43
- package/dist/runtime/composables/usePasswordAuth.d.ts +64 -0
- package/dist/runtime/composables/usePasswordAuth.js +126 -0
- package/dist/runtime/composables/useTiptapHistory.d.ts +2 -2
- package/dist/runtime/composables/useTiptapHistory.js +5 -5
- package/dist/runtime/extensions/svg-embed.d.ts +23 -0
- package/dist/runtime/extensions/svg-embed.js +33 -0
- package/dist/runtime/extensions/views/MetaFieldView.vue +23 -6
- package/dist/runtime/extensions/views/SvgEmbedView.d.vue.ts +4 -0
- package/dist/runtime/extensions/views/SvgEmbedView.vue +120 -0
- package/dist/runtime/extensions/views/SvgEmbedView.vue.d.ts +4 -0
- package/dist/runtime/plugin-abracadabra.client.js +58 -9
- package/dist/runtime/plugin-abracadabra.server.js +2 -0
- package/dist/runtime/plugins/core.plugin.js +8 -4
- package/dist/runtime/server/plugins/abracadabra-service.js +102 -13
- package/dist/runtime/types.d.ts +11 -0
- package/dist/runtime/utils/awareRingStyle.js +1 -1
- package/dist/runtime/utils/sanitizeSvg.d.ts +19 -0
- package/dist/runtime/utils/sanitizeSvg.js +87 -0
- package/package.json +7 -8
- package/dist/runtime/components/renderers/ASpatialRenderer.d.vue.ts +0 -19
- package/dist/runtime/components/renderers/ASpatialRenderer.vue +0 -459
- package/dist/runtime/components/renderers/ASpatialRenderer.vue.d.ts +0 -19
- package/dist/runtime/components/renderers/spatial/SpatialGround.d.vue.ts +0 -20
- package/dist/runtime/components/renderers/spatial/SpatialGround.vue +0 -26
- package/dist/runtime/components/renderers/spatial/SpatialGround.vue.d.ts +0 -20
- package/dist/runtime/components/renderers/spatial/SpatialObject.d.vue.ts +0 -17
- package/dist/runtime/components/renderers/spatial/SpatialObject.vue +0 -257
- package/dist/runtime/components/renderers/spatial/SpatialObject.vue.d.ts +0 -17
- package/dist/runtime/components/renderers/spatial/SpatialSceneBridge.d.vue.ts +0 -15
- package/dist/runtime/components/renderers/spatial/SpatialSceneBridge.vue +0 -18
- package/dist/runtime/components/renderers/spatial/SpatialSceneBridge.vue.d.ts +0 -15
- package/dist/runtime/components/renderers/spatial/SpatialTransformInputs.d.vue.ts +0 -16
- package/dist/runtime/components/renderers/spatial/SpatialTransformInputs.vue +0 -66
- package/dist/runtime/components/renderers/spatial/SpatialTransformInputs.vue.d.ts +0 -16
- package/dist/runtime/components/renderers/spatial/SpatialUserAvatar.d.vue.ts +0 -8
- package/dist/runtime/components/renderers/spatial/SpatialUserAvatar.vue +0 -53
- package/dist/runtime/components/renderers/spatial/SpatialUserAvatar.vue.d.ts +0 -8
- package/dist/runtime/composables/useSpatialCamera.d.ts +0 -16
- package/dist/runtime/composables/useSpatialCamera.js +0 -175
- package/dist/runtime/composables/useSpatialDrag.d.ts +0 -14
- package/dist/runtime/composables/useSpatialDrag.js +0 -137
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
loading: { type: Boolean, required: false, default: false },
|
|
5
|
+
sent: { type: Boolean, required: false, default: false },
|
|
6
|
+
error: { type: [String, null], required: false },
|
|
7
|
+
email: { type: [String, null], required: false },
|
|
8
|
+
title: { type: String, required: false, default: "Verify your email" },
|
|
9
|
+
subtitle: { type: String, required: false, default: "Confirming your email address lets you reset your password and receive notifications." }
|
|
10
|
+
});
|
|
11
|
+
const emit = defineEmits(["request"]);
|
|
12
|
+
const showSentCopy = computed(() => props.sent && !props.loading && !props.error);
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<div class="ev-card">
|
|
17
|
+
<div class="ev-head">
|
|
18
|
+
<UIcon
|
|
19
|
+
name="i-lucide-mail-check"
|
|
20
|
+
class="size-5 text-(--ui-primary) shrink-0"
|
|
21
|
+
/>
|
|
22
|
+
<div class="flex-1">
|
|
23
|
+
<h4 class="ev-title">
|
|
24
|
+
{{ title }}
|
|
25
|
+
</h4>
|
|
26
|
+
<p class="ev-sub">
|
|
27
|
+
{{ subtitle }}
|
|
28
|
+
</p>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<UAlert
|
|
33
|
+
v-if="showSentCopy"
|
|
34
|
+
color="success"
|
|
35
|
+
variant="soft"
|
|
36
|
+
icon="i-lucide-mail-check"
|
|
37
|
+
title="Verification email sent"
|
|
38
|
+
:description="email ? `We sent a link to ${email}. The link expires shortly \u2014 use it soon.` : 'We sent a verification link to your registered email. The link expires shortly \u2014 use it soon.'"
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
<UAlert
|
|
42
|
+
v-else-if="error"
|
|
43
|
+
color="error"
|
|
44
|
+
variant="soft"
|
|
45
|
+
icon="i-lucide-triangle-alert"
|
|
46
|
+
:description="error"
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
<div class="ev-actions">
|
|
50
|
+
<UButton
|
|
51
|
+
color="primary"
|
|
52
|
+
size="sm"
|
|
53
|
+
icon="i-lucide-send"
|
|
54
|
+
:label="sent ? 'Resend verification email' : 'Send verification email'"
|
|
55
|
+
:loading="loading"
|
|
56
|
+
:disabled="loading"
|
|
57
|
+
@click="emit('request')"
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<style scoped>
|
|
64
|
+
.ev-card{background:var(--ui-bg);border:1px solid var(--ui-border);border-radius:.6rem;display:flex;flex-direction:column;gap:.75rem;padding:1rem}.ev-head{align-items:flex-start;display:flex;gap:.6rem}.ev-title{color:var(--ui-text-highlighted);font-size:.875rem;font-weight:600;margin:0}.ev-sub{color:var(--ui-text-muted);font-size:.8125rem;line-height:1.5;margin:.2rem 0 0}.ev-actions{display:flex;justify-content:flex-end;padding-top:.25rem}
|
|
65
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
loading?: boolean;
|
|
3
|
+
/** Flip to true after the consumer's request handler resolves. */
|
|
4
|
+
sent?: boolean;
|
|
5
|
+
error?: string | null;
|
|
6
|
+
/** Address shown in the cooldown copy ("we sent a link to <email>"). Optional. */
|
|
7
|
+
email?: string | null;
|
|
8
|
+
title?: string;
|
|
9
|
+
subtitle?: string;
|
|
10
|
+
};
|
|
11
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
|
+
request: () => any;
|
|
13
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
14
|
+
onRequest?: (() => any) | undefined;
|
|
15
|
+
}>, {
|
|
16
|
+
subtitle: string;
|
|
17
|
+
title: string;
|
|
18
|
+
loading: boolean;
|
|
19
|
+
sent: boolean;
|
|
20
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|
|
@@ -28,8 +28,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
28
28
|
}>, {
|
|
29
29
|
subtitle: string;
|
|
30
30
|
title: string;
|
|
31
|
-
wordCount: 12 | 24;
|
|
32
31
|
loading: boolean;
|
|
32
|
+
wordCount: 12 | 24;
|
|
33
33
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
34
|
declare const _default: typeof __VLS_export;
|
|
35
35
|
export default _default;
|
|
@@ -28,8 +28,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
28
28
|
}>, {
|
|
29
29
|
subtitle: string;
|
|
30
30
|
title: string;
|
|
31
|
-
wordCount: 12 | 24;
|
|
32
31
|
loading: boolean;
|
|
32
|
+
wordCount: 12 | 24;
|
|
33
33
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
34
|
declare const _default: typeof __VLS_export;
|
|
35
35
|
export default _default;
|
|
@@ -359,6 +359,7 @@ const addFieldMenuItems = computed(
|
|
|
359
359
|
<div class="space-y-1">
|
|
360
360
|
<label class="text-xs font-medium text-muted">{{ locale.color }}</label>
|
|
361
361
|
<AColorPicker
|
|
362
|
+
:field-key="`node-panel:meta:color:${props.nodeId}`"
|
|
362
363
|
:model-value="meta.color"
|
|
363
364
|
@update:model-value="patchMeta({ color: $event })"
|
|
364
365
|
/>
|
|
@@ -669,6 +670,7 @@ const addFieldMenuItems = computed(
|
|
|
669
670
|
<!-- Color Preset / Color Picker -->
|
|
670
671
|
<template v-else-if="['colorPreset', 'colorPicker'].includes(field.type)">
|
|
671
672
|
<AColorPicker
|
|
673
|
+
:field-key="`node-panel:custom:${props.nodeId}:${field.key}`"
|
|
672
674
|
:model-value="String(getCustomFieldValue(field) ?? '')"
|
|
673
675
|
@update:model-value="setCustomFieldValue(field, $event)"
|
|
674
676
|
/>
|
|
@@ -3,7 +3,7 @@ type __VLS_Props = {
|
|
|
3
3
|
count?: number;
|
|
4
4
|
/** Tooltip text. Default: 'Notifications'. */
|
|
5
5
|
tooltip?: string;
|
|
6
|
-
size?: '
|
|
6
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
7
7
|
variant?: 'ghost' | 'soft' | 'outline' | 'solid' | 'subtle' | 'link';
|
|
8
8
|
color?: 'neutral' | 'primary' | 'secondary' | 'error' | 'warning' | 'success' | 'info';
|
|
9
9
|
icon?: string;
|
|
@@ -17,7 +17,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
17
17
|
}>, {
|
|
18
18
|
color: "neutral" | "primary" | "secondary" | "error" | "warning" | "success" | "info";
|
|
19
19
|
icon: string;
|
|
20
|
-
size: "
|
|
20
|
+
size: "xs" | "sm" | "md" | "lg" | "xl";
|
|
21
21
|
variant: "ghost" | "soft" | "outline" | "solid" | "subtle" | "link";
|
|
22
22
|
tooltip: string;
|
|
23
23
|
chipColor: "primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral";
|
|
@@ -3,7 +3,7 @@ type __VLS_Props = {
|
|
|
3
3
|
count?: number;
|
|
4
4
|
/** Tooltip text. Default: 'Notifications'. */
|
|
5
5
|
tooltip?: string;
|
|
6
|
-
size?: '
|
|
6
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
7
7
|
variant?: 'ghost' | 'soft' | 'outline' | 'solid' | 'subtle' | 'link';
|
|
8
8
|
color?: 'neutral' | 'primary' | 'secondary' | 'error' | 'warning' | 'success' | 'info';
|
|
9
9
|
icon?: string;
|
|
@@ -17,7 +17,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
17
17
|
}>, {
|
|
18
18
|
color: "neutral" | "primary" | "secondary" | "error" | "warning" | "success" | "info";
|
|
19
19
|
icon: string;
|
|
20
|
-
size: "
|
|
20
|
+
size: "xs" | "sm" | "md" | "lg" | "xl";
|
|
21
21
|
variant: "ghost" | "soft" | "outline" | "solid" | "subtle" | "link";
|
|
22
22
|
tooltip: string;
|
|
23
23
|
chipColor: "primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open?: boolean;
|
|
3
|
+
loading?: boolean;
|
|
4
|
+
error?: string | null;
|
|
5
|
+
title?: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
minLength?: number;
|
|
8
|
+
};
|
|
9
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
10
|
+
submit: (payload: {
|
|
11
|
+
currentPassword: string;
|
|
12
|
+
newPassword: string;
|
|
13
|
+
}) => any;
|
|
14
|
+
"update:open": (v: boolean) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
+
onSubmit?: ((payload: {
|
|
17
|
+
currentPassword: string;
|
|
18
|
+
newPassword: string;
|
|
19
|
+
}) => any) | undefined;
|
|
20
|
+
"onUpdate:open"?: ((v: boolean) => any) | undefined;
|
|
21
|
+
}>, {
|
|
22
|
+
subtitle: string;
|
|
23
|
+
title: string;
|
|
24
|
+
minLength: number;
|
|
25
|
+
loading: boolean;
|
|
26
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
27
|
+
declare const _default: typeof __VLS_export;
|
|
28
|
+
export default _default;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref, watch } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
open: { type: Boolean, required: false },
|
|
5
|
+
loading: { type: Boolean, required: false, default: false },
|
|
6
|
+
error: { type: [String, null], required: false },
|
|
7
|
+
title: { type: String, required: false, default: "Change password" },
|
|
8
|
+
subtitle: { type: String, required: false, default: "Enter your current password, then choose a new one." },
|
|
9
|
+
minLength: { type: Number, required: false, default: 8 }
|
|
10
|
+
});
|
|
11
|
+
const emit = defineEmits(["update:open", "submit"]);
|
|
12
|
+
const open = computed({
|
|
13
|
+
get: () => !!props.open,
|
|
14
|
+
set: (v) => emit("update:open", v)
|
|
15
|
+
});
|
|
16
|
+
const currentPassword = ref("");
|
|
17
|
+
const newPassword = ref("");
|
|
18
|
+
const confirm = ref("");
|
|
19
|
+
const showCurrent = ref(false);
|
|
20
|
+
const showNew = ref(false);
|
|
21
|
+
watch(() => props.open, (v) => {
|
|
22
|
+
if (!v) return;
|
|
23
|
+
currentPassword.value = "";
|
|
24
|
+
newPassword.value = "";
|
|
25
|
+
confirm.value = "";
|
|
26
|
+
showCurrent.value = false;
|
|
27
|
+
showNew.value = false;
|
|
28
|
+
});
|
|
29
|
+
const passwordTooShort = computed(
|
|
30
|
+
() => newPassword.value.length > 0 && newPassword.value.length < props.minLength
|
|
31
|
+
);
|
|
32
|
+
const sameAsCurrent = computed(
|
|
33
|
+
() => newPassword.value.length > 0 && currentPassword.value.length > 0 && newPassword.value === currentPassword.value
|
|
34
|
+
);
|
|
35
|
+
const confirmMismatch = computed(
|
|
36
|
+
() => confirm.value.length > 0 && confirm.value !== newPassword.value
|
|
37
|
+
);
|
|
38
|
+
const canSubmit = computed(
|
|
39
|
+
() => !!currentPassword.value && newPassword.value.length >= props.minLength && confirm.value === newPassword.value && !sameAsCurrent.value && !props.loading
|
|
40
|
+
);
|
|
41
|
+
function submit() {
|
|
42
|
+
if (!canSubmit.value) return;
|
|
43
|
+
emit("submit", {
|
|
44
|
+
currentPassword: currentPassword.value,
|
|
45
|
+
newPassword: newPassword.value
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<UModal
|
|
52
|
+
v-model:open="open"
|
|
53
|
+
:title="title"
|
|
54
|
+
:ui="{ content: 'sm:max-w-md' }"
|
|
55
|
+
>
|
|
56
|
+
<template #body>
|
|
57
|
+
<div class="flex flex-col gap-4">
|
|
58
|
+
<p class="text-sm text-(--ui-text-muted)">
|
|
59
|
+
{{ subtitle }}
|
|
60
|
+
</p>
|
|
61
|
+
|
|
62
|
+
<UAlert
|
|
63
|
+
v-if="error"
|
|
64
|
+
color="error"
|
|
65
|
+
variant="soft"
|
|
66
|
+
icon="i-lucide-triangle-alert"
|
|
67
|
+
:description="error"
|
|
68
|
+
/>
|
|
69
|
+
|
|
70
|
+
<div class="flex flex-col gap-1">
|
|
71
|
+
<label class="text-xs font-medium text-(--ui-text-muted)">Current password</label>
|
|
72
|
+
<UInput
|
|
73
|
+
v-model="currentPassword"
|
|
74
|
+
:type="showCurrent ? 'text' : 'password'"
|
|
75
|
+
size="md"
|
|
76
|
+
autofocus
|
|
77
|
+
autocomplete="current-password"
|
|
78
|
+
placeholder="••••••••"
|
|
79
|
+
icon="i-lucide-lock"
|
|
80
|
+
:ui="{ trailing: 'pe-1' }"
|
|
81
|
+
@keydown.enter="submit"
|
|
82
|
+
>
|
|
83
|
+
<template #trailing>
|
|
84
|
+
<UButton
|
|
85
|
+
tabindex="-1"
|
|
86
|
+
variant="ghost"
|
|
87
|
+
color="neutral"
|
|
88
|
+
size="xs"
|
|
89
|
+
:icon="showCurrent ? 'i-lucide-eye-off' : 'i-lucide-eye'"
|
|
90
|
+
:aria-label="showCurrent ? 'Hide password' : 'Show password'"
|
|
91
|
+
@click="showCurrent = !showCurrent"
|
|
92
|
+
/>
|
|
93
|
+
</template>
|
|
94
|
+
</UInput>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<div class="flex flex-col gap-1">
|
|
98
|
+
<label class="text-xs font-medium text-(--ui-text-muted)">New password</label>
|
|
99
|
+
<UInput
|
|
100
|
+
v-model="newPassword"
|
|
101
|
+
:type="showNew ? 'text' : 'password'"
|
|
102
|
+
size="md"
|
|
103
|
+
autocomplete="new-password"
|
|
104
|
+
:placeholder="`${minLength}+ characters`"
|
|
105
|
+
icon="i-lucide-key-round"
|
|
106
|
+
:ui="{ trailing: 'pe-1' }"
|
|
107
|
+
@keydown.enter="submit"
|
|
108
|
+
>
|
|
109
|
+
<template #trailing>
|
|
110
|
+
<UButton
|
|
111
|
+
tabindex="-1"
|
|
112
|
+
variant="ghost"
|
|
113
|
+
color="neutral"
|
|
114
|
+
size="xs"
|
|
115
|
+
:icon="showNew ? 'i-lucide-eye-off' : 'i-lucide-eye'"
|
|
116
|
+
:aria-label="showNew ? 'Hide password' : 'Show password'"
|
|
117
|
+
@click="showNew = !showNew"
|
|
118
|
+
/>
|
|
119
|
+
</template>
|
|
120
|
+
</UInput>
|
|
121
|
+
<p
|
|
122
|
+
v-if="passwordTooShort"
|
|
123
|
+
class="text-xs text-(--ui-color-error-500)"
|
|
124
|
+
>
|
|
125
|
+
At least {{ minLength }} characters.
|
|
126
|
+
</p>
|
|
127
|
+
<p
|
|
128
|
+
v-if="sameAsCurrent"
|
|
129
|
+
class="text-xs text-(--ui-color-warning-500)"
|
|
130
|
+
>
|
|
131
|
+
New password matches the current one — pick a different one.
|
|
132
|
+
</p>
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
<div class="flex flex-col gap-1">
|
|
136
|
+
<label class="text-xs font-medium text-(--ui-text-muted)">Confirm new password</label>
|
|
137
|
+
<UInput
|
|
138
|
+
v-model="confirm"
|
|
139
|
+
:type="showNew ? 'text' : 'password'"
|
|
140
|
+
size="md"
|
|
141
|
+
autocomplete="new-password"
|
|
142
|
+
placeholder="Type it again"
|
|
143
|
+
icon="i-lucide-shield-check"
|
|
144
|
+
@keydown.enter="submit"
|
|
145
|
+
/>
|
|
146
|
+
<p
|
|
147
|
+
v-if="confirmMismatch"
|
|
148
|
+
class="text-xs text-(--ui-color-error-500)"
|
|
149
|
+
>
|
|
150
|
+
Passwords don't match.
|
|
151
|
+
</p>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</template>
|
|
155
|
+
|
|
156
|
+
<template #footer>
|
|
157
|
+
<div class="flex items-center justify-end gap-2 w-full">
|
|
158
|
+
<UButton
|
|
159
|
+
variant="ghost"
|
|
160
|
+
color="neutral"
|
|
161
|
+
size="sm"
|
|
162
|
+
label="Cancel"
|
|
163
|
+
:disabled="loading"
|
|
164
|
+
@click="open = false"
|
|
165
|
+
/>
|
|
166
|
+
<UButton
|
|
167
|
+
color="primary"
|
|
168
|
+
size="sm"
|
|
169
|
+
icon="i-lucide-key-round"
|
|
170
|
+
label="Update password"
|
|
171
|
+
:loading="loading"
|
|
172
|
+
:disabled="!canSubmit"
|
|
173
|
+
@click="submit"
|
|
174
|
+
/>
|
|
175
|
+
</div>
|
|
176
|
+
</template>
|
|
177
|
+
</UModal>
|
|
178
|
+
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open?: boolean;
|
|
3
|
+
loading?: boolean;
|
|
4
|
+
error?: string | null;
|
|
5
|
+
title?: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
minLength?: number;
|
|
8
|
+
};
|
|
9
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
10
|
+
submit: (payload: {
|
|
11
|
+
currentPassword: string;
|
|
12
|
+
newPassword: string;
|
|
13
|
+
}) => any;
|
|
14
|
+
"update:open": (v: boolean) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
+
onSubmit?: ((payload: {
|
|
17
|
+
currentPassword: string;
|
|
18
|
+
newPassword: string;
|
|
19
|
+
}) => any) | undefined;
|
|
20
|
+
"onUpdate:open"?: ((v: boolean) => any) | undefined;
|
|
21
|
+
}>, {
|
|
22
|
+
subtitle: string;
|
|
23
|
+
title: string;
|
|
24
|
+
minLength: number;
|
|
25
|
+
loading: boolean;
|
|
26
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
27
|
+
declare const _default: typeof __VLS_export;
|
|
28
|
+
export default _default;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open?: boolean;
|
|
3
|
+
loading?: boolean;
|
|
4
|
+
/** Server / client error to display inline. */
|
|
5
|
+
error?: string | null;
|
|
6
|
+
title?: string;
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
/** Show the "Don't have an account? Register" link. */
|
|
9
|
+
showRegisterLink?: boolean;
|
|
10
|
+
/** Show the "Forgot password?" link. */
|
|
11
|
+
showForgotLink?: boolean;
|
|
12
|
+
/** Show the optional invite-code field under Advanced. */
|
|
13
|
+
showInviteCode?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
16
|
+
submit: (payload: {
|
|
17
|
+
username: string;
|
|
18
|
+
password: string;
|
|
19
|
+
inviteCode?: string;
|
|
20
|
+
}) => any;
|
|
21
|
+
"update:open": (v: boolean) => any;
|
|
22
|
+
register: () => any;
|
|
23
|
+
forgot: () => any;
|
|
24
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
25
|
+
onSubmit?: ((payload: {
|
|
26
|
+
username: string;
|
|
27
|
+
password: string;
|
|
28
|
+
inviteCode?: string;
|
|
29
|
+
}) => any) | undefined;
|
|
30
|
+
"onUpdate:open"?: ((v: boolean) => any) | undefined;
|
|
31
|
+
onRegister?: (() => any) | undefined;
|
|
32
|
+
onForgot?: (() => any) | undefined;
|
|
33
|
+
}>, {
|
|
34
|
+
subtitle: string;
|
|
35
|
+
title: string;
|
|
36
|
+
loading: boolean;
|
|
37
|
+
showRegisterLink: boolean;
|
|
38
|
+
showForgotLink: boolean;
|
|
39
|
+
showInviteCode: boolean;
|
|
40
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
41
|
+
declare const _default: typeof __VLS_export;
|
|
42
|
+
export default _default;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref, watch } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
open: { type: Boolean, required: false },
|
|
5
|
+
loading: { type: Boolean, required: false, default: false },
|
|
6
|
+
error: { type: [String, null], required: false },
|
|
7
|
+
title: { type: String, required: false, default: "Sign in" },
|
|
8
|
+
subtitle: { type: String, required: false, default: "Enter your username and password." },
|
|
9
|
+
showRegisterLink: { type: Boolean, required: false, default: true },
|
|
10
|
+
showForgotLink: { type: Boolean, required: false, default: true },
|
|
11
|
+
showInviteCode: { type: Boolean, required: false, default: false }
|
|
12
|
+
});
|
|
13
|
+
const emit = defineEmits(["update:open", "submit", "forgot", "register"]);
|
|
14
|
+
const open = computed({
|
|
15
|
+
get: () => !!props.open,
|
|
16
|
+
set: (v) => emit("update:open", v)
|
|
17
|
+
});
|
|
18
|
+
const username = ref("");
|
|
19
|
+
const password = ref("");
|
|
20
|
+
const inviteCode = ref("");
|
|
21
|
+
const showPassword = ref(false);
|
|
22
|
+
const showAdvanced = ref(false);
|
|
23
|
+
watch(() => props.open, (v) => {
|
|
24
|
+
if (!v) return;
|
|
25
|
+
username.value = "";
|
|
26
|
+
password.value = "";
|
|
27
|
+
inviteCode.value = "";
|
|
28
|
+
showPassword.value = false;
|
|
29
|
+
showAdvanced.value = props.showInviteCode;
|
|
30
|
+
});
|
|
31
|
+
const canSubmit = computed(
|
|
32
|
+
() => !!username.value.trim() && !!password.value && !props.loading
|
|
33
|
+
);
|
|
34
|
+
function submit() {
|
|
35
|
+
if (!canSubmit.value) return;
|
|
36
|
+
emit("submit", {
|
|
37
|
+
username: username.value.trim(),
|
|
38
|
+
password: password.value,
|
|
39
|
+
inviteCode: inviteCode.value.trim() || void 0
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template>
|
|
45
|
+
<UModal
|
|
46
|
+
v-model:open="open"
|
|
47
|
+
:title="title"
|
|
48
|
+
:ui="{ content: 'sm:max-w-md' }"
|
|
49
|
+
>
|
|
50
|
+
<template #body>
|
|
51
|
+
<div class="flex flex-col gap-4">
|
|
52
|
+
<p class="text-sm text-(--ui-text-muted)">
|
|
53
|
+
{{ subtitle }}
|
|
54
|
+
</p>
|
|
55
|
+
|
|
56
|
+
<UAlert
|
|
57
|
+
v-if="error"
|
|
58
|
+
color="error"
|
|
59
|
+
variant="soft"
|
|
60
|
+
icon="i-lucide-triangle-alert"
|
|
61
|
+
:description="error"
|
|
62
|
+
/>
|
|
63
|
+
|
|
64
|
+
<div class="flex flex-col gap-1">
|
|
65
|
+
<label class="text-xs font-medium text-(--ui-text-muted)">Username</label>
|
|
66
|
+
<UInput
|
|
67
|
+
v-model="username"
|
|
68
|
+
size="md"
|
|
69
|
+
autofocus
|
|
70
|
+
autocomplete="username"
|
|
71
|
+
placeholder="your-handle"
|
|
72
|
+
icon="i-lucide-at-sign"
|
|
73
|
+
@keydown.enter="submit"
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<div class="flex flex-col gap-1">
|
|
78
|
+
<label class="text-xs font-medium text-(--ui-text-muted)">Password</label>
|
|
79
|
+
<UInput
|
|
80
|
+
v-model="password"
|
|
81
|
+
:type="showPassword ? 'text' : 'password'"
|
|
82
|
+
size="md"
|
|
83
|
+
autocomplete="current-password"
|
|
84
|
+
placeholder="••••••••"
|
|
85
|
+
icon="i-lucide-lock"
|
|
86
|
+
:ui="{ trailing: 'pe-1' }"
|
|
87
|
+
@keydown.enter="submit"
|
|
88
|
+
>
|
|
89
|
+
<template #trailing>
|
|
90
|
+
<UButton
|
|
91
|
+
tabindex="-1"
|
|
92
|
+
variant="ghost"
|
|
93
|
+
color="neutral"
|
|
94
|
+
size="xs"
|
|
95
|
+
:icon="showPassword ? 'i-lucide-eye-off' : 'i-lucide-eye'"
|
|
96
|
+
:aria-label="showPassword ? 'Hide password' : 'Show password'"
|
|
97
|
+
@click="showPassword = !showPassword"
|
|
98
|
+
/>
|
|
99
|
+
</template>
|
|
100
|
+
</UInput>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<div
|
|
104
|
+
v-if="showInviteCode"
|
|
105
|
+
class="flex items-center justify-between text-xs"
|
|
106
|
+
>
|
|
107
|
+
<UButton
|
|
108
|
+
variant="ghost"
|
|
109
|
+
color="neutral"
|
|
110
|
+
size="xs"
|
|
111
|
+
:icon="showAdvanced ? 'i-lucide-chevron-up' : 'i-lucide-chevron-down'"
|
|
112
|
+
:label="showAdvanced ? 'Hide advanced' : 'Advanced'"
|
|
113
|
+
@click="showAdvanced = !showAdvanced"
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div
|
|
118
|
+
v-if="showInviteCode && showAdvanced"
|
|
119
|
+
class="flex flex-col gap-1"
|
|
120
|
+
>
|
|
121
|
+
<label class="text-xs font-medium text-(--ui-text-muted)">Invite code (optional)</label>
|
|
122
|
+
<UInput
|
|
123
|
+
v-model="inviteCode"
|
|
124
|
+
size="sm"
|
|
125
|
+
placeholder="paste invite code"
|
|
126
|
+
icon="i-lucide-ticket"
|
|
127
|
+
@keydown.enter="submit"
|
|
128
|
+
/>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div
|
|
132
|
+
v-if="showForgotLink || showRegisterLink"
|
|
133
|
+
class="flex items-center justify-between gap-2 -mt-1 text-xs"
|
|
134
|
+
>
|
|
135
|
+
<UButton
|
|
136
|
+
v-if="showForgotLink"
|
|
137
|
+
variant="link"
|
|
138
|
+
color="neutral"
|
|
139
|
+
size="xs"
|
|
140
|
+
label="Forgot password?"
|
|
141
|
+
@click="emit('forgot')"
|
|
142
|
+
/>
|
|
143
|
+
<UButton
|
|
144
|
+
v-if="showRegisterLink"
|
|
145
|
+
variant="link"
|
|
146
|
+
color="primary"
|
|
147
|
+
size="xs"
|
|
148
|
+
label="Create an account"
|
|
149
|
+
@click="emit('register')"
|
|
150
|
+
/>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</template>
|
|
154
|
+
|
|
155
|
+
<template #footer>
|
|
156
|
+
<div class="flex items-center justify-end gap-2 w-full">
|
|
157
|
+
<UButton
|
|
158
|
+
variant="ghost"
|
|
159
|
+
color="neutral"
|
|
160
|
+
size="sm"
|
|
161
|
+
label="Cancel"
|
|
162
|
+
:disabled="loading"
|
|
163
|
+
@click="open = false"
|
|
164
|
+
/>
|
|
165
|
+
<UButton
|
|
166
|
+
color="primary"
|
|
167
|
+
size="sm"
|
|
168
|
+
icon="i-lucide-log-in"
|
|
169
|
+
label="Sign in"
|
|
170
|
+
:loading="loading"
|
|
171
|
+
:disabled="!canSubmit"
|
|
172
|
+
@click="submit"
|
|
173
|
+
/>
|
|
174
|
+
</div>
|
|
175
|
+
</template>
|
|
176
|
+
</UModal>
|
|
177
|
+
</template>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
open?: boolean;
|
|
3
|
+
loading?: boolean;
|
|
4
|
+
/** Server / client error to display inline. */
|
|
5
|
+
error?: string | null;
|
|
6
|
+
title?: string;
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
/** Show the "Don't have an account? Register" link. */
|
|
9
|
+
showRegisterLink?: boolean;
|
|
10
|
+
/** Show the "Forgot password?" link. */
|
|
11
|
+
showForgotLink?: boolean;
|
|
12
|
+
/** Show the optional invite-code field under Advanced. */
|
|
13
|
+
showInviteCode?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
16
|
+
submit: (payload: {
|
|
17
|
+
username: string;
|
|
18
|
+
password: string;
|
|
19
|
+
inviteCode?: string;
|
|
20
|
+
}) => any;
|
|
21
|
+
"update:open": (v: boolean) => any;
|
|
22
|
+
register: () => any;
|
|
23
|
+
forgot: () => any;
|
|
24
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
25
|
+
onSubmit?: ((payload: {
|
|
26
|
+
username: string;
|
|
27
|
+
password: string;
|
|
28
|
+
inviteCode?: string;
|
|
29
|
+
}) => any) | undefined;
|
|
30
|
+
"onUpdate:open"?: ((v: boolean) => any) | undefined;
|
|
31
|
+
onRegister?: (() => any) | undefined;
|
|
32
|
+
onForgot?: (() => any) | undefined;
|
|
33
|
+
}>, {
|
|
34
|
+
subtitle: string;
|
|
35
|
+
title: string;
|
|
36
|
+
loading: boolean;
|
|
37
|
+
showRegisterLink: boolean;
|
|
38
|
+
showForgotLink: boolean;
|
|
39
|
+
showInviteCode: boolean;
|
|
40
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
41
|
+
declare const _default: typeof __VLS_export;
|
|
42
|
+
export default _default;
|