Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add forgot password component #104

Merged
merged 17 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion frontend/src/lib/components/ChildrenRegistration.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
{
label: 'Abschließen',
onclick: async () => {
console.log('build shit');
const childData = buildDataToSend(data);
const required = buildRequired(data);
const verified = await verifyInput(childData, required);
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/lib/components/DataDisplay/GalleryDisplay.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
const index = data.indexOf(item);
return componentProps[index];
});

$: console.log('data in gallery: ', data);
</script>

<div class="mx-auto p-4">
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/components/DataInput/DataInput.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// variables
export let component: any;
export let value: any;
export let label: string;
export let label: string | null = null;
export let componentClass: string = '';
export let textTrigger: string = 'noAdditionalText';
export let showTextField: boolean = false;
Expand Down
105 changes: 105 additions & 0 deletions frontend/src/lib/components/UserForgotPassword.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { base } from '$app/paths';
import { resetForgotPassword } from '$lib/client/services.gen';
import AlertMessage from '$lib/components/AlertMessage.svelte';
import DataInput from '$lib/components/DataInput/DataInput.svelte';
import { Button, Card, Heading, Input } from 'flowbite-svelte';
import { _ } from 'svelte-i18n';

const maildata = {
component: Input,
type: 'text',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you make the type 'email' and make it required then you get validation of the email automatically: see e.g. https://github.com/ssciwr/mondey/blob/main/frontend/src/lib/components/Admin/Login.svelte#L24-L31

value: null,
props: {
placeholder: $_('user.forgotPw.placeholder')
}
};

let alertMessage: string = $_('user.forgotPw.formatError');
let valid: boolean = true;
let showAlert: boolean = !valid;
let showSuccess: boolean = false;

function validateEmail(value: string | null): boolean {
if (value === null) {
return false;
} else {
const mailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return mailRegex.test(value);
}
}

async function submitData(mailstring: string): Promise<void> {
const data = {
body: {
email: mailstring
},
throwOnError: true
};

await resetForgotPassword(data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's not recommended to mix await and .then styles - can lead to confusion (see e.g. this random blog post https://maximorlov.com/why-you-shouldnt-mix-promise-then-with-async-await/)

Copy link
Collaborator Author

@MaHaWo MaHaWo Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok. With respect to the linked blog post I don´t think it's a problem in this specific case because it has a catch block at the end, but as a general rule it's certainly valid...

.then((returned) => {
console.log('successful transmission, response status: ', returned.response.status);
showSuccess = true;
})
.catch((error) => {
console.log(error);
showAlert = true;
alertMessage = $_('user.forgotPw.sendError');
});
}
</script>

{#if showAlert}
<AlertMessage
title={$_('user.forgotPw.alertTitle')}
message={alertMessage}
lastpage={`${base}/userLand/lostPassword`}
onclick={() => {
showAlert = false;
}}
/>
{/if}

<Card class="container m-2 mx-auto w-full max-w-xl items-center justify-center p-2">
<Heading
tag="h3"
class="m-2 p-2 text-center font-bold tracking-tight text-gray-700 dark:text-gray-400"
>{$_('user.forgotPw.heading')}</Heading
>
{#if showSuccess === false}
<div class="m-2 mx-auto w-full flex-col space-y-6 p-2">
<DataInput
component={maildata.component}
bind:value={maildata.value}
properties={maildata.props}
/>
</div>

<div class="m-2 flex w-full items-center justify-center p-2">
<Button
size="md"
on:click={(event) => {
valid = validateEmail(maildata.value);
showAlert = !valid;
if (valid) {
submitData(maildata.value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you wrap the inputs in a form and make the button of type "submit" then the user pressing enter will press the button, e.g.

<form onsubmit={preventDefault(doLogin)}>

<Button type="submit" class="mb-6">Login</Button>

}
}}>{$_('user.forgotPw.pending')}</Button
>
</div>
{:else}
<div class="m-2 flex w-full items-center justify-center p-2">
<p>{$_('user.forgotPw.mailSentMessage')}</p>
</div>
<div class="m-2 flex w-full items-center justify-center p-2">
<Button
size="md"
on:click={(event) => {
goto(`/${base}`);
}}>{$_('user.forgotPw.success')}</Button
>
</div>
{/if}
</Card>
13 changes: 13 additions & 0 deletions frontend/src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,18 @@
"help": "Förderhilfen",
"image": "Bild",
"images": "Bilder"
},
"user": {
MaHaWo marked this conversation as resolved.
Show resolved Hide resolved
"login": {},
"forgotPw": {
"heading": "Passwort vergessen?",
"placeholder": "Bitte geben sie eine E-mail Adresse an um ihr Passwort zu erneuern",
"success": "Zurück zur Startseite",
"pending": "Absenden",
"alertTitle": "Fehler",
"formatError": "Die angegebene email Adresse hat ein falsches Format",
"mailSentMessage": "Bitte überprüfen sie ihr E-Mail Postfach",
"sendError": "Beim Senden der Daten ist ein Fehler aufgetreten. Bitte versuchen sie es erneut"
}
}
}
13 changes: 13 additions & 0 deletions frontend/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,18 @@
"help": "More information",
"image": "Image",
"images": "Images"
},
"user": {
"login": {},
"forgotPw": {
"heading": "Forgot your password?",
"placeholder": "Please enter your e-mail adress to get a new password",
"success": "Back to home",
"pending": "Send",
"alertTitle": "Error",
"formatError": "The given e-mail adress has a wrong format.",
"mailSentMessage": "Please check your e-mail inbox",
"sendError": "An error occured while sending the data. Please try again."
}
}
}
5 changes: 5 additions & 0 deletions frontend/src/routes/userLand/lostPassword/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
import UserForgotPassword from '$lib/components/UserForgotPassword.svelte';
</script>

<UserForgotPassword />