Skip to content

Commit d3818de

Browse files
authored
Merge branch 'main' into unify-navbars
2 parents 4cc3956 + 825089f commit d3818de

7 files changed

+210
-4
lines changed

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ repos:
99
- id: check-toml
1010

1111
- repo: https://github.com/astral-sh/ruff-pre-commit
12-
rev: v0.9.9
12+
rev: v0.9.10
1313
hooks:
1414
- id: ruff
1515
types_or: [python, pyi, jupyter]

DEVELOPMENT.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,17 @@ cd mondey
6666

6767
```sh
6868
cd mondey_backend
69-
pip install .
69+
pip install -e .
7070
cd ..
7171
mondey-backend
7272
```
73+
(run the last command above in the `mondey/mondey-backend` folder itself)
74+
75+
7376

7477
3. install and run the frontend development server:
7578

79+
3.1: Run the frontend
7680
```sh
7781
cd frontend
7882
pnpm install

frontend/.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# api location for local development:
2-
VITE_MONDEY_API_URL=http://localhost:8000/api
2+
VITE_MONDEY_API_URL=http://localhost:5173/api

frontend/src/lib/components/AlertMessage.svelte

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Alert, Button } from "flowbite-svelte";
55
import { EyeSolid, InfoCircleSolid } from "flowbite-svelte-icons";
66
77
let {
8+
id = "alertMessage",
89
message = "",
910
title = "",
1011
infotitle = "",
@@ -14,6 +15,7 @@ let {
1415
console.log(event);
1516
},
1617
}: {
18+
id?: string;
1719
message?: string;
1820
title?: string;
1921
infotitle?: string;
@@ -23,7 +25,7 @@ let {
2325
} = $props();
2426
</script>
2527

26-
<Alert class="m-4 p-4">
28+
<Alert id={`${id}`} class="m-4 p-4">
2729
<div class="flex items-center gap-3">
2830
<InfoCircleSolid class="h-5 w-5" />
2931
<span class="text-lg font-medium"> {title} </span>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
<svelte:options runes={true} />
2+
3+
<script lang="ts">
4+
import {
5+
authCookieLogin,
6+
usersCurrentUser,
7+
usersPatchCurrentUser,
8+
} from "$lib/client/services.gen";
9+
import { i18n } from "$lib/i18n.svelte";
10+
import { preventDefault } from "$lib/util";
11+
import { Button, Heading, Input, Label, Modal } from "flowbite-svelte";
12+
import AlertMessage from "./AlertMessage.svelte";
13+
14+
let newPassword = $state(null) as string | null;
15+
let newPasswordRepeat = $state(null) as string | null;
16+
let currentPassword = $state(null) as string | null;
17+
let currentPasswordValid = $state(false);
18+
let passwordChangeSuccess = $state(false);
19+
let showAlert = $state(false);
20+
let alertMessage = $state(i18n.tr.settings.defaultAlertMessage);
21+
22+
async function submitNewPassword() {
23+
currentPasswordValid = false;
24+
passwordChangeSuccess = false;
25+
showAlert = false;
26+
27+
if (currentPassword === null || currentPassword === "") {
28+
showAlert = true;
29+
alertMessage = i18n.tr.settings.emptyPasswordError;
30+
return;
31+
}
32+
33+
if (newPassword === null || newPassword === "") {
34+
showAlert = true;
35+
alertMessage = i18n.tr.settings.emptyPasswordError;
36+
return;
37+
}
38+
39+
if (newPassword !== newPasswordRepeat) {
40+
showAlert = true;
41+
alertMessage = i18n.tr.settings.nonMatchingPasswordsError;
42+
return;
43+
}
44+
45+
if (newPassword === currentPassword) {
46+
showAlert = true;
47+
alertMessage = i18n.tr.settings.samePasswordsError;
48+
return;
49+
}
50+
51+
const currentUser = await usersCurrentUser();
52+
53+
if (currentUser.error || !currentUser.data) {
54+
alertMessage = i18n.tr.settings.getUserError;
55+
showAlert = true;
56+
return;
57+
}
58+
59+
const verifyResponse = await authCookieLogin({
60+
body: {
61+
username: currentUser.data.email,
62+
password: currentPassword,
63+
},
64+
});
65+
66+
if (verifyResponse.error) {
67+
alertMessage = i18n.tr.settings.oldPasswordWrong;
68+
showAlert = true;
69+
return;
70+
}
71+
72+
currentPasswordValid = true;
73+
74+
const patchResponse = await usersPatchCurrentUser({
75+
body: {
76+
password: newPassword,
77+
},
78+
});
79+
80+
if (patchResponse.error) {
81+
alertMessage = i18n.tr.settings.sendError;
82+
showAlert = true;
83+
passwordChangeSuccess = false;
84+
} else {
85+
passwordChangeSuccess = true;
86+
}
87+
}
88+
</script>
89+
90+
{#if showAlert}
91+
<AlertMessage
92+
id="alertMessageSettings"
93+
title={i18n.tr.settings.alertTitle}
94+
message={alertMessage}
95+
onclick={() => {
96+
showAlert = false;
97+
}}
98+
/>
99+
{/if}
100+
101+
<div class="m-2 p-2 flex flex-col space-y-2 text-gray-700 dark:text-gray-400">
102+
<Heading
103+
tag="h4"
104+
class="m-1 mb-3 p-1 text-center font-bold tracking-tight text-gray-700 dark:text-gray-400"
105+
id="changePasswordHeading">{i18n.tr.settings.changePassword}</Heading
106+
>
107+
<form
108+
class="m-2 mx-auto w-full flex-col space-y-6"
109+
onsubmit={preventDefault(submitNewPassword)}
110+
>
111+
<Label
112+
class="font-semibold text-gray-700 dark:text-gray-400"
113+
id="oldPasswordLabel"
114+
for="oldPassword">{i18n.tr.settings.enterPassword}</Label
115+
>
116+
<Input
117+
bind:value={currentPassword}
118+
type="password"
119+
id="oldPassword"
120+
required
121+
placeholder={i18n.tr.settings.placeholder}
122+
autocomplete="current-password"
123+
/>
124+
125+
<Label
126+
class="font-semibold text-gray-700 dark:text-gray-400"
127+
id="newPasswordLabel"
128+
for="newPassword">{i18n.tr.settings.newPassword}</Label
129+
>
130+
<Input
131+
bind:value={newPassword}
132+
type="password"
133+
id="newPassword"
134+
required
135+
placeholder={i18n.tr.settings.placeholder}
136+
/>
137+
138+
<Label
139+
class="font-semibold text-gray-700 dark:text-gray-400"
140+
id="newPasswordConfirmLabel"
141+
for="newPasswordConfirm"
142+
>{i18n.tr.settings.newPasswordConfirm}</Label
143+
>
144+
<Input
145+
bind:value={newPasswordRepeat}
146+
type="password"
147+
id="newPasswordConfirm"
148+
required
149+
placeholder={i18n.tr.settings.placeholder}
150+
/>
151+
152+
<Button id="changePasswordSubmitButton" size="lg" type="submit"
153+
>{i18n.tr.settings.confirmChange}</Button
154+
>
155+
</form>
156+
157+
<Modal
158+
id="passwordChangeSuccessModal"
159+
classBody="flex flex-col pb-2 mb-2 items-center"
160+
bind:open={passwordChangeSuccess}
161+
dismissable={false}
162+
>
163+
<span class="mb-2 pb-2"
164+
>{i18n.tr.settings.confirmPasswordChangeSuccess}</span
165+
>
166+
<Button
167+
id="ModalCloseButton"
168+
type="button"
169+
on:click={() => {
170+
newPassword = null;
171+
newPasswordRepeat = null;
172+
currentPassword = "";
173+
currentPasswordValid = false;
174+
passwordChangeSuccess = false;
175+
}}>{i18n.tr.settings.closeWindow}</Button
176+
>
177+
</Modal>
178+
</div>

frontend/src/lib/translations.ts

+19
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,25 @@ export const translationIds = {
197197
loadingMessage: "Daten werden geladen",
198198
settingsLabel: "Einstellungen",
199199
},
200+
settings: {
201+
settings: "Einstellungen",
202+
changePassword: "Passwort ändern",
203+
enterPassword: "Bitte aktuelles Passwort eingeben",
204+
getUserError: "kein aktiver Benutzer",
205+
oldPasswordWrong: "Das angegbene Passwort ist falsch",
206+
newPassword: "Bitte neues Passwort",
207+
newPasswordConfirm: "Bitte neues Passwort bestätigen",
208+
confirmChange: "Änderungen bestätigen",
209+
confirmPasswordChangeSuccess: "Änderung des Passworts erfolgreich",
210+
emptyPasswordError: "Das Passwort darf nicht leer sein",
211+
nonMatchingPasswordsError: "Passwörter stimmen nicht überein",
212+
samePasswordsError: "Das neue Passwort darf nicht dem alten entsprechen",
213+
closeWindow: "Fenster schließen",
214+
sendError: "Beim Senden der Daten ist ein Fehler aufgetreten",
215+
defaultAlertMessage: "Ein Fehler ist aufgetreten",
216+
alertTitle: "Fehler",
217+
placeholder: "Bitte ausfüllen",
218+
},
200219
childData: {
201220
newChildHeading: "Neu",
202221
newChildHeadingLong: "Neues Kind registrieren",

frontend/vite.config.ts

+3
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,8 @@ export default defineConfig({
1212
host: "localhost",
1313
port: 5173,
1414
strictPort: true,
15+
proxy: {
16+
"/api": "http://localhost:8000",
17+
},
1518
},
1619
});

0 commit comments

Comments
 (0)