From a640703f2da8815dc26ad1600a6f206be1624379 Mon Sep 17 00:00:00 2001
From: ivarlovlie <git@ivarlovlie.no>
Date: Wed, 1 Jun 2022 22:10:32 +0200
Subject: feat: Initial after clean slate

---
 .../src/app/pages/views/profile-modal.svelte       | 156 +++++++++++++++++++++
 1 file changed, 156 insertions(+)
 create mode 100644 apps/projects-web/src/app/pages/views/profile-modal.svelte

(limited to 'apps/projects-web/src/app/pages/views/profile-modal.svelte')

diff --git a/apps/projects-web/src/app/pages/views/profile-modal.svelte b/apps/projects-web/src/app/pages/views/profile-modal.svelte
new file mode 100644
index 0000000..839b59d
--- /dev/null
+++ b/apps/projects-web/src/app/pages/views/profile-modal.svelte
@@ -0,0 +1,156 @@
+<script>
+	import {update_profile} from "$shared/lib/api/user";
+	import Modal from "$shared/components/modal.svelte";
+	import Alert from "$shared/components/alert.svelte";
+	import Button from "$shared/components/button.svelte";
+	import {is_email} from "$shared/lib/helpers";
+	import {api_base} from "$shared/lib/configuration";
+	import {delete_user} from "$app/lib/services/user-service";
+	import {get_session_data} from "$shared/lib/session";
+
+	const archiveLink = api_base("_/api/account/archive");
+
+	let modal;
+	let understands = false;
+
+	let formIsLoading = false;
+	let formError;
+
+	let username = get_session_data()?.profile.username;
+	let usernameFieldMessage;
+	let usernameFieldMessageClass = "color-error";
+
+	let password;
+	let passwordFieldMessage;
+	let passwordFieldMessageClass = "color-error";
+
+	async function submit_form(e) {
+		e.preventDefault();
+		if (!username && !password) {
+			console.error("Not submitting becuase both values is empty");
+			return;
+		}
+
+		usernameFieldMessage = "";
+		passwordFieldMessage = "";
+
+		if (username && !is_email(username)) {
+			usernameFieldMessage = "Username has to be a valid email";
+			return;
+		}
+
+		if (password && password?.length < 6) {
+			passwordFieldMessage = "The new password must contain at least 6 characters";
+			return;
+		}
+
+		formIsLoading = true;
+
+		const response = await update_profile({
+			username,
+			password,
+		});
+
+		formIsLoading = false;
+
+		if (response.ok) {
+			if (password) {
+				passwordFieldMessage = "Successfully updated";
+				passwordFieldMessageClass = "color-success";
+				password = "";
+			}
+			if (username) {
+				usernameFieldMessage = "Successfully updated";
+				usernameFieldMessageClass = "color-success";
+				password = "";
+			}
+		} else {
+			formError = response.data.title ?? "An unknown error occured";
+		}
+	}
+
+	async function handle_delete_account_button_click() {
+		if (understands && confirm("Are you absolutely sure that you want to delete your account?")) {
+			await delete_user();
+		}
+	}
+
+	export const functions = {
+		open() {
+			modal.open();
+		},
+		close() {
+			// modal.close();
+		},
+	};
+</script>
+
+<Modal title="Profile"
+       bind:functions={modal}>
+    <section class="margin-bottom-md">
+        <p class="text-md margin-bottom-sm">Update your information</p>
+        <form on:submit={submit_form}
+              autocomplete="new-password">
+            {#if formError}
+                <small class="color-danger">{formError}</small>
+            {/if}
+            <div class="margin-bottom-sm">
+                <label for="email"
+                       class="form-label margin-bottom-xxs">New username</label>
+                <input type="email"
+                       class="form-control width-100%"
+                       id="email"
+                       placeholder={username}
+                       bind:value={username}/>
+                {#if usernameFieldMessage}
+                    <small class={usernameFieldMessageClass}>{usernameFieldMessage}</small>
+                {/if}
+            </div>
+            <div class="margin-bottom-sm">
+                <label for="password"
+                       class="form-label margin-bottom-xxs">New password</label>
+                <input type="password"
+                       class="form-control width-100%"
+                       id="password"
+                       bind:value={password}/>
+                {#if passwordFieldMessage}
+                    <small class={passwordFieldMessageClass}>{passwordFieldMessage}</small>
+                {/if}
+            </div>
+            <div class="flex justify-end">
+                <Button text="Save"
+                        on:click={submit_form}
+                        variant="primary"
+                        loading={formIsLoading}/>
+            </div>
+        </form>
+    </section>
+    <section class="margin-bottom-md">
+        <p class="text-md margin-bottom-sm">Download your data</p>
+        <a class="btn btn--subtle"
+           href={archiveLink}
+           download>Click here to download your data</a>
+    </section>
+    <section>
+        <p class="text-md margin-bottom-sm">Delete account</p>
+        <div class="margin-bottom-sm">
+            <Alert
+                    message="Deleting your account and data means that all of your data (entries, categories, etc.) will be unrecoverable forever.<br>You should probably download your data before continuing."
+                    type="info"
+            />
+        </div>
+        <div class="form-check margin-bottom-sm">
+            <input type="checkbox"
+                   class="checkbox"
+                   id="the-consequences"
+                   bind:checked={understands}/>
+            <label for="the-consequences">I understand the consequences of deleting my account and data.</label>
+        </div>
+        <div class="flex justify-end">
+            <Button text="Delete everything"
+                    variant="accent"
+                    disabled={!understands}
+                    on:click={handle_delete_account_button_click}/>
+        </div>
+    </section>
+</Modal>
-- 
cgit v1.3

