styling, DateOfBirth corrected

This commit is contained in:
Alex
2025-01-31 19:27:15 +01:00
parent c2d5188765
commit 67ef3a2fca
14 changed files with 716 additions and 779 deletions

View File

@@ -283,7 +283,6 @@
.input {
width: 100%;
margin: 0.5rem 0;
}
input,
textarea,
@@ -316,7 +315,6 @@
}
/* Add consistent spacing between input boxes */
.input-box {
margin: 1rem 0;
padding: 0.5rem;
background-color: var(--surface0);
border-radius: 6px;

View File

@@ -28,28 +28,6 @@
<div class="modal-background">
<div transition:modal|global={{ duration: 1000 }} class="modal" role="dialog" aria-modal="true">
<!-- svelte-ignore a11y-missing-attribute -->
<a
title={$t('cancel')}
class="modal-close"
on:click={closeModal}
role="button"
tabindex="0"
on:keydown={(e) => e.key == 'Enter' && closeModal()}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 384 512"
aria-hidden="true"
>
<path
d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"
/>
</svg>
<span class="sr-only">{$t('cancel')}</span>
</a>
<div class="container">
<slot />
</div>
@@ -64,7 +42,7 @@
top: 0;
right: 0;
bottom: 0;
background: rgba(30, 30, 46, 0.65); /* var(--base) with 0.75 opacity */
background: var(--modal-backdrop); /* var(--base) with 0.75 opacity */
backdrop-filter: blur(4px); /* Optional: adds a slight blur effect */
z-index: 9999;
display: flex;
@@ -149,7 +127,6 @@
.modal .container {
flex-direction: column;
left: 0;
width: 100%;
}
}
</style>

View File

@@ -23,7 +23,7 @@
zip_code: '',
city: '',
company: '',
date_of_birth: '',
dateofbirth: '',
notes: '',
profile_picture: '',
payment_status: 0,
@@ -297,11 +297,11 @@
placeholder={$t('placeholder.phone')}
/>
<InputField
name="user[date_of_birth]"
name="user[dateofbirth]"
type="date"
label={$t('date_of_birth')}
bind:value={localUser.date_of_birth}
placeholder={$t('placeholder.date_of_birth')}
label={$t('dateofbirth')}
bind:value={localUser.dateofbirth}
placeholder={$t('placeholder.dateofbirth')}
/>
<InputField
name="user[address]"
@@ -529,7 +529,7 @@
.category-break {
grid-column: 1 / -1;
height: 1px;
background-color: var(--surface0);
background-color: var(--overlay0);
margin-top: 10px;
margin-left: 20%;
width: 60%;

View File

@@ -25,6 +25,7 @@
--base: #1e1e2e;
--mantle: #181825;
--crust: #11111b;
--modal-backdrop: rgba(49, 50, 68, 0.45); /* For Mocha theme */
}
@font-face {
@@ -385,8 +386,6 @@ li strong {
display: flex;
align-items: center;
justify-content: space-between;
margin: 10px 0;
padding: 10px;
width: 100%;
height: auto;
box-sizing: border-box;

View File

@@ -1,179 +1,176 @@
export default {
userStatus: {
1: "Nicht verifiziert",
2: "Verifiziert",
3: "Aktiv",
4: "Passiv",
5: "Deaktiviert",
},
userRole: {
0: "Mitglied",
1: "Betrachter",
4: "Bearbeiter",
8: "Administrator",
},
placeholder: {
password: "Passwort eingeben...",
email: "Emailadresse eingeben...",
company: "Firmennamen eingeben...",
first_name: "Vornamen eingeben...",
last_name: "Nachnamen eingeben...",
phone: "Telefonnummer eingeben...",
address: "Straße und Hausnummer eingeben...",
zip_code: "Postleitzahl eingeben...",
city: "Wohnort eingeben...",
bank_name: "Namen der Bank eingeben...",
parent_member_id: "Mitgliedsnr des Hauptmitglieds eingeben...",
bank_account_holder: "Namen eingeben...",
iban: "IBAN eingeben..",
bic: "BIC eingeben(Bei nicht deutschen Konten)...",
mandate_reference: "SEPA Mandatsreferenz eingeben..",
notes: "Deine Notizen zu {name}...",
licence_number: "Auf dem Führerschein unter Feld 5",
issued_date: "Ausgabedatum unter Feld 4a",
expiration_date: "Ablaufdatum unter Feld 4b",
issuing_country: "Ausstellendes Land",
},
validation: {
required: "Eingabe benötigt",
password: "Password zu kurz, mindestens 8 Zeichen",
password_match: "Passwörter stimmen nicht überein!",
phone: "Ungültiges Format(+491738762387 oder 0173850698)",
zip_code: "Ungültige Postleitzahl(Nur deutsche Wohnorte sind zulässig)",
bic: "Ungültige BIC",
iban: "Ungültige IBAN",
date: "Bitte geben Sie ein Datum ein",
email: "Ungültige Emailadresse",
licence: "Nummer zu kurz(11 Zeichen)",
},
server: {
error: {
invalid_json: "JSON Daten sind ungültig",
no_auth_token: "Nicht authorisiert, fehlender oder ungültiger Auth-Token",
jwt_parsing_error:
"Nicht authorisiert, Auth-Token konnte nicht gelesen werden",
unauthorized: "Sie sind nicht befugt diese Handlung durchzuführen",
internal_server_error:
"Verdammt, Fehler auf unserer Seite, probieren Sie es nochmal, danach rufen Sie jemanden vom Verein an.",
},
validation: {
invalid_user_id: "Nutzer ID ungültig",
invalid_subscription_model: "Model nicht gefunden",
user_not_found: "{field} konnte nicht gefunden werden",
invalid_user_data: "Nutzerdaten ungültig",
user_not_found_or_wrong_password:
"Existiert nicht oder falsches Passwort",
email_already_registered:
"Ein Mitglied wurde schon mit dieser Emailadresse erstellt.",
alphanumunicode: "beinhaltet nicht erlaubte Zeichen",
safe_content: "I see what you did there! Do not cross this line!",
iban: "Ungültig. Format: DE07123412341234123412",
bic: "Ungültig. Format: BELADEBEXXX",
email: "Format ungültig",
number: "Ist keine Nummer",
euDriversLicence: "Ist kein europäischer Führerschein",
lte: "Ist zu groß/neu",
gt: "Ist zu klein/alt",
required: "Feld wird benötigt",
image: "Dies ist kein Bild",
alphanum: "beinhaltet ungültige Zeichen",
alphaunicode: "darf nur aus Buchstaben bestehen",
},
},
licenceCategory: {
AM: "Mopeds und leichte vierrädrige Kraftfahrzeuge (50ccm, max 45km/h)",
A1: "Leichte Motorräder (125ccm)",
A2: "Motorräder mit mittlerer Leistung (max 35kW)",
A: "Motorräder",
B: "Kraftfahrzeuge ≤ 3500 kg, ≤ 8 Sitzplätze",
C1: "Mittelschwere Fahrzeuge -7500 kg",
C: "Schwere Nutzfahrzeuge > 3500 kg",
D1: "Kleinbusse 9-16 Sitzplätze",
D: "Busse > 8 Sitzplätze",
BE: "Fahrzeugklasse B mit Anhänger",
C1E: "Fahrzeugklasse C1 mit Anhänger",
CE: "Fahrzeugklasse C mit Anhänger",
D1E: "Fahrzeugklasse D1 mit Anhänger",
DE: "Fahrzeugklasse D mit Anhänger",
L: "Land-, Forstwirtschaftsfahrzeuge, Stapler max 40km/h",
T: "Land-, Forstwirtschaftsfahrzeuge, Stapler max 60km/h",
},
users: "Mitglieder",
user: {
login: "Nutzer Anmeldung",
edit: "Nutzer bearbeiten",
user: "Nutzer",
management: "Mitgliederverwaltung",
id: "Mitgliedsnr",
name: "Name",
email: "Email",
status: "Status",
role: "Nutzerrolle",
},
cancel: "Abbrechen",
confirm: "Bestätigen",
actions: "Aktionen",
edit: "Bearbeiten",
delete: "Löschen",
mandate_date_signed: "Mandatserteilungsdatum",
licence_categories: "Führerscheinklassen",
subscription_model: "Mitgliedschatfsmodell",
licence: "Führerschein",
licence_number: "Führerscheinnummer",
issued_date: "Ausgabedatum",
expiration_date: "Ablaufdatum",
country: "Land",
monthly_fee: "Monatliche Gebühr",
hourly_rate: "Stundensatz",
details: "Details",
conditions: "Bedingungen",
unknown: "Unbekannt",
notes: "Notizen",
address: "Straße & Hausnummer",
city: "Wohnort",
zip_code: "PLZ",
forgot_password: "Passwort vergessen?",
password: "Passwort",
password_repeat: "Passwort wiederholen",
email: "Email",
company: "Firma",
login: "Anmeldung",
profile: "Profil",
membership: "Mitgliedschaft",
bankaccount: "Kontodaten",
first_name: "Vorname",
last_name: "Nachname",
name: "Name",
phone: "Telefonnummer",
date_of_birth: "Geburtstag",
status: "Status",
start: "Beginn",
end: "Ende",
parent_member_id: "Hauptmitgliedsnr.",
bank_account_holder: "Kontoinhaber",
bank_name: "Bank",
iban: "IBAN",
bic: "BIC",
mandate_reference: "SEPA Mandat",
subscriptions: "Tarifmodelle",
payments: "Zahlungen",
add_new: "Neu",
included_hours_per_year: "Inkludierte Stunden pro Jahr",
included_hours_per_month: "Inkludierte Stunden pro Monat",
userStatus: {
1: 'Nicht verifiziert',
2: 'Verifiziert',
3: 'Aktiv',
4: 'Passiv',
5: 'Deaktiviert'
},
userRole: {
0: 'Mitglied',
1: 'Betrachter',
4: 'Bearbeiter',
8: 'Administrator'
},
placeholder: {
password: 'Passwort eingeben...',
email: 'Emailadresse eingeben...',
company: 'Firmennamen eingeben...',
first_name: 'Vornamen eingeben...',
last_name: 'Nachnamen eingeben...',
phone: 'Telefonnummer eingeben...',
address: 'Straße und Hausnummer eingeben...',
zip_code: 'Postleitzahl eingeben...',
city: 'Wohnort eingeben...',
bank_name: 'Namen der Bank eingeben...',
parent_member_id: 'Mitgliedsnr des Hauptmitglieds eingeben...',
bank_account_holder: 'Namen eingeben...',
iban: 'IBAN eingeben..',
bic: 'BIC eingeben(Bei nicht deutschen Konten)...',
mandate_reference: 'SEPA Mandatsreferenz eingeben..',
notes: 'Deine Notizen zu {name}...',
licence_number: 'Auf dem Führerschein unter Feld 5',
issued_date: 'Ausgabedatum unter Feld 4a',
expiration_date: 'Ablaufdatum unter Feld 4b',
issuing_country: 'Ausstellendes Land'
},
validation: {
required: 'Eingabe benötigt',
password: 'Password zu kurz, mindestens 8 Zeichen',
password_match: 'Passwörter stimmen nicht überein!',
phone: 'Ungültiges Format(+491738762387 oder 0173850698)',
zip_code: 'Ungültige Postleitzahl(Nur deutsche Wohnorte sind zulässig)',
bic: 'Ungültige BIC',
iban: 'Ungültige IBAN',
date: 'Bitte geben Sie ein Datum ein',
email: 'Ungültige Emailadresse',
licence: 'Nummer zu kurz(11 Zeichen)'
},
server: {
error: {
invalid_json: 'JSON Daten sind ungültig',
no_auth_token: 'Nicht authorisiert, fehlender oder ungültiger Auth-Token',
jwt_parsing_error: 'Nicht authorisiert, Auth-Token konnte nicht gelesen werden',
unauthorized: 'Sie sind nicht befugt diese Handlung durchzuführen',
internal_server_error:
'Verdammt, Fehler auf unserer Seite, probieren Sie es nochmal, danach rufen Sie jemanden vom Verein an.'
},
validation: {
invalid_user_id: 'Nutzer ID ungültig',
invalid_subscription_model: 'Model nicht gefunden',
user_not_found: '{field} konnte nicht gefunden werden',
invalid_user_data: 'Nutzerdaten ungültig',
user_not_found_or_wrong_password: 'Existiert nicht oder falsches Passwort',
email_already_registered: 'Ein Mitglied wurde schon mit dieser Emailadresse erstellt.',
alphanumunicode: 'beinhaltet nicht erlaubte Zeichen',
safe_content: 'I see what you did there! Do not cross this line!',
iban: 'Ungültig. Format: DE07123412341234123412',
bic: 'Ungültig. Format: BELADEBEXXX',
email: 'Format ungültig',
number: 'Ist keine Nummer',
euDriversLicence: 'Ist kein europäischer Führerschein',
lte: 'Ist zu groß/neu',
gt: 'Ist zu klein/alt',
required: 'Feld wird benötigt',
image: 'Dies ist kein Bild',
alphanum: 'beinhaltet ungültige Zeichen',
alphaunicode: 'darf nur aus Buchstaben bestehen'
}
},
licenceCategory: {
AM: 'Mopeds und leichte vierrädrige Kraftfahrzeuge (50ccm, max 45km/h)',
A1: 'Leichte Motorräder (125ccm)',
A2: 'Motorräder mit mittlerer Leistung (max 35kW)',
A: 'Motorräder',
B: 'Kraftfahrzeuge ≤ 3500 kg, ≤ 8 Sitzplätze',
C1: 'Mittelschwere Fahrzeuge -7500 kg',
C: 'Schwere Nutzfahrzeuge > 3500 kg',
D1: 'Kleinbusse 9-16 Sitzplätze',
D: 'Busse > 8 Sitzplätze',
BE: 'Fahrzeugklasse B mit Anhänger',
C1E: 'Fahrzeugklasse C1 mit Anhänger',
CE: 'Fahrzeugklasse C mit Anhänger',
D1E: 'Fahrzeugklasse D1 mit Anhänger',
DE: 'Fahrzeugklasse D mit Anhänger',
L: 'Land-, Forstwirtschaftsfahrzeuge, Stapler max 40km/h',
T: 'Land-, Forstwirtschaftsfahrzeuge, Stapler max 60km/h'
},
users: 'Mitglieder',
user: {
login: 'Nutzer Anmeldung',
edit: 'Nutzer bearbeiten',
user: 'Nutzer',
management: 'Mitgliederverwaltung',
id: 'Mitgliedsnr',
name: 'Name',
email: 'Email',
status: 'Status',
role: 'Nutzerrolle'
},
cancel: 'Abbrechen',
confirm: 'Bestätigen',
actions: 'Aktionen',
edit: 'Bearbeiten',
delete: 'Löschen',
mandate_date_signed: 'Mandatserteilungsdatum',
licence_categories: 'Führerscheinklassen',
subscription_model: 'Mitgliedschatfsmodell',
licence: 'Führerschein',
licence_number: 'Führerscheinnummer',
issued_date: 'Ausgabedatum',
expiration_date: 'Ablaufdatum',
country: 'Land',
monthly_fee: 'Monatliche Gebühr',
hourly_rate: 'Stundensatz',
details: 'Details',
conditions: 'Bedingungen',
unknown: 'Unbekannt',
notes: 'Notizen',
address: 'Straße & Hausnummer',
city: 'Wohnort',
zip_code: 'PLZ',
forgot_password: 'Passwort vergessen?',
password: 'Passwort',
password_repeat: 'Passwort wiederholen',
email: 'Email',
company: 'Firma',
login: 'Anmeldung',
profile: 'Profil',
membership: 'Mitgliedschaft',
bankaccount: 'Kontodaten',
first_name: 'Vorname',
last_name: 'Nachname',
name: 'Name',
phone: 'Telefonnummer',
dateofbirth: 'Geburtstag',
status: 'Status',
start: 'Beginn',
end: 'Ende',
parent_member_id: 'Hauptmitgliedsnr.',
bank_account_holder: 'Kontoinhaber',
bank_name: 'Bank',
iban: 'IBAN',
bic: 'BIC',
mandate_reference: 'SEPA Mandat',
subscriptions: 'Tarifmodelle',
payments: 'Zahlungen',
add_new: 'Neu',
included_hours_per_year: 'Inkludierte Stunden pro Jahr',
included_hours_per_month: 'Inkludierte Stunden pro Monat',
// For payments section
payment: {
id: "Zahlungs-Nr",
amount: "Betrag",
date: "Datum",
status: "Status",
},
// For payments section
payment: {
id: 'Zahlungs-Nr',
amount: 'Betrag',
date: 'Datum',
status: 'Status'
},
// For subscription statuses
subscriptionStatus: {
pending: "Ausstehend",
completed: "Abgeschlossen",
failed: "Fehlgeschlagen",
cancelled: "Storniert",
},
// For subscription statuses
subscriptionStatus: {
pending: 'Ausstehend',
completed: 'Abgeschlossen',
failed: 'Fehlgeschlagen',
cancelled: 'Storniert'
}
};

View File

@@ -1,24 +1,24 @@
// @ts-nocheck
import { quintOut } from "svelte/easing";
import { crossfade } from "svelte/transition";
import { quintOut } from 'svelte/easing';
import { crossfade } from 'svelte/transition';
export const [send, receive] = crossfade({
duration: (d) => Math.sqrt(d * 200),
duration: (d) => Math.sqrt(d * 200),
// eslint-disable-next-line no-unused-vars
fallback(node, params) {
const style = getComputedStyle(node);
const transform = style.transform === "none" ? "" : style.transform;
// eslint-disable-next-line no-unused-vars
fallback(node, params) {
const style = getComputedStyle(node);
const transform = style.transform === 'none' ? '' : style.transform;
return {
duration: 600,
easing: quintOut,
css: (t) => `
return {
duration: 600,
easing: quintOut,
css: (t) => `
transform: ${transform} scale(${t});
opacity: ${t}
`,
};
},
`
};
}
});
/**
@@ -27,9 +27,9 @@ export const [send, receive] = crossfade({
* @param {string} email - The email to validate
*/
export const isValidEmail = (email) => {
const EMAIL_REGEX =
/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
return EMAIL_REGEX.test(email.trim());
const EMAIL_REGEX =
/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
return EMAIL_REGEX.test(email.trim());
};
/**
* Validates a strong password field
@@ -37,11 +37,9 @@ export const isValidEmail = (email) => {
* @param {string} password - The password to validate
*/
export const isValidPasswordStrong = (password) => {
const strongRegex = new RegExp(
"^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})"
);
const strongRegex = new RegExp('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})');
return strongRegex.test(password.trim());
return strongRegex.test(password.trim());
};
/**
* Validates a medium password field
@@ -49,11 +47,11 @@ export const isValidPasswordStrong = (password) => {
* @param {string} password - The password to validate
*/
export const isValidPasswordMedium = (password) => {
const mediumRegex = new RegExp(
"^(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})"
);
const mediumRegex = new RegExp(
'^(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})'
);
return mediumRegex.test(password.trim());
return mediumRegex.test(password.trim());
};
/**
@@ -63,22 +61,22 @@ export const isValidPasswordMedium = (password) => {
*/
export function isEmpty(obj) {
for (const _i in obj) {
return false;
}
return true;
for (const _i in obj) {
return false;
}
return true;
}
export function toRFC3339(dateString) {
if (!dateString) dateString = "0001-01-01T00:00:00.000Z";
const date = new Date(dateString);
return date.toISOString();
if (!dateString) dateString = '0001-01-01T00:00:00.000Z';
const date = new Date(dateString);
return date.toISOString();
}
export function fromRFC3339(dateString) {
if (!dateString) dateString = "0001-01-01T00:00:00.000Z";
const date = new Date(dateString);
return date.toISOString().split("T")[0];
if (!dateString) dateString = '0001-01-01T00:00:00.000Z';
const date = new Date(dateString);
return date.toISOString().split('T')[0];
}
/**
@@ -86,28 +84,26 @@ export function fromRFC3339(dateString) {
* @param {App.Locals.User} user - The user object to format
*/
export function userDatesFromRFC3339(user) {
if (user.date_of_birth) {
user.date_of_birth = fromRFC3339(user.date_of_birth);
}
if (user.membership) {
if (user.membership.start_date) {
user.membership.start_date = fromRFC3339(user.membership.start_date);
}
if (user.membership.end_date) {
user.membership.end_date = fromRFC3339(user.membership.end_date);
}
}
if (user.licence?.issued_date) {
user.licence.issued_date = fromRFC3339(user.licence.issued_date);
}
if (user.licence?.expiration_date) {
user.licence.expiration_date = fromRFC3339(user.licence.expiration_date);
}
if (user.bank_account && user.bank_account.mandate_date_signed) {
user.bank_account.mandate_date_signed = fromRFC3339(
user.bank_account.mandate_date_signed
);
}
if (user.dateofbirth) {
user.dateofbirth = fromRFC3339(user.dateofbirth);
}
if (user.membership) {
if (user.membership.start_date) {
user.membership.start_date = fromRFC3339(user.membership.start_date);
}
if (user.membership.end_date) {
user.membership.end_date = fromRFC3339(user.membership.end_date);
}
}
if (user.licence?.issued_date) {
user.licence.issued_date = fromRFC3339(user.licence.issued_date);
}
if (user.licence?.expiration_date) {
user.licence.expiration_date = fromRFC3339(user.licence.expiration_date);
}
if (user.bank_account && user.bank_account.mandate_date_signed) {
user.bank_account.mandate_date_signed = fromRFC3339(user.bank_account.mandate_date_signed);
}
}
/**
@@ -115,28 +111,26 @@ export function userDatesFromRFC3339(user) {
* @param {App.Locals.User} user - The user object to format
*/
export function userDatesToRFC3339(user) {
if (user.date_of_birth) {
user.date_of_birth = toRFC3339(user.date_of_birth);
}
if (user.membership) {
if (user.membership.start_date) {
user.membership.start_date = toRFC3339(user.membership.start_date);
}
if (user.membership.end_date) {
user.membership.end_date = toRFC3339(user.membership.end_date);
}
}
if (user.licence?.issued_date) {
user.licence.issued_date = toRFC3339(user.licence.issued_date);
}
if (user.licence?.expiration_date) {
user.licence.expiration_date = toRFC3339(user.licence.expiration_date);
}
if (user.bank_account && user.bank_account.mandate_date_signed) {
user.bank_account.mandate_date_signed = toRFC3339(
user.bank_account.mandate_date_signed
);
}
if (user.dateofbirth) {
user.dateofbirth = toRFC3339(user.dateofbirth);
}
if (user.membership) {
if (user.membership.start_date) {
user.membership.start_date = toRFC3339(user.membership.start_date);
}
if (user.membership.end_date) {
user.membership.end_date = toRFC3339(user.membership.end_date);
}
}
if (user.licence?.issued_date) {
user.licence.issued_date = toRFC3339(user.licence.issued_date);
}
if (user.licence?.expiration_date) {
user.licence.expiration_date = toRFC3339(user.licence.expiration_date);
}
if (user.bank_account && user.bank_account.mandate_date_signed) {
user.bank_account.mandate_date_signed = toRFC3339(user.bank_account.mandate_date_signed);
}
}
/**
@@ -145,33 +139,33 @@ export function userDatesToRFC3339(user) {
* @returns {array} The formatted error object
*/
export function formatError(obj) {
const errors = [];
if (typeof obj === "object" && obj !== null) {
if (Array.isArray(obj)) {
obj.forEach((error) => {
errors.push({
field: error.field,
key: error.key,
id: Math.random() * 1000,
});
});
} else {
Object.keys(obj).forEach((field) => {
errors.push({
field: field,
key: obj[field].key,
id: Math.random() * 1000,
});
});
}
} else {
errors.push({
field: "general",
key: obj,
id: 0,
});
}
return errors;
const errors = [];
if (typeof obj === 'object' && obj !== null) {
if (Array.isArray(obj)) {
obj.forEach((error) => {
errors.push({
field: error.field,
key: error.key,
id: Math.random() * 1000
});
});
} else {
Object.keys(obj).forEach((field) => {
errors.push({
field: field,
key: obj[field].key,
id: Math.random() * 1000
});
});
}
} else {
errors.push({
field: 'general',
key: obj,
id: 0
});
}
return errors;
}
/**
@@ -180,26 +174,26 @@ export function formatError(obj) {
* @param {import('RequestEvent<Partial<Record<string, string>>, string | null>')} event - The event object
*/
export function refreshCookie(newToken, event) {
if (newToken) {
const match = newToken.match(/jwt=([^;]+)/);
if (match) {
if (event) {
event.cookies.set("jwt", match[1], {
path: "/",
httpOnly: true,
secure: process.env.NODE_ENV === "production", // Secure in production
sameSite: "lax",
maxAge: 5 * 24 * 60 * 60, // 5 days in seconds
});
} else {
cookies.set("jwt", match[1], {
path: "/",
httpOnly: true,
secure: process.env.NODE_ENV === "production", // Secure in production
sameSite: "lax",
maxAge: 5 * 24 * 60 * 60, // 5 days in seconds
});
}
}
}
if (newToken) {
const match = newToken.match(/jwt=([^;]+)/);
if (match) {
if (event) {
event.cookies.set('jwt', match[1], {
path: '/',
httpOnly: true,
secure: process.env.NODE_ENV === 'production', // Secure in production
sameSite: 'lax',
maxAge: 5 * 24 * 60 * 60 // 5 days in seconds
});
} else {
cookies.set('jwt', match[1], {
path: '/',
httpOnly: true,
secure: process.env.NODE_ENV === 'production', // Secure in production
sameSite: 'lax',
maxAge: 5 * 24 * 60 * 60 // 5 days in seconds
});
}
}
}
}

View File

@@ -0,0 +1,121 @@
import { toRFC3339 } from './helpers';
/**
* Converts FormData to a nested object structure
* @param {FormData} formData - The FormData object to convert
* @returns {{ user: Partial<App.Locals['user']> }} Nested object representation of the form data
*/
export function formDataToObject(formData) {
/** @type { Partial<App.Locals['user']> } */
const object = {};
console.log('Form data entries:');
for (const [key, value] of formData.entries()) {
console.log('Key:', key, 'Value:', value);
}
for (const [key, value] of formData.entries()) {
/** @type {string[]} */
const keys = key.match(/\[([^\]]+)\]/g)?.map((k) => k.slice(1, -1)) || [key];
console.log('Processed keys:', keys);
/** @type {Record<string, any>} */
let current = object;
console.log('Current object state:', JSON.stringify(current));
for (let i = 0; i < keys.length - 1; i++) {
/**
* Create nested object if it doesn't exist
* @type {Record<string, any>}
* @description Ensures proper nesting structure for user data fields
* @example
* // For input name="user[membership][status]"
* // Creates: { user: { membership: { status: value } } }
*/
current[keys[i]] = current[keys[i]] || {};
/**
* Move to the next level of the object
* @type {Record<string, any>}
*/
current = current[keys[i]];
}
const lastKey = keys[keys.length - 1];
if (lastKey.endsWith('[]')) {
/**
* Handle array fields (licence categories)
*/
const arrayKey = lastKey.slice(0, -2);
current[arrayKey] = current[arrayKey] || [];
current[arrayKey].push(value);
} else {
current[lastKey] = value;
}
}
return { user: object };
}
/**
* Processes the raw form data into the expected user data structure
* @param {{ user: Partial<App.Locals['user']> } } rawData - The raw form data object
* @returns {{ user: Partial<App.Locals['user']> }} Processed user data
*/
export function processFormData(rawData) {
/** @type {{ user: Partial<App.Locals['user']> }} */
const 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 || ''),
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,
subscription_model: {
id: Number(rawData.user.membership?.subscription_model?.id) || 0,
name: String(rawData.user.membership?.subscription_model?.name) || ''
}
},
licence: {
id: Number(rawData.user.licence?.id) || 0,
status: Number(rawData.user.licence?.status),
licence_number: String(rawData.user.licence?.licence_number || ''),
issued_date: toRFC3339(rawData.user.licence?.issued_date),
expiration_date: toRFC3339(rawData.user.licence?.expiration_date),
country: String(rawData.user.licence?.country || ''),
licence_categories: rawData.user.licence?.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)
}
}
};
// Remove undefined or null properties
const cleanUpdateData = JSON.parse(JSON.stringify(processedData), (key, value) =>
value !== null && value !== '' ? value : undefined
);
console.dir(cleanUpdateData);
return cleanUpdateData;
}