@edgedev/create-edge-app 1.1.25 → 1.1.27
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/README.md +55 -20
- package/{agent.md → agents.md} +2 -0
- package/bin/cli.js +6 -6
- package/edge/components/auth/login.vue +384 -0
- package/edge/components/auth/register.vue +396 -0
- package/edge/components/auth.vue +108 -0
- package/edge/components/autoFileUpload.vue +215 -0
- package/edge/components/billing.vue +8 -0
- package/edge/components/buttonDivider.vue +14 -0
- package/edge/components/chip.vue +34 -0
- package/edge/components/clipboardButton.vue +42 -0
- package/edge/components/cms/block.vue +529 -0
- package/edge/components/cms/blockApi.vue +212 -0
- package/edge/components/cms/blockEditor.vue +725 -0
- package/edge/components/cms/blockInput.vue +66 -0
- package/edge/components/cms/blockPicker.vue +486 -0
- package/edge/components/cms/blockRender.vue +78 -0
- package/edge/components/cms/blockSheetContent.vue +28 -0
- package/edge/components/cms/codeEditor.vue +466 -0
- package/edge/components/cms/fontUpload.vue +327 -0
- package/edge/components/cms/htmlContent.vue +807 -0
- package/edge/components/cms/init_blocks/api_with_subarrays.html +17 -0
- package/edge/components/cms/init_blocks/array_with_collection.html +7 -0
- package/edge/components/cms/init_blocks/array_with_objects.html +7 -0
- package/edge/components/cms/init_blocks/carousel.html +103 -0
- package/edge/components/cms/init_blocks/contact_us.html +69 -0
- package/edge/components/cms/init_blocks/content_with_left_image.html +27 -0
- package/edge/components/cms/init_blocks/footer.html +24 -0
- package/edge/components/cms/init_blocks/header_divider.html +7 -0
- package/edge/components/cms/init_blocks/hero.html +35 -0
- package/edge/components/cms/init_blocks/hero_carousel.html +52 -0
- package/edge/components/cms/init_blocks/newsletter.html +117 -0
- package/edge/components/cms/init_blocks/post_content.html +7 -0
- package/edge/components/cms/init_blocks/post_title_header.html +21 -0
- package/edge/components/cms/init_blocks/posts_list.html +20 -0
- package/edge/components/cms/init_blocks/properties_showcase.html +100 -0
- package/edge/components/cms/init_blocks/property_carousel.html +59 -0
- package/edge/components/cms/init_blocks/property_detail.html +112 -0
- package/edge/components/cms/init_blocks/property_detail_header.html +34 -0
- package/edge/components/cms/init_blocks/property_results.html +137 -0
- package/edge/components/cms/init_blocks/property_search.html +75 -0
- package/edge/components/cms/init_blocks/simple_array.html +7 -0
- package/edge/components/cms/mediaCard.vue +116 -0
- package/edge/components/cms/mediaManager.vue +386 -0
- package/edge/components/cms/menu.vue +1103 -0
- package/edge/components/cms/optionsSelect.vue +107 -0
- package/edge/components/cms/page.vue +1785 -0
- package/edge/components/cms/posts.vue +1083 -0
- package/edge/components/cms/site.vue +1475 -0
- package/edge/components/cms/themeDefaultMenu.vue +548 -0
- package/edge/components/cms/themeEditor.vue +429 -0
- package/edge/components/dashboard.vue +776 -0
- package/edge/components/editor.vue +671 -0
- package/edge/components/fileTree.vue +72 -0
- package/edge/components/files.vue +89 -0
- package/edge/components/formSubtypes/myOrgs.vue +214 -0
- package/edge/components/formSubtypes/users.vue +336 -0
- package/edge/components/functionChips.vue +57 -0
- package/edge/components/gError.vue +98 -0
- package/edge/components/gHelper.vue +67 -0
- package/edge/components/gInput.vue +1331 -0
- package/edge/components/loggingIn.vue +41 -0
- package/edge/components/menu.vue +137 -0
- package/edge/components/menuContent.vue +132 -0
- package/edge/components/myAccount.vue +317 -0
- package/edge/components/myOrganizations.vue +75 -0
- package/edge/components/myProfile.vue +122 -0
- package/edge/components/orgSwitcher.vue +25 -0
- package/edge/components/organizationMembers.vue +522 -0
- package/edge/components/organizationSettings.vue +271 -0
- package/edge/components/shad/breadcrumbs.vue +35 -0
- package/edge/components/shad/button.vue +43 -0
- package/edge/components/shad/checkbox.vue +73 -0
- package/edge/components/shad/combobox.vue +238 -0
- package/edge/components/shad/datepicker.vue +184 -0
- package/edge/components/shad/dialog.vue +32 -0
- package/edge/components/shad/dropdownMenu.vue +54 -0
- package/edge/components/shad/dropdownMenuItem.vue +21 -0
- package/edge/components/shad/form.vue +59 -0
- package/edge/components/shad/html.vue +877 -0
- package/edge/components/shad/input.vue +139 -0
- package/edge/components/shad/number.vue +109 -0
- package/edge/components/shad/select.vue +151 -0
- package/edge/components/shad/selectTags.vue +278 -0
- package/edge/components/shad/switch.vue +67 -0
- package/edge/components/shad/tags.vue +137 -0
- package/edge/components/shad/textarea.vue +102 -0
- package/edge/components/shad/typeMoney.vue +167 -0
- package/edge/components/sideBar.vue +288 -0
- package/edge/components/sideBarContent.vue +268 -0
- package/edge/components/sidebarProvider.vue +33 -0
- package/edge/components/tooltip.vue +16 -0
- package/edge/components/userMenu.vue +148 -0
- package/edge/components/v/alert.vue +59 -0
- package/edge/components/v/alertTitle.vue +18 -0
- package/edge/components/v/card.vue +53 -0
- package/edge/components/v/cardActions.vue +18 -0
- package/edge/components/v/cardText.vue +18 -0
- package/edge/components/v/cardTitle.vue +20 -0
- package/edge/components/v/col.vue +56 -0
- package/edge/components/v/list.vue +46 -0
- package/edge/components/v/listItem.vue +26 -0
- package/edge/components/v/listItemTitle.vue +18 -0
- package/edge/components/v/row.vue +42 -0
- package/edge/components/v/toolbar.vue +24 -0
- package/edge/composables/global.ts +519 -0
- package/edge-pull.sh +2 -0
- package/edge-push.sh +1 -0
- package/edge-status.sh +14 -0
- package/package.json +1 -1
- package/edge-components-install.sh +0 -1
package/README.md
CHANGED
|
@@ -1,36 +1,71 @@
|
|
|
1
1
|
# Edge Firebase Starter
|
|
2
|
-
## Setup
|
|
3
2
|
|
|
3
|
+
Nuxt 3 + Vue 3 (SPA mode) starter with Edge components and Firebase integration.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
- Node.js (LTS recommended)
|
|
7
|
+
- pnpm (recommended) or npm
|
|
8
|
+
|
|
9
|
+
## Create a new app
|
|
4
10
|
```bash
|
|
5
|
-
#Run
|
|
11
|
+
# Run once under your current Node version:
|
|
6
12
|
npm install -g --ignore-scripts @edgedev/create-edge-app
|
|
7
13
|
|
|
8
|
-
#
|
|
14
|
+
# Create a new app:
|
|
9
15
|
npx @edgedev/create-edge-app yourappname
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Install and run
|
|
19
|
+
```bash
|
|
20
|
+
# Install dependencies
|
|
21
|
+
pnpm install
|
|
22
|
+
|
|
23
|
+
# Start dev server
|
|
24
|
+
pnpm dev
|
|
25
|
+
```
|
|
10
26
|
|
|
11
|
-
|
|
12
|
-
|
|
27
|
+
## Repo structure
|
|
28
|
+
- `edge/` shared Edge framework subtree (do not edit directly unless absolutely required)
|
|
29
|
+
- `pages/` app routes (use `/pages/app/...` for authenticated app pages)
|
|
30
|
+
- `components/` local app components
|
|
31
|
+
- `functions/` Firebase Functions (add new files, do not edit shared config files)
|
|
32
|
+
- `firestore.rules`, `storage.rules` Firebase rules (do not modify here)
|
|
13
33
|
|
|
34
|
+
## Keeping the Edge subtree in sync
|
|
35
|
+
Use the provided scripts instead of manual edits:
|
|
36
|
+
```bash
|
|
37
|
+
./edge-status.sh
|
|
38
|
+
./edge-pull.sh
|
|
39
|
+
./edge-push.sh
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Deep links (iOS)
|
|
43
|
+
Add URL types to your `Info.plist` when configuring deep links:
|
|
44
|
+
```xml
|
|
45
|
+
<key>CFBundleURLTypes</key>
|
|
46
|
+
<array>
|
|
47
|
+
<dict>
|
|
48
|
+
<key>CFBundleURLSchemes</key>
|
|
49
|
+
<array>
|
|
50
|
+
<string>com.edgemarketingdesign.offcall</string>
|
|
51
|
+
</array>
|
|
52
|
+
<key>CFBundleURLName</key>
|
|
53
|
+
<string>Offcall App URL</string>
|
|
14
54
|
<key>CFBundleURLTypes</key>
|
|
15
55
|
<array>
|
|
16
|
-
|
|
56
|
+
<dict>
|
|
17
57
|
<key>CFBundleURLSchemes</key>
|
|
18
58
|
<array>
|
|
19
|
-
|
|
59
|
+
<string>*</string>
|
|
20
60
|
</array>
|
|
21
61
|
<key>CFBundleURLName</key>
|
|
22
|
-
<string>
|
|
23
|
-
|
|
24
|
-
<array>
|
|
25
|
-
<dict>
|
|
26
|
-
<key>CFBundleURLSchemes</key>
|
|
27
|
-
<array>
|
|
28
|
-
<string>*</string>
|
|
29
|
-
</array>
|
|
30
|
-
<key>CFBundleURLName</key>
|
|
31
|
-
<string>Wildcard</string>
|
|
32
|
-
</dict>
|
|
33
|
-
</array>
|
|
34
|
-
</dict>
|
|
62
|
+
<string>Wildcard</string>
|
|
63
|
+
</dict>
|
|
35
64
|
</array>
|
|
65
|
+
</dict>
|
|
66
|
+
</array>
|
|
36
67
|
```
|
|
68
|
+
|
|
69
|
+
## Notes
|
|
70
|
+
- Auth/Firestore/Functions/Storage access should go through the injected `edgeFirebase` plugin, not direct SDK imports.
|
|
71
|
+
- Prefer Edge components (`edge-dashboard`, `edge-editor`, and `edge/components/shad` wrappers) for UI and data flows.
|
package/{agent.md → agents.md}
RENAMED
|
@@ -70,8 +70,10 @@ Adjust props (search, filters, pagination, save overrides) using the existing co
|
|
|
70
70
|
## Do/Don't
|
|
71
71
|
- Do reuse Edge components (`dashboard`, `editor`, `cms` blocks, auth widgets) before adding new ones.
|
|
72
72
|
- Do keep Firestore paths, queries, and role checks consistent with `edgeGlobal` helpers (`isAdminGlobal`, `getRoleName`, etc.).
|
|
73
|
+
- Do use the `edge-*.sh` scripts (like `edge-pull.sh` and `edge-components-update.sh`) to sync/update the `edge` subtree instead of manual edits.
|
|
73
74
|
- Don’t introduce TypeScript, Options API, raw Firebase SDK calls, or ad-hoc forms/tables when an Edge component exists.
|
|
74
75
|
- Don’t edit code inside the `edge` folder unless absolutely required; it is a shared repo. If a change is unavoidable, keep it generic (no project-specific hacks) and call out the suggestion instead of making the edit when possible.
|
|
76
|
+
- Don’t modify `storage.rules` or `firestore.rules`.
|
|
75
77
|
|
|
76
78
|
## Firebase Functions guidance
|
|
77
79
|
- Review `functions/config.js`, `functions/edgeFirebase.js`, and `functions/cms.js` to mirror established patterns, but do not edit those files.
|
package/bin/cli.js
CHANGED
|
@@ -67,7 +67,7 @@ const gitCheckoutCommand = `git clone --depth 1 https://github.com/Edge-Marketin
|
|
|
67
67
|
const removeGitDirCommand = `rm -rf ${repoName}/.git`
|
|
68
68
|
const installDependenciesCommand = `cd ${repoName} && pnpm store prune && pnpm install --force --ignore-scripts=false`
|
|
69
69
|
const installFunctionDependenciesCommand = `cd ${repoName}/functions && npm install`
|
|
70
|
-
const cloneFirebaseFrameworkCommand = `cd ${repoName} && git clone https://github.com/Edge-Marketing-and-Design/edge-vue-components.git edge`
|
|
70
|
+
// const cloneFirebaseFrameworkCommand = `cd ${repoName} && git clone https://github.com/Edge-Marketing-and-Design/edge-vue-components.git edge`
|
|
71
71
|
|
|
72
72
|
console.log(`Cloning with name ${repoName}...`)
|
|
73
73
|
const checkedOut = runCommand(gitCheckoutCommand)
|
|
@@ -105,11 +105,11 @@ if (!installedFunctionDeps) {
|
|
|
105
105
|
process.exit(1)
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
console.log(`Cloning Firebase Framework inside ${repoName}...`)
|
|
109
|
-
const clonedFirebaseFramework = runCommand(cloneFirebaseFrameworkCommand)
|
|
110
|
-
if (!clonedFirebaseFramework) {
|
|
111
|
-
|
|
112
|
-
}
|
|
108
|
+
// console.log(`Cloning Firebase Framework inside ${repoName}...`)
|
|
109
|
+
// const clonedFirebaseFramework = runCommand(cloneFirebaseFrameworkCommand)
|
|
110
|
+
// if (!clonedFirebaseFramework) {
|
|
111
|
+
// process.exit(1)
|
|
112
|
+
// }
|
|
113
113
|
|
|
114
114
|
console.log(`Successfully created ${repoName}!`)
|
|
115
115
|
console.log(`cd into ${repoName} and run 'sh firebase_init.sh' to initialize your firebase project.`)
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { toTypedSchema } from '@vee-validate/zod'
|
|
3
|
+
import * as z from 'zod'
|
|
4
|
+
const props = defineProps({
|
|
5
|
+
providers: {
|
|
6
|
+
type: Array,
|
|
7
|
+
default: () => ['email'],
|
|
8
|
+
},
|
|
9
|
+
primaryButtonClasses: {
|
|
10
|
+
type: String,
|
|
11
|
+
required: false,
|
|
12
|
+
},
|
|
13
|
+
secondaryButtonClasses: {
|
|
14
|
+
type: String,
|
|
15
|
+
reactive: false,
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const route = useRoute()
|
|
20
|
+
|
|
21
|
+
const edgeFirebase = inject('edgeFirebase')
|
|
22
|
+
// const edgeGlobal = inject('edgeGlobal')
|
|
23
|
+
|
|
24
|
+
const state = reactive({
|
|
25
|
+
form2: false,
|
|
26
|
+
phone: '',
|
|
27
|
+
email: '',
|
|
28
|
+
password: '',
|
|
29
|
+
passwordVisible: false,
|
|
30
|
+
passwordShow: false,
|
|
31
|
+
panel: '',
|
|
32
|
+
phoneConfirmDialog: false,
|
|
33
|
+
phoneNumber: null,
|
|
34
|
+
phoneCode: '',
|
|
35
|
+
forgotPasswordDialog: false,
|
|
36
|
+
passwordResetResult: { success: null, message: '' },
|
|
37
|
+
passwordResetSent: false,
|
|
38
|
+
passwordResetDialog: false,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const login = reactive({
|
|
42
|
+
email: '',
|
|
43
|
+
password: '',
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const sendPhoneCode = async () => {
|
|
47
|
+
state.phoneNumber = await edgeFirebase.sendPhoneCode(`${state.phone}`)
|
|
48
|
+
if (state.phoneNumber !== false) {
|
|
49
|
+
state.phoneConfirmDialog = true
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const phoneLogin = async () => {
|
|
54
|
+
await edgeFirebase.logInWithPhone(state.phoneNumber, state.phoneCode)
|
|
55
|
+
state.phoneConfirmDialog = false
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const submitForgotPassword = async () => {
|
|
59
|
+
const result = await edgeFirebase.sendPasswordReset(login.email)
|
|
60
|
+
state.passwordResetResult = result
|
|
61
|
+
state.passwordResetSent = true
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const resetPassword = async () => {
|
|
65
|
+
let result = null
|
|
66
|
+
if (route.query.mode === 'resetPassword') {
|
|
67
|
+
result = await edgeFirebase.passwordReset(login.password, route.query.oobCode)
|
|
68
|
+
}
|
|
69
|
+
if (route.query.mode !== 'resetPassword') {
|
|
70
|
+
result = await edgeFirebase.emailUpdate(route.query.oobCode)
|
|
71
|
+
}
|
|
72
|
+
state.passwordResetResult = result
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,50}$/
|
|
76
|
+
|
|
77
|
+
const loginSchema = toTypedSchema(z.object({
|
|
78
|
+
email: z.string().email().min(6).max(50),
|
|
79
|
+
password: z.string().superRefine((value, ctx) => {
|
|
80
|
+
if (value.length < 8 || value.length > 50 || !passwordPattern.test(value)) {
|
|
81
|
+
ctx.addIssue({
|
|
82
|
+
code: z.ZodIssueCode.custom,
|
|
83
|
+
message: 'Password must be 8–50 characters and include at least one uppercase letter, one lowercase letter, one number, and one special character (e.g., !@#$%^&*).',
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
}),
|
|
87
|
+
}))
|
|
88
|
+
|
|
89
|
+
const emailSchema = toTypedSchema(z.object({
|
|
90
|
+
email: z.string().email().min(6).max(50),
|
|
91
|
+
}))
|
|
92
|
+
|
|
93
|
+
const passwordSchema = toTypedSchema(z.object({
|
|
94
|
+
password: z.string().superRefine((value, ctx) => {
|
|
95
|
+
if (!passwordPattern.test(value)) {
|
|
96
|
+
ctx.addIssue({
|
|
97
|
+
code: z.ZodIssueCode.custom,
|
|
98
|
+
message: 'Password must be 8–50 characters and include at least one uppercase letter, one lowercase letter, one number, and one special character (e.g., !@#$%^&*).',
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
}),
|
|
102
|
+
}))
|
|
103
|
+
|
|
104
|
+
const phoneSchema = toTypedSchema(z.object({
|
|
105
|
+
phone: z.string().min(14, 'Not a valid phone number').max(14),
|
|
106
|
+
}))
|
|
107
|
+
|
|
108
|
+
const codeSchema = toTypedSchema(z.object({
|
|
109
|
+
phoneCode: z.string().min(1, 'Not a valid code'),
|
|
110
|
+
}))
|
|
111
|
+
|
|
112
|
+
const onSubmit = async (values) => {
|
|
113
|
+
await edgeFirebase.logIn(login)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const onPhoneSubmit = async (values) => {
|
|
117
|
+
console.log(values)
|
|
118
|
+
await sendPhoneCode()
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
onMounted(async () => {
|
|
122
|
+
state.panel = props.providers[0]
|
|
123
|
+
if (route.query.oobCode) {
|
|
124
|
+
await edgeFirebase.logOut()
|
|
125
|
+
state.passwordResetDialog = true
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const registerPath = computed(() => {
|
|
130
|
+
const firstPart = route.path.split('/')[1]
|
|
131
|
+
return `/${firstPart}/signup`
|
|
132
|
+
})
|
|
133
|
+
</script>
|
|
134
|
+
|
|
135
|
+
<template>
|
|
136
|
+
<edge-logging-in v-if="edgeFirebase.user.loggingIn !== false || edgeFirebase.user.loggedIn" />
|
|
137
|
+
<Card v-else>
|
|
138
|
+
<slot />
|
|
139
|
+
<CardContent>
|
|
140
|
+
<Accordion v-if="state.panel" v-model="state.panel" expand-icon="mdi-square-outline" :default-value="state.panel" collapse-icon="mdi-check">
|
|
141
|
+
<AccordionItem v-for="provider in props.providers" :key="provider" elevation="0" :value="provider">
|
|
142
|
+
<AccordionTrigger class="font-medium text-lg">
|
|
143
|
+
<template v-if="provider === 'email'">
|
|
144
|
+
Sign in with Email
|
|
145
|
+
</template>
|
|
146
|
+
<template v-if="provider === 'microsoft'">
|
|
147
|
+
Sign in with Microsoft
|
|
148
|
+
</template>
|
|
149
|
+
<template v-if="provider === 'phone'">
|
|
150
|
+
Sign in with Phone
|
|
151
|
+
</template>
|
|
152
|
+
</AccordionTrigger>
|
|
153
|
+
<AccordionContent>
|
|
154
|
+
<template v-if="provider === 'email'">
|
|
155
|
+
<edge-shad-form :schema="loginSchema" @submit="onSubmit">
|
|
156
|
+
<div class="grid gap-2 text-center">
|
|
157
|
+
<p class="text-balance text-muted-foreground">
|
|
158
|
+
Enter your email below to login to your account
|
|
159
|
+
</p>
|
|
160
|
+
</div>
|
|
161
|
+
<div class="grid gap-4">
|
|
162
|
+
<div class="grid gap-2">
|
|
163
|
+
<edge-shad-input
|
|
164
|
+
v-model="login.email"
|
|
165
|
+
name="email"
|
|
166
|
+
type="email"
|
|
167
|
+
label="Email"
|
|
168
|
+
placeholder="m@example.com"
|
|
169
|
+
/>
|
|
170
|
+
</div>
|
|
171
|
+
<div class="grid gap-2">
|
|
172
|
+
<edge-shad-input
|
|
173
|
+
v-model="login.password"
|
|
174
|
+
name="password"
|
|
175
|
+
type="password"
|
|
176
|
+
label="Password"
|
|
177
|
+
>
|
|
178
|
+
<a
|
|
179
|
+
class="text-sm underline cursor-pointer"
|
|
180
|
+
@click="state.forgotPasswordDialog = true"
|
|
181
|
+
>
|
|
182
|
+
Forgot your password?
|
|
183
|
+
</a>
|
|
184
|
+
</edge-shad-input>
|
|
185
|
+
</div>
|
|
186
|
+
<edge-shad-button type="submit" :class="props.primaryButtonClasses">
|
|
187
|
+
Login
|
|
188
|
+
</edge-shad-button>
|
|
189
|
+
</div>
|
|
190
|
+
</edge-shad-form>
|
|
191
|
+
</template>
|
|
192
|
+
<template v-if="provider === 'phone'">
|
|
193
|
+
<edge-shad-form :schema="phoneSchema" @submit="onPhoneSubmit">
|
|
194
|
+
<edge-shad-input
|
|
195
|
+
v-model="state.phone"
|
|
196
|
+
name="phone"
|
|
197
|
+
type="tel"
|
|
198
|
+
label="Phone Number"
|
|
199
|
+
placeholder="(555) 555-5555"
|
|
200
|
+
:mask-options="{ mask: '(###) ###-####' }"
|
|
201
|
+
class="mb-4"
|
|
202
|
+
/>
|
|
203
|
+
<edge-shad-button type="submit" :class="props.primaryButtonClasses">
|
|
204
|
+
Login
|
|
205
|
+
</edge-shad-button>
|
|
206
|
+
</edge-shad-form>
|
|
207
|
+
</template>
|
|
208
|
+
<template v-if="provider === 'microsoft'">
|
|
209
|
+
<edge-shad-button :class="props.primaryButtonClasses" class="w-full" @click="edgeFirebase.logInWithMicrosoft()">
|
|
210
|
+
Sign in with Microsoft
|
|
211
|
+
</edge-shad-button>
|
|
212
|
+
</template>
|
|
213
|
+
</AccordionContent>
|
|
214
|
+
</AccordionItem>
|
|
215
|
+
</Accordion>
|
|
216
|
+
<edge-g-error v-if="edgeFirebase.user.logInError" :error="edgeFirebase.user.logInErrorMessage" />
|
|
217
|
+
<Separator
|
|
218
|
+
class="my-4 dark:bg-slate-600"
|
|
219
|
+
/>
|
|
220
|
+
Don't have an account?
|
|
221
|
+
<edge-shad-button class="bg-secondary text-secondary-foreground" :class="props.secondaryButtonClasses" :to="registerPath">
|
|
222
|
+
Sign up here.
|
|
223
|
+
</edge-shad-button>
|
|
224
|
+
<edge-shad-dialog
|
|
225
|
+
v-model="state.passwordResetDialog"
|
|
226
|
+
>
|
|
227
|
+
<DialogContent>
|
|
228
|
+
<DialogHeader>
|
|
229
|
+
<DialogTitle>
|
|
230
|
+
<span v-if="route.query.mode === 'resetPassword'">
|
|
231
|
+
Reset Password
|
|
232
|
+
|
|
233
|
+
</span>
|
|
234
|
+
<span v-else>
|
|
235
|
+
Update Email Address
|
|
236
|
+
</span>
|
|
237
|
+
</DialogTitle>
|
|
238
|
+
<DialogDescription class="text-left mb-2">
|
|
239
|
+
<span v-if="route.query.mode === 'resetPassword'" class="mb-2">
|
|
240
|
+
Enter your new password below and click "Reset Password".
|
|
241
|
+
</span>
|
|
242
|
+
<template v-else>
|
|
243
|
+
<p class="mb-2">
|
|
244
|
+
To update your email address, click "Update Email Address".
|
|
245
|
+
</p>
|
|
246
|
+
<p class="mb-2">
|
|
247
|
+
This will change your email address to the address that received the email with the link you clicked on to get here.
|
|
248
|
+
</p>
|
|
249
|
+
</template>
|
|
250
|
+
</DialogDescription>
|
|
251
|
+
</DialogHeader>
|
|
252
|
+
<edge-shad-form
|
|
253
|
+
:schema="passwordSchema"
|
|
254
|
+
@submit="resetPassword"
|
|
255
|
+
>
|
|
256
|
+
<edge-shad-input
|
|
257
|
+
v-if="route.query.mode === 'resetPassword'"
|
|
258
|
+
v-model="login.password"
|
|
259
|
+
name="password"
|
|
260
|
+
type="password"
|
|
261
|
+
label="Password"
|
|
262
|
+
/>
|
|
263
|
+
<edge-g-error v-if="state.passwordResetResult.success === false" :error="state.passwordResetResult.message" />
|
|
264
|
+
<Alert v-if="state.passwordResetResult.success === true" class="mt-2 bg-green-800">
|
|
265
|
+
<AlertDescription>
|
|
266
|
+
<span v-if="route.query.mode === 'resetPassword'">
|
|
267
|
+
Your password has been reset. Close this dialog and log in with your new password.
|
|
268
|
+
</span>
|
|
269
|
+
<span v-else>
|
|
270
|
+
Your email address has been updated. Close this dialog and log in with your updated address.
|
|
271
|
+
</span>
|
|
272
|
+
</AlertDescription>
|
|
273
|
+
</Alert>
|
|
274
|
+
<DialogFooter v-if="route.query.mode === 'resetPassword'" class="flex justify-between pt-6">
|
|
275
|
+
<edge-shad-button v-if="state.passwordResetResult.success === true" variant="destructive" @click="state.passwordResetDialog = false">
|
|
276
|
+
Close
|
|
277
|
+
</edge-shad-button>
|
|
278
|
+
<edge-shad-button v-else variant="destructive" @click="state.passwordResetDialog = false">
|
|
279
|
+
Cancel
|
|
280
|
+
</edge-shad-button>
|
|
281
|
+
<edge-shad-button v-if="state.passwordResetResult.success !== true" :class="props.primaryButtonClasses" type="submit">
|
|
282
|
+
Reset Password
|
|
283
|
+
</edge-shad-button>
|
|
284
|
+
</DialogFooter>
|
|
285
|
+
</edge-shad-form>
|
|
286
|
+
<edge-shad-form
|
|
287
|
+
v-if="route.query.mode !== 'resetPassword'"
|
|
288
|
+
@submit="resetPassword"
|
|
289
|
+
>
|
|
290
|
+
<DialogFooter class="pt-6 flex justify-between">
|
|
291
|
+
<edge-shad-button v-if="state.passwordResetResult.success === true" variant="destructive" @click="state.passwordResetDialog = false">
|
|
292
|
+
Close
|
|
293
|
+
</edge-shad-button>
|
|
294
|
+
<edge-shad-button v-else variant="destructive" @click="state.passwordResetDialog = false">
|
|
295
|
+
Cancel
|
|
296
|
+
</edge-shad-button>
|
|
297
|
+
<edge-shad-button v-if="state.passwordResetResult.success !== true" :class="props.primaryButtonClasses" type="submit">
|
|
298
|
+
Update Email Address
|
|
299
|
+
</edge-shad-button>
|
|
300
|
+
</DialogFooter>
|
|
301
|
+
</edge-shad-form>
|
|
302
|
+
</DialogContent>
|
|
303
|
+
</edge-shad-dialog>
|
|
304
|
+
|
|
305
|
+
<edge-shad-dialog
|
|
306
|
+
v-model="state.forgotPasswordDialog"
|
|
307
|
+
>
|
|
308
|
+
<DialogContent>
|
|
309
|
+
<edge-shad-form
|
|
310
|
+
:schema="emailSchema"
|
|
311
|
+
@submit="submitForgotPassword"
|
|
312
|
+
>
|
|
313
|
+
<DialogHeader>
|
|
314
|
+
<DialogTitle>Password Reset</DialogTitle>
|
|
315
|
+
<DialogDescription class="text-left mb-2">
|
|
316
|
+
If you forgot your password, please enter your email address below and click "Send Password Reset".
|
|
317
|
+
</DialogDescription>
|
|
318
|
+
</DialogHeader>
|
|
319
|
+
<edge-shad-input
|
|
320
|
+
v-model="login.email"
|
|
321
|
+
init-valu
|
|
322
|
+
name="email"
|
|
323
|
+
type="email"
|
|
324
|
+
label="Email"
|
|
325
|
+
placeholder="m@example.com"
|
|
326
|
+
class="mb-4"
|
|
327
|
+
/>
|
|
328
|
+
<Alert v-if="state.passwordResetSent" class="my-2 bg-green-800">
|
|
329
|
+
<AlertDescription>
|
|
330
|
+
If you entered the correct email address, a password reset email has been sent to your email address. Please check your email and click the link to reset your password.
|
|
331
|
+
</AlertDescription>
|
|
332
|
+
</Alert>
|
|
333
|
+
<DialogFooter class="pt-0 flex justify-between">
|
|
334
|
+
<edge-shad-button v-if="state.passwordResetSent === true" variant="destructive" @click="state.forgotPasswordDialog = false; state.passwordResetSent = false;">
|
|
335
|
+
Close
|
|
336
|
+
</edge-shad-button>
|
|
337
|
+
<edge-shad-button v-else variant="destructive" @click="state.forgotPasswordDialog = false; state.passwordResetSent = false;">
|
|
338
|
+
Cancel
|
|
339
|
+
</edge-shad-button>
|
|
340
|
+
<edge-shad-button v-if="state.passwordResetSent === false" :class="props.primaryButtonClasses" type="submit">
|
|
341
|
+
Send Password Reset
|
|
342
|
+
</edge-shad-button>
|
|
343
|
+
</DialogFooter>
|
|
344
|
+
</edge-shad-form>
|
|
345
|
+
</DialogContent>
|
|
346
|
+
</edge-shad-dialog>
|
|
347
|
+
<edge-shad-dialog
|
|
348
|
+
v-model="state.phoneConfirmDialog"
|
|
349
|
+
>
|
|
350
|
+
<DialogContent>
|
|
351
|
+
<edge-shad-form
|
|
352
|
+
:schema="codeSchema"
|
|
353
|
+
@submit="phoneLogin"
|
|
354
|
+
>
|
|
355
|
+
<DialogHeader>
|
|
356
|
+
<DialogTitle>Enter Confirmation Code</DialogTitle>
|
|
357
|
+
<DialogDescription class="text-left mb-2">
|
|
358
|
+
Please enter the confirmation code that you received via text message. This code is used to verify your phone number. If you did not receive a text message, please confirm that your phone number is correct and request a new code.
|
|
359
|
+
</DialogDescription>
|
|
360
|
+
</DialogHeader>
|
|
361
|
+
<edge-shad-input
|
|
362
|
+
v-model="state.phoneCode"
|
|
363
|
+
name="phoneCode"
|
|
364
|
+
type="text"
|
|
365
|
+
label="Confirmation Code"
|
|
366
|
+
/>
|
|
367
|
+
|
|
368
|
+
<DialogFooter class="pt-6 flex justify-between">
|
|
369
|
+
<edge-shad-button variant="destructive" @click="state.phoneConfirmDialog = false">
|
|
370
|
+
Cancel
|
|
371
|
+
</edge-shad-button>
|
|
372
|
+
<edge-shad-button :class="props.primaryButtonClasses" type="submit">
|
|
373
|
+
Submit
|
|
374
|
+
</edge-shad-button>
|
|
375
|
+
</DialogFooter>
|
|
376
|
+
</edge-shad-form>
|
|
377
|
+
</DialogContent>
|
|
378
|
+
</edge-shad-dialog>
|
|
379
|
+
</CardContent>
|
|
380
|
+
</Card>
|
|
381
|
+
</template>
|
|
382
|
+
|
|
383
|
+
<style lang="scss" scoped>
|
|
384
|
+
</style>
|