|
1 | 1 | <script lang="ts"> |
2 | 2 | import { invalidate, goto } from '$app/navigation'; |
| 3 | + import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; |
3 | 4 | import { Modal } from '$lib/components'; |
4 | | - import { Button } from '$lib/elements/forms'; |
| 5 | + import { Button, InputEmail, InputPassword } from '$lib/elements/forms'; |
5 | 6 | import { sdk } from '$lib/stores/sdk'; |
6 | 7 | import { user } from '$lib/stores/user'; |
7 | 8 | import { get } from 'svelte/store'; |
|
28 | 29 | let resendTimer = $state(0); |
29 | 30 | let timerInterval: ReturnType<typeof setInterval> | null = null; |
30 | 31 |
|
| 32 | + let showUpdateEmail = $state(false); |
| 33 | + let newEmail = $state(''); |
| 34 | + let newPassword = $state(''); |
| 35 | + let updating = $state(false); |
| 36 | +
|
| 37 | + $effect(() => { |
| 38 | + if (showUpdateEmail) { |
| 39 | + newEmail = email || get(user)?.email || ''; |
| 40 | + } |
| 41 | + }); |
| 42 | +
|
31 | 43 | async function logout() { |
32 | 44 | error = null; |
33 | 45 | try { |
|
114 | 126 | } |
115 | 127 | } |
116 | 128 |
|
| 129 | + async function updateEmail() { |
| 130 | + error = null; |
| 131 | + updating = true; |
| 132 | + try { |
| 133 | + await sdk.forConsole.account.updateEmail({ |
| 134 | + email: newEmail, |
| 135 | + password: newPassword |
| 136 | + }); |
| 137 | + await invalidate(Dependencies.ACCOUNT); |
| 138 | + trackEvent(Submit.AccountUpdateEmail); |
| 139 | + resetUpdateEmailForm(); |
| 140 | + } catch (err) { |
| 141 | + error = err.message; |
| 142 | + trackError(err, Submit.AccountUpdateEmail); |
| 143 | + } finally { |
| 144 | + updating = false; |
| 145 | + } |
| 146 | + } |
| 147 | +
|
| 148 | + function resetUpdateEmailForm() { |
| 149 | + showUpdateEmail = false; |
| 150 | + newEmail = ''; |
| 151 | + newPassword = ''; |
| 152 | + error = null; |
| 153 | + } |
| 154 | +
|
117 | 155 | onMount(restoreTimerState); |
118 | 156 |
|
119 | 157 | onDestroy(() => { |
|
129 | 167 | </script> |
130 | 168 |
|
131 | 169 | <div class="email-verification-scrim"> |
132 | | - <Modal |
133 | | - bind:show |
134 | | - bind:error |
135 | | - title="Verify your email address" |
136 | | - {onSubmit} |
137 | | - dismissible={false} |
138 | | - autoClose={false} |
139 | | - backdrop={false}> |
140 | | - <Card.Base variant="secondary" padding="s"> |
141 | | - <Layout.Stack gap="xxs"> |
142 | | - <Typography.Text gap="m"> |
143 | | - To continue using Appwrite Cloud, please verify your email address. An email |
144 | | - will be sent to <Typography.Text |
145 | | - variant="m-600" |
146 | | - color="neutral-secondary" |
147 | | - style="display: inline;">{email || get(user)?.email}</Typography.Text> |
148 | | - </Typography.Text> |
149 | | - |
150 | | - <Link variant="default" on:click={() => logout()}>Switch account</Link> |
151 | | - |
152 | | - {#if emailSent && resendTimer > 0} |
153 | | - <div transition:slide={{ duration: 150 }}> |
154 | | - <Typography.Text |
| 170 | + {#if !showUpdateEmail} |
| 171 | + <Modal |
| 172 | + bind:show |
| 173 | + bind:error |
| 174 | + title="Verify your email address" |
| 175 | + {onSubmit} |
| 176 | + dismissible={false} |
| 177 | + autoClose={false} |
| 178 | + backdrop={false}> |
| 179 | + <Card.Base variant="secondary" padding="s"> |
| 180 | + <Layout.Stack gap="xxs"> |
| 181 | + <Typography.Text gap="m"> |
| 182 | + To continue using Appwrite Cloud, please verify your email address. An email |
| 183 | + will be sent to <Typography.Text |
| 184 | + variant="m-600" |
155 | 185 | color="neutral-secondary" |
156 | | - style="margin-block-start: var(--gap-L, 16px);"> |
157 | | - Didn't get the email? Try again in {resendTimer}s |
158 | | - </Typography.Text> |
159 | | - </div> |
160 | | - {/if} |
161 | | - </Layout.Stack> |
162 | | - </Card.Base> |
163 | | - |
164 | | - <svelte:fragment slot="footer"> |
165 | | - <Button |
166 | | - submit |
167 | | - submissionLoader |
168 | | - forceShowLoader={creating} |
169 | | - disabled={creating || resendTimer > 0}> |
170 | | - {emailSent ? 'Resend email' : 'Send email'} |
171 | | - </Button> |
172 | | - </svelte:fragment> |
173 | | - </Modal> |
| 186 | + style="display: inline;">{email || get(user)?.email}</Typography.Text> |
| 187 | + </Typography.Text> |
| 188 | + |
| 189 | + <Typography.Text> |
| 190 | + Wrong email? <Link |
| 191 | + variant="default" |
| 192 | + on:click={() => { |
| 193 | + showUpdateEmail = true; |
| 194 | + error = null; |
| 195 | + }}>Update email address</Link> or <Link |
| 196 | + variant="default" |
| 197 | + on:click={() => logout()}>Switch account</Link> |
| 198 | + </Typography.Text> |
| 199 | + |
| 200 | + {#if emailSent && resendTimer > 0} |
| 201 | + <div transition:slide={{ duration: 150 }}> |
| 202 | + <Typography.Text |
| 203 | + color="neutral-secondary" |
| 204 | + style="margin-block-start: var(--gap-L, 16px);"> |
| 205 | + Didn't get the email? Try again in {resendTimer}s |
| 206 | + </Typography.Text> |
| 207 | + </div> |
| 208 | + {/if} |
| 209 | + </Layout.Stack> |
| 210 | + </Card.Base> |
| 211 | + |
| 212 | + <svelte:fragment slot="footer"> |
| 213 | + <Button |
| 214 | + submit |
| 215 | + submissionLoader |
| 216 | + forceShowLoader={creating} |
| 217 | + disabled={creating || resendTimer > 0}> |
| 218 | + {emailSent ? 'Resend email' : 'Send email'} |
| 219 | + </Button> |
| 220 | + </svelte:fragment> |
| 221 | + </Modal> |
| 222 | + {:else} |
| 223 | + <Modal |
| 224 | + bind:show={showUpdateEmail} |
| 225 | + bind:error |
| 226 | + title="Update email address" |
| 227 | + onSubmit={updateEmail} |
| 228 | + autoClose={false} |
| 229 | + backdrop={false}> |
| 230 | + <InputEmail |
| 231 | + id="new-email" |
| 232 | + label="Email" |
| 233 | + placeholder="Enter email" |
| 234 | + bind:value={newEmail} |
| 235 | + required |
| 236 | + helper="You'll need access to this email to verify your account" /> |
| 237 | + <InputPassword |
| 238 | + id="update-password" |
| 239 | + label="Password" |
| 240 | + placeholder="Enter password" |
| 241 | + required |
| 242 | + bind:value={newPassword} /> |
| 243 | + |
| 244 | + <svelte:fragment slot="footer"> |
| 245 | + <Button text on:click={resetUpdateEmailForm}>Cancel</Button> |
| 246 | + <Button submit submissionLoader forceShowLoader={updating} disabled={updating} |
| 247 | + >Update</Button> |
| 248 | + </svelte:fragment> |
| 249 | + </Modal> |
| 250 | + {/if} |
174 | 251 | </div> |
175 | 252 |
|
176 | 253 | <style> |
|
0 commit comments