diff --git a/frontend/src/routes/auth/about/[id]/+page.server.js b/frontend/src/routes/auth/about/[id]/+page.server.js index dbad482..0371d7c 100644 --- a/frontend/src/routes/auth/about/[id]/+page.server.js +++ b/frontend/src/routes/auth/about/[id]/+page.server.js @@ -1,6 +1,7 @@ import { BASE_API_URI } from "$lib/utils/constants"; import { formatError } from "$lib/utils/helpers"; import { fail, redirect } from "@sveltejs/kit"; +import { toRFC3339 } from "$lib/utils/utils"; /** @type {import('./$types').PageServerLoad} */ export async function load({ locals, params }) { @@ -21,19 +22,50 @@ export const actions = { * @returns Error data or redirects user to the home page or the previous page */ updateUser: async ({ request, fetch, cookies, locals }) => { - const formData = await request.formData(); - /** @type {Record} */ - const updateData = {}; + let formData = await request.formData(); - // Convert FormData to a plain object - formData.forEach((value, key) => { - if (typeof value === "string" && value !== "") { - updateData[key] = value; - } - }); + /** @type {Partial} */ + const updateData = { + id: Number(formData.get("id")), + first_name: String(formData.get("first_name")), + last_name: String(formData.get("last_name")), + email: String(formData.get("email")), + phone: String(formData.get("phone")), + notes: String(formData.get("notes")), + address: String(formData.get("address")), + zip_code: String(formData.get("zip_code")), + city: String(formData.get("city")), + date_of_birth: toRFC3339(formData.get("birth_date")), + company: String(formData.get("company")), + profile_picture: String(formData.get("profile_picture")), + membership: { + id: Number(formData.get("membership_id")), + start_date: toRFC3339(formData.get("membership_start_date")), + end_date: toRFC3339(formData.get("membership_end_date")), + status: Number(formData.get("membership_status")), + parent_member_id: Number(formData.get("parent_member_id")), + subscription_model: { + id: Number(formData.get("subscription_model_id")), + name: String(formData.get("subscription_model_name")), + }, + }, + bank_account: { + id: Number(formData.get("bank_account_id")), + mandate_date_signed: String(formData.get("mandate_date_signed")), + bank: String(formData.get("bank")), + account_holder_name: String(formData.get("account_holder_name")), + iban: String(formData.get("iban")), + bic: String(formData.get("bic")), + mandate_reference: String(formData.get("mandate_reference")), + }, + }; + // Remove undefined or null properties + const cleanUpdateData = Object.fromEntries( + Object.entries(updateData).filter(([_, v]) => v != null) + ); + console.dir(cleanUpdateData); const apiURL = `${BASE_API_URI}/backend/users/update/`; - const res = await fetch(apiURL, { method: "PATCH", credentials: "include", @@ -41,7 +73,7 @@ export const actions = { "Content-Type": "application/json", Cookie: `jwt=${cookies.get("jwt")}`, }, - body: JSON.stringify(updateData), + body: JSON.stringify(cleanUpdateData), }); if (!res.ok) { @@ -51,11 +83,11 @@ export const actions = { } const response = await res.json(); - locals.user = response; + // Format dates if (locals.user.date_of_birth) { - locals.user.date_of_birth = response["date_of_birth"].split("T")[0]; + locals.user.date_of_birth = response.date_of_birth.split("T")[0]; } if (locals.user.membership?.start_date) { locals.user.membership.start_date = @@ -65,6 +97,7 @@ export const actions = { locals.user.membership.end_date = locals.user.membership.end_date.split("T")[0]; } + throw redirect(303, `/auth/about/${response.id}`); }, /** @@ -102,6 +135,7 @@ export const actions = { profile_picture: response[""], }; }, + /** * * @param request - The request object diff --git a/frontend/src/routes/auth/about/[id]/+page.svelte b/frontend/src/routes/auth/about/[id]/+page.svelte index 45ede1a..f86b1d8 100644 --- a/frontend/src/routes/auth/about/[id]/+page.svelte +++ b/frontend/src/routes/auth/about/[id]/+page.svelte @@ -11,7 +11,14 @@ import { t } from "svelte-i18n"; import { fly } from "svelte/transition"; - $: ({ user } = $page.data); + /** @type {import('./$types').ActionData} */ + export let form; + + /** @type {App.Locals['subscriptions']}*/ + $: subscriptions = $page.data.subscriptions; + + /** @type {App.Locals['user']}*/ + $: user = $page.data.user; /** @typedef {{name: string, src: string}} Avatar */ const avatarFiles = import.meta.glob("$lib/img/Avatar-*.jpeg", { @@ -20,11 +27,38 @@ /** @type{Avatar[]} */ let avatars = []; - const TABS = ["profile", "membership", "bankaccount"]; + const TABS = ["profile", "licence", "membership", "bankaccount"]; let activeTab = TABS[0]; - /** @type{string[]} */ - let errorMessages = []; + $: subscriptionModelOptions = subscriptions.map((sub) => ({ + value: sub?.name ?? "", + label: sub?.name ?? "", + })); + + const userStatusOptions = [ + { value: 1, label: $t("userStatus.1"), color: "#b1b1b1" }, // Grey for "Nicht verifiziert" + { value: 2, label: $t("userStatus.2"), color: "#90EE90" }, // Light green for "Verifiziert" + { value: 3, label: $t("userStatus.3"), color: "#00bc00" }, // Green for "Aktiv" + { value: 4, label: $t("userStatus.4"), color: "#FFC0CB" }, // Pink for "Passiv" + { value: 5, label: $t("userStatus.5"), color: "#FF4646" }, // Red for "Deaktiviert" + ]; + + const userRoleOptions = [ + { value: 0, label: $t("userRole.0"), color: "#b1b1b1" }, // Grey for "Mitglied" + { value: 1, label: $t("userRole.1"), color: "#00bc00" }, // Green for "Betrachter" + { value: 4, label: $t("userRole.4"), color: "#FFC0CB" }, // Pink for "Bearbeiter" + { value: 8, label: $t("userRole.8"), color: "#FF4646" }, // Red for "Admin" + ]; + const membershipStatusOptions = [ + { value: 3, label: $t("userStatus.3"), color: "#00bc00" }, // Green for "Aktiv" + { value: 4, label: $t("userStatus.4"), color: "#FFC0CB" }, // Pink for "Passiv" + { value: 5, label: $t("userStatus.5"), color: "#FF4646" }, // Red for "Deaktiviert" + ]; + const licenceStatusOptions = [ + { value: 3, label: $t("userStatus.3"), color: "#00bc00" }, // Green for "Aktiv" + { value: 4, label: $t("userStatus.4"), color: "#FFC0CB" }, // Pink for "Passiv" + { value: 5, label: $t("userStatus.5"), color: "#FF4646" }, // Red for "Deaktiviert" + ]; let showModal = false, isUploading = false, @@ -37,7 +71,13 @@ const close = () => (showModal = false); const toggleAvatars = () => (showAvatars = !showAvatars); + $: selectedSubscriptionModel = + subscriptions.find( + (sub) => sub?.id === user.membership?.subscription_model.id + ) || null; + onMount(() => { + console.dir(user); avatars = Object.entries(avatarFiles).map(([path, module]) => { if (typeof path !== "string") { throw new Error("Unexpected non-string path"); @@ -60,9 +100,6 @@ }); }); - /** @type {import('./$types').ActionData} */ - export let form; - /** * Sets the active tab * @param {string} tab - The tab to set as active @@ -73,28 +110,11 @@ /** @type {import('./$types').SubmitFunction} */ const handleUpdate = async ({ form, formData, action, cancel }) => { - errorMessages = []; - const errorElements = form.querySelectorAll(".error-message"); - - errorElements.forEach((element) => { - if (element.textContent) { - errorMessages.push(element.textContent); - } - }); - - if (errorMessages.length > 0) { - cancel(); - return; - } - - errorMessages = []; isUpdating = true; return async ({ result }) => { isUpdating = false; if (result.type === "success" || result.type === "redirect") { close(); - } else if (result.type == "failure" && result.data?.errors) { - errorMessages = result.data.errors.map((error) => error.error); } await applyAction(result); }; @@ -164,10 +184,10 @@ {user.phone} {/if} - {#if user.birth_date} + {#if user.date_of_birth}

Geburtstag: - {user.birth_date} + {user.date_of_birth}

{/if} {#if user.notes} @@ -256,6 +276,7 @@ method="POST" use:enhance={handleUpdate} > +

{$t("user_edit")}

{#if form?.success}

{/each} - {#if activeTab == "profile"} -
+
+ + {#if user.role_id === 8} - - - - - - - - - -
- {:else if activeTab == "membership"} -
- - - - -
- {:else if activeTab == "bankaccount"} -
- - - - - -
- {/if} - {#if errorMessages.length > 0} -
- {#each errorMessages as message, i (i)} -

- {message} + {/if} + + + + + + + + + + + + +

+
+ +
+
+ + +
+
+

+ {$t("monthly_fee")}: + {selectedSubscriptionModel?.monthly_fee || "-"}

- {/each} +

+ {$t("hourly_rate")}: + {selectedSubscriptionModel?.hourly_rate || "-"} +

+ {#if selectedSubscriptionModel?.included_hours_per_year} +

+ {$t("included_hours_per_year")}: + {selectedSubscriptionModel?.included_hours_per_year} +

+ {/if} + {#if selectedSubscriptionModel?.included_hours_per_month} +

+ {$t("included_hours_per_month")}: + {selectedSubscriptionModel?.included_hours_per_month} +

+ {/if} +
+
+

+ {$t("details")}: + {selectedSubscriptionModel?.details || "-"} +

+ {#if selectedSubscriptionModel?.conditions} +

+ {$t("conditions")}: + {selectedSubscriptionModel?.conditions} +

+ {/if} +
- {/if} + + + +
+
+ + + + + +
{#if isUpdating} @@ -457,18 +566,26 @@ {/if}