feat(#3): Add forgot password functionality

This commit is contained in:
Josh Creek
2024-06-06 19:21:16 +01:00
parent 79715504e7
commit ec1f9a993d
4 changed files with 179 additions and 18 deletions
+57 -2
View File
@@ -1,5 +1,7 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { general } from '$lib/stores/generalStore.js';
const dispatch = createEventDispatcher();
function emitSignedInEvent() {
@@ -23,6 +25,59 @@
emitSignedInEvent();
});
}
async function forgotPassword() {
if (email === '') {
general.update((value) => {
return {
...value,
hideToast: false,
toastMessage: 'Please enter your email address',
toastType: 'error'
};
});
setTimeout(() => {
general.update((value) => {
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
});
}, 5000);
return;
}
const { data, error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: 'https://example.com/auth/update-password'
});
if (error) {
console.error('Error sending password reset email:', error.message);
general.update((value) => {
return {
...value,
hideToast: false,
toastMessage: 'Error sending password reset email. Please try again.',
toastType: 'error'
};
});
} else {
console.log('Password reset email sent:', data);
general.update((value) => {
return {
...value,
hideToast: false,
toastMessage: 'Password reset email sent. Please check your inbox.',
toastType: 'success'
};
});
}
setTimeout(() => {
general.update((value) => {
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
});
}, 5000);
}
</script>
<div class="card shrink-0 w-full max-w-sm shadow-2xl bg-base-100">
@@ -60,9 +115,9 @@
</label>
</div>
<div class="form-control">
<a href="/" id="forgot-password" class="label-text-alt link link-hover">
<button id="forgot-password" class="label-text-alt link link-hover" on:click={forgotPassword}>
Forgot your password?
</a>
</button>
</div>
<div class="form-control mt-2">
<button class="btn btn-primary" on:click={signInWithEmail}>Sign In</button>
+1 -1
View File
@@ -1,3 +1,3 @@
import { writable } from 'svelte/store';
export const general = writable({ hideToast: true });
export const general = writable({ hideToast: true, toastMessage: '', toastType: 'success' });
+40 -15
View File
@@ -237,25 +237,50 @@
</footer>
<div
id="success-toast"
id={localGeneral.toastType == 'success' ? 'success-toast' : 'error-toast'}
role="alert"
class="alert alert-success fixed top-20 right-3 max-w-52 text-white {localGeneral.hideToast
class="alert {localGeneral.toastType == 'success'
? 'alert-success'
: 'alert-error'} fixed top-20 right-3 max-w-52 text-white {localGeneral.hideToast
? 'hidden'
: ''}"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
<span>Added to basket</span>
{#if localGeneral.toastType == 'success'}
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
{:else}
<svg
class="stroke-current shrink-0 h-6 w-6"
viewBox="0 0 32 32"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
><g
><g id="Error_1_"
><g id="Error">
<circle cx="16" cy="16" id="BG" r="16" style="fill:#E6E6E6;" />
<path
d="M14.5,25h3v-3h-3V25z M14.5,6v13h3V6H14.5z"
id="Exclamatory_x5F_Sign"
style="fill:#D72828;"
/>
</g>
</g></g
></svg
>
{/if}
<span>{localGeneral.toastMessage == '' ? 'Added to basket' : localGeneral.toastMessage}</span>
</div>
<style scoped>
@@ -0,0 +1,81 @@
<script lang="ts">
import { general } from '$lib/stores/generalStore.js';
// Access the supabase client from the layout data
export let supabase: any;
let newPassword = '';
async function resetPassword() {
if (newPassword === '') {
general.update((value) => {
return {
...value,
hideToast: false,
toastMessage: 'Please enter a new password',
toastType: 'error'
};
});
setTimeout(() => {
general.update((value) => {
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
});
}, 5000);
return;
}
const { data, error } = await supabase.auth.updateUser({
password: newPassword
});
if (error) {
console.error('Error updating password:', error.message);
general.update((value) => {
return {
...value,
hideToast: false,
toastMessage: 'Error updating password. Please try again.',
toastType: 'error'
};
});
setTimeout(() => {
general.update((value) => {
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
});
}, 5000);
return;
} else {
general.update((value) => {
return {
...value,
hideToast: false,
toastMessage: 'Password updated successfully. Please sign in with your new password.',
toastType: 'success'
};
});
setTimeout(() => {
general.update((value) => {
return { ...value, hideToast: true, toastMessage: '', toastType: 'success' };
});
}, 5000);
}
}
</script>
<svelte:head>
<title>Update Password</title>
</svelte:head>
<main>
<h1>Update Password</h1>
<form on:submit|preventDefault={resetPassword}>
<label for="newPassword">New Password</label>
<input type="password" id="newPassword" bind:value={newPassword} />
<button type="submit">Update Password</button>
</form>
</main>