From 2fdb484451f9db2cecccd18e9cb5bf056f1f2527 Mon Sep 17 00:00:00 2001 From: Alex <$(pass /github/email)> Date: Tue, 11 Feb 2025 19:17:30 +0100 Subject: [PATCH] frontend: added subscription processing --- frontend/src/lib/utils/processing.js | 136 ++++++++++-------- .../routes/auth/about/[id]/+page.server.js | 4 +- .../routes/auth/admin/users/+page.server.js | 51 ++++++- 3 files changed, 131 insertions(+), 60 deletions(-) diff --git a/frontend/src/lib/utils/processing.js b/frontend/src/lib/utils/processing.js index 451d4f5..61e231c 100644 --- a/frontend/src/lib/utils/processing.js +++ b/frontend/src/lib/utils/processing.js @@ -3,10 +3,10 @@ import { toRFC3339 } from './helpers'; /** * Converts FormData to a nested object structure * @param {FormData} formData - The FormData object to convert - * @returns {{ user: Partial,password2: string }} Nested object representation of the form data + * @returns {{ object: Partial | Partial, password2: string }} Nested object representation of the form data */ export function formDataToObject(formData) { - /** @type { Partial } */ + /** @type { Partial | Partial } */ const object = {}; let password2 = ''; @@ -56,89 +56,113 @@ export function formDataToObject(formData) { } } - return { user: object, password2: password2 }; + return { object: object, password2: password2 }; } /** * Processes the raw form data into the expected user data structure - * @param {{ user: Partial, password2: string} } rawData - The raw form data object + * @param {{ object: Partial, password2: string} } rawData - The raw form data object * @returns {{ user: Partial }} Processed user data */ -export function processFormData(rawData) { +export function processUserFormData(rawData) { /** @type {{ user: Partial }} */ let processedData = { user: { - id: Number(rawData.user.id) || 0, - status: Number(rawData.user.status), - role_id: Number(rawData.user.role_id), - first_name: String(rawData.user.first_name), - last_name: String(rawData.user.last_name), - email: String(rawData.user.email), - phone: String(rawData.user.phone || ''), - company: String(rawData.user.company || ''), - dateofbirth: toRFC3339(rawData.user.dateofbirth), - address: String(rawData.user.address || ''), - zip_code: String(rawData.user.zip_code || ''), - city: String(rawData.user.city || ''), - notes: String(rawData.user.notes || ''), - profile_picture: String(rawData.user.profile_picture || ''), + id: Number(rawData.object.id) || 0, + status: Number(rawData.object.status), + role_id: Number(rawData.object.role_id), + first_name: String(rawData.object.first_name), + last_name: String(rawData.object.last_name), + email: String(rawData.object.email), + phone: String(rawData.object.phone || ''), + company: String(rawData.object.company || ''), + dateofbirth: toRFC3339(rawData.object.dateofbirth), + address: String(rawData.object.address || ''), + zip_code: String(rawData.object.zip_code || ''), + city: String(rawData.object.city || ''), + notes: String(rawData.object.notes || ''), + profile_picture: String(rawData.object.profile_picture || ''), membership: { - id: Number(rawData.user.membership?.id) || 0, - status: Number(rawData.user.membership?.status), - start_date: toRFC3339(rawData.user.membership?.start_date), - end_date: toRFC3339(rawData.user.membership?.end_date), - parent_member_id: Number(rawData.user.membership?.parent_member_id) || 0, + id: Number(rawData.object.membership?.id) || 0, + status: Number(rawData.object.membership?.status), + start_date: toRFC3339(rawData.object.membership?.start_date), + end_date: toRFC3339(rawData.object.membership?.end_date), + parent_member_id: Number(rawData.object.membership?.parent_member_id) || 0, subscription_model: { - id: Number(rawData.user.membership?.subscription_model?.id) || 0, - name: String(rawData.user.membership?.subscription_model?.name) || '', - details: String(rawData.user.membership?.subscription_model?.details) || '', - conditions: String(rawData.user.membership?.subscription_model?.conditions) || '', - hourly_rate: Number(rawData.user.membership?.subscription_model?.hourly_rate) || 0, - monthly_fee: Number(rawData.user.membership?.subscription_model?.monthly_fee) || 0, + id: Number(rawData.object.membership?.subscription_model?.id) || 0, + name: String(rawData.object.membership?.subscription_model?.name) || '', + details: String(rawData.object.membership?.subscription_model?.details) || '', + conditions: String(rawData.object.membership?.subscription_model?.conditions) || '', + hourly_rate: Number(rawData.object.membership?.subscription_model?.hourly_rate) || 0, + monthly_fee: Number(rawData.object.membership?.subscription_model?.monthly_fee) || 0, included_hours_per_month: - Number(rawData.user.membership?.subscription_model?.included_hours_per_month) || 0, + Number(rawData.object.membership?.subscription_model?.included_hours_per_month) || 0, included_hours_per_year: - Number(rawData.user.membership?.subscription_model?.included_hours_per_year) || 0 + Number(rawData.object.membership?.subscription_model?.included_hours_per_year) || 0 } }, licence: { - id: Number(rawData.user.licence?.id) || 0, - status: Number(rawData.user.licence?.status), - number: String(rawData.user.licence?.number || ''), - issued_date: toRFC3339(rawData.user.licence?.issued_date), - expiration_date: toRFC3339(rawData.user.licence?.expiration_date), - country: String(rawData.user.licence?.country || ''), - categories: rawData.user.licence?.categories || [] + id: Number(rawData.object.licence?.id) || 0, + status: Number(rawData.object.licence?.status), + number: String(rawData.object.licence?.number || ''), + issued_date: toRFC3339(rawData.object.licence?.issued_date), + expiration_date: toRFC3339(rawData.object.licence?.expiration_date), + country: String(rawData.object.licence?.country || ''), + categories: rawData.object.licence?.categories || [] }, bank_account: { - id: Number(rawData.user.bank_account?.id) || 0, - account_holder_name: String(rawData.user.bank_account?.account_holder_name || ''), - bank: String(rawData.user.bank_account?.bank || ''), - iban: String(rawData.user.bank_account?.iban || ''), - bic: String(rawData.user.bank_account?.bic || ''), - mandate_reference: String(rawData.user.bank_account?.mandate_reference || ''), - mandate_date_signed: toRFC3339(rawData.user.bank_account?.mandate_date_signed) + id: Number(rawData.object.bank_account?.id) || 0, + account_holder_name: String(rawData.object.bank_account?.account_holder_name || ''), + bank: String(rawData.object.bank_account?.bank || ''), + iban: String(rawData.object.bank_account?.iban || ''), + bic: String(rawData.object.bank_account?.bic || ''), + mandate_reference: String(rawData.object.bank_account?.mandate_reference || ''), + mandate_date_signed: toRFC3339(rawData.object.bank_account?.mandate_date_signed) } } }; console.log('Categories: --------'); - console.dir(rawData.user.licence); + console.dir(rawData.object.licence); if ( - rawData.user.password && + rawData.object.password && rawData.password2 && - rawData.user.password === rawData.password2 && - rawData.user.password.trim() !== '' + rawData.object.password === rawData.password2 && + rawData.object.password.trim() !== '' ) { - processedData.user.password = rawData.user.password; + processedData.user.password = rawData.object.password; } - - // Remove undefined or null properties - const cleanUpdateData = JSON.parse(JSON.stringify(processedData), (key, value) => + const clean = JSON.parse(JSON.stringify(processedData), (key, value) => value !== null && value !== '' ? value : undefined ); - console.dir(cleanUpdateData); - return cleanUpdateData; + console.dir(clean); + return clean; +} + +/** + * Processes the raw form data into the expected user data structure + * @param {{ object: Partial} } rawData - The raw form data object + * @returns {{ subscription: Partial }} Processed user data + */ +export function processSubscriptionFormData(rawData) { + /** @type {{ subscription: Partial }} */ + let processedData = { + subscription: { + id: Number(rawData.object.id) || 0, + name: String(rawData.object.name) || '', + details: String(rawData.object.details) || '', + conditions: String(rawData.object.conditions) || '', + hourly_rate: Number(rawData.object.hourly_rate) || 0, + monthly_fee: Number(rawData.object.monthly_fee) || 0, + included_hours_per_month: Number(rawData.object.included_hours_per_month) || 0, + included_hours_per_year: Number(rawData.object.included_hours_per_year) || 0 + } + }; + const clean = JSON.parse(JSON.stringify(processedData), (key, value) => + value !== null && value !== '' ? value : undefined + ); + console.dir(clean); + return clean; } diff --git a/frontend/src/routes/auth/about/[id]/+page.server.js b/frontend/src/routes/auth/about/[id]/+page.server.js index f0d267a..162bd7e 100644 --- a/frontend/src/routes/auth/about/[id]/+page.server.js +++ b/frontend/src/routes/auth/about/[id]/+page.server.js @@ -1,7 +1,7 @@ import { BASE_API_URI } from '$lib/utils/constants'; import { formatError, userDatesFromRFC3339 } from '$lib/utils/helpers'; import { fail, redirect } from '@sveltejs/kit'; -import { formDataToObject, processFormData } from '$lib/utils/processing'; +import { formDataToObject, processUserFormData } from '$lib/utils/processing'; /** * @typedef {Object} UpdateData @@ -30,7 +30,7 @@ export const actions = { let formData = await request.formData(); const rawData = formDataToObject(formData); - const processedData = processFormData(rawData); + const processedData = processUserFormData(rawData); const isCreating = !processedData.user.id || processedData.user.id === 0; console.log('Is creating: ', isCreating); diff --git a/frontend/src/routes/auth/admin/users/+page.server.js b/frontend/src/routes/auth/admin/users/+page.server.js index 3e6553a..b88f39e 100644 --- a/frontend/src/routes/auth/admin/users/+page.server.js +++ b/frontend/src/routes/auth/admin/users/+page.server.js @@ -5,7 +5,11 @@ import { BASE_API_URI } from '$lib/utils/constants'; import { formatError, userDatesFromRFC3339 } from '$lib/utils/helpers'; import { fail, redirect } from '@sveltejs/kit'; -import { formDataToObject, processFormData } from '$lib/utils/processing'; +import { + formDataToObject, + processSubscriptionFormData, + processUserFormData +} from '$lib/utils/processing'; /** @type {import('./$types').PageServerLoad} */ export async function load({ locals }) { @@ -29,7 +33,7 @@ export const actions = { let formData = await request.formData(); const rawData = formDataToObject(formData); - const processedData = processFormData(rawData); + const processedData = processUserFormData(rawData); console.dir(processedData.user.membership); const isCreating = !processedData.user.id || processedData.user.id === 0; @@ -55,6 +59,49 @@ export const actions = { return fail(400, { errors: errors }); } + const response = await res.json(); + console.log('Server success response:', response); + locals.user = response; + userDatesFromRFC3339(locals.user); + throw redirect(303, `/auth/admin/users`); + }, + /** + * + * @param request - The request object + * @param fetch - Fetch object from sveltekit + * @param cookies - SvelteKit's cookie object + * @param locals - The local object, housing current user + * @returns Error data or redirects user to the home page or the previous page + */ + updateSubscription: async ({ request, fetch, cookies, locals }) => { + let formData = await request.formData(); + + const rawData = formDataToObject(formData); + const processedData = processSubscriptionFormData(rawData); + + const isCreating = !processedData.subscription.id || processedData.subscription.id === 0; + console.log('Is creating: ', isCreating); + const apiURL = `${BASE_API_URI}/backend/subscriptions/upsert`; + + /** @type {RequestInit} */ + const requestOptions = { + method: isCreating ? 'POST' : 'PATCH', + credentials: 'include', + headers: { + 'Content-Type': 'application/json', + Cookie: `jwt=${cookies.get('jwt')}` + }, + body: JSON.stringify(processedData) + }; + + const res = await fetch(apiURL, requestOptions); + + if (!res.ok) { + const response = await res.json(); + const errors = formatError(response.errors); + return fail(400, { errors: errors }); + } + const response = await res.json(); console.log('Server success response:', response); locals.user = response;