Merge remote-tracking branch 'origin/master'

This commit is contained in:
Jeppe Bundgaard
2026-03-16 13:07:51 +01:00
9 changed files with 175 additions and 134 deletions
+28 -1
View File
@@ -98,4 +98,31 @@ textarea.has-sharp-edges {
/*}*/
/*button.is-link {*/
/* background-color: #1584BC;*/
/*}*/
/*}*/
.mt-30 {
margin-top: 30px !important;
}
.cell .card-content .field{
width: 100%;
}
.cell .card-content .field .label{
font-weight: 800;
}
@media screen and (max-width: 768px) {
.mb-8-mobile{
margin-bottom: 8px !important;
}
}
@media screen and (min-width: 769px) {
.ml-16-tablet {
margin-left: 16px !important;
}
.mt-30-tablet {
margin-top: 30px !important;
}
}
+8 -7
View File
@@ -3642,8 +3642,8 @@
"booking_email": "E-mail til bookinger",
"booking_email_desc": "Den e-mailadresse, der modtager booking bekræftelser og vaskecertifikater.",
"description": "Dine notifikationsindstillinger",
"edit_booking_email": "Rediger e-mail til booking bekræftelse",
"edit_sms_phone": "Rediger telefonnummer til SMS notifikationer",
"edit_booking_email": "Rediger",
"edit_sms_phone": "Rediger",
"email_notifications": "E-mail notifikationer",
"email_notifications_desc": "Modtag e-mails med bookingbekræftelser og vaskecertifikater.",
"email_subtitle": "E-mail",
@@ -3655,10 +3655,11 @@
"title": "Notifikationer"
},
"security": {
"change_password": "Skift adgangskode",
"password_label": "Adgangskode",
"change_password": "Rediger",
"description": "Dine sikkerhedsindstillinger",
"edit_email": "Rediger e-mail",
"edit_phone": "Rediger telefonnummer",
"edit_email": "Rediger",
"edit_phone": "Rediger",
"email_desc": "Vi bruger denne e-mail til at nulstille din adgangskode, fremsende vaskecertifikater og andre vigtige oplysninger.",
"logout": "Log ud",
"title": "Sikkerhed"
@@ -3853,7 +3854,7 @@
"passkeys": {
"title": "Passnøgler",
"description": "Brug passkey til at logge sikkert ind med biometri som Face ID, Touch ID eller din enheds PIN-kode.",
"add_passkey": "Tilføj passkey",
"add_passkey": "Tilføj",
"rename_passkey": "Omdøb passkey",
"delete_passkey": "Slet passkey",
"no_passkeys": "Du har ikke tilføjet nogen passkeys endnu. Tilføj en for at aktivere login uden adgangskode.",
@@ -3887,7 +3888,7 @@
"status_disabled": "To-faktor-godkendelse er deaktiveret",
"status_enabled_desc": "Din konto er beskyttet med et ekstra bekræftelsestrin.",
"status_disabled_desc": "Aktiver to-faktor-godkendelse for forbedret sikkerhed.",
"enable_button": "Aktiver to-faktor-godkendelse",
"enable_button": "Aktiver",
"disable_button": "Deaktiver to-faktor-godkendelse",
"setup_title": "Opsæt to-faktor-godkendelse",
"setup_step1": "Scan denne QR-kode med din godkendelsesapp (Google Authenticator, Authy, osv.):",
+1
View File
@@ -3653,6 +3653,7 @@
"title": "Benachrichtigungen"
},
"security": {
"password_label": "Passwort",
"change_password": "Passwort ?ndern",
"description": "Ihre Sicherheitseinstellungen",
"edit_email": "E-Mail bearbeiten",
+1
View File
@@ -3655,6 +3655,7 @@
"title": "Notifications"
},
"security": {
"password_label": "Password",
"change_password": "Change password",
"description": "Your security settings",
"edit_email": "Edit email",
+1
View File
@@ -3653,6 +3653,7 @@
"title": "Varsler"
},
"security": {
"password_label": "Passord",
"change_password": "Endre passord",
"description": "Sikkerhetsinnstillingene dine",
"edit_email": "Rediger e-post",
+1
View File
@@ -3653,6 +3653,7 @@
"title": "Aviseringar"
},
"security": {
"password_label": "Lösenord",
"change_password": "Change password",
"description": "Dina säkerhetsinställningar",
"edit_email": "Edit email",
@@ -543,7 +543,6 @@ const onClickSaveWashCertificateEmail = async () => {
<ConfigurationCategory
v-if="!SessionUser.isSubuser.value"
class="mt-2"
:module="SessionUser.functions.device.isMobile() ? `` : $t('user_dashboard.profile.title')"
:title="$t('user_dashboard.profile.invoicing.title')"
:description="$t('user_dashboard.profile.invoicing.description')"
icon="fas fa-user"
@@ -567,68 +566,65 @@ const onClickSaveWashCertificateEmail = async () => {
<ConfigurationCategory
v-if="!SessionUser.isSubuser.value"
class="mt-2"
:module="SessionUser.functions.device.isMobile() ? `` : $t('user_dashboard.profile.title')"
:title="$t('user_dashboard.profile.security.title')"
:description="$t('user_dashboard.profile.security.description')"
icon="fas fa-lock"
>
<!-- E-mail -->
<ConfigurationInput
:title="SessionUser.objects.global.language.email"
:description="$t('user_dashboard.profile.security.email_desc')"
v-bind:value="SessionUser.user.email"
:disabled="true"
/>
<button
class="button is-link is-small mt-2"
@click="onClickSaveEmail"
:disabled="isLoading"
>
<span>
<i class="fas fa-edit"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.security.edit_email') }}</span>
</span>
</button>
<!-- Telefonnummer -->
<ConfigurationInput
:title="SessionUser.objects.global.language.phone_number"
:description="SessionUser.objects.global.language.phone_number"
v-bind:value="SessionUser.user.phone.number"
:disabled="true"
/>
<div class="buttons">
<!-- Change phone number and country code -->
<div class="columns is-align-items-flex-start">
<ConfigurationInput
:title="SessionUser.objects.global.language.email"
v-bind:value="SessionUser.user.email"
:disabled="true"
/>
<button
class="button is-link is-small mt-2"
@click="onClickSavePhoneNumber"
class="button is-link ml-16-tablet mt-30-tablet mb-8-mobile"
@click="onClickSaveEmail"
:disabled="isLoading"
>
<span>
<i class="fas fa-edit"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.security.edit_phone') }}</span>
<span class="ml-2">{{ $t('user_dashboard.profile.security.edit_email') }}</span>
</span>
</button>
<!-- Change password -->
</div>
<!-- Telefonnummer -->
<div class="columns is-align-items-flex-start">
<ConfigurationInput
:title="SessionUser.objects.global.language.phone_number"
v-bind:value="SessionUser.user.phone.number"
:disabled="true"
/>
<div class="buttons">
<!-- Change phone number and country code -->
<button
class="button is-link ml-16-tablet mt-30-tablet mb-8-mobile"
@click="onClickSavePhoneNumber"
:disabled="isLoading"
>
<span>
<i class="fas fa-edit"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.security.edit_phone') }}</span>
</span>
</button>
</div>
</div>
<!-- Change password -->
<div class="columns is-align-items-flex-start">
<ConfigurationInput
:title="$t('user_dashboard.profile.security.password_label')"
value="************"
:disabled="true"
/>
<button
class="button is-link is-small mt-2"
class="button is-link ml-16-tablet mt-30-tablet mb-8-mobile"
@click="onClickChangePassword"
:disabled="isLoading"
>
<span>
<i class="fas fa-key"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.security.change_password') }}</span>
</span>
</button>
<!-- Sign out -->
<button
class="button is-danger is-small mt-2"
@click="SessionUser.functions.showConfirmLogoutDialog()"
:disabled="isLoading"
>
<span>
<i class="fas fa-sign-out-alt"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.security.logout') }}</span>
</span>
<span>
<i class="fas fa-key"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.security.change_password') }}</span>
</span>
</button>
</div>
<!-- Passkeys -->
@@ -793,30 +789,30 @@ const onClickSaveWashCertificateEmail = async () => {
<ConfigurationCategory
v-if="!SessionUser.isSubuser.value"
class="mt-2"
:module="SessionUser.functions.device.isMobile() ? `` : $t('user_dashboard.profile.title')"
:title="$t('user_dashboard.profile.notifications.title')"
:subtitle="$t('user_dashboard.profile.notifications.email_subtitle')"
:description="$t('user_dashboard.profile.notifications.description')"
icon="fas fa-bell"
>
<!-- Email to booking confirmation -->
<ConfigurationInput
:title="$t('user_dashboard.profile.notifications.booking_email')"
:description="$t('user_dashboard.profile.notifications.booking_email_desc')"
v-bind:value="SessionUser.user.notifications.wash_certificate_email"
:disabled="true"
/>
<!-- Change email to booking confirmation -->
<button
class="button is-link is-small mt-2"
@click="onClickSaveWashCertificateEmail"
:disabled="isLoading"
>
<span>
<i class="fas fa-edit"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.notifications.edit_booking_email') }}</span>
</span>
</button>
<div class="columns is-align-items-flex-start">
<ConfigurationInput
:title="$t('user_dashboard.profile.notifications.booking_email')"
:description="$t('user_dashboard.profile.notifications.booking_email_desc')"
v-bind:value="SessionUser.user.notifications.wash_certificate_email"
:disabled="true"
/>
<!-- Change email to booking confirmation -->
<button
class="button is-link ml-16-tablet mt-30-tablet mb-8-mobile"
@click="onClickSaveWashCertificateEmail"
:disabled="isLoading"
>
<span>
<i class="fas fa-edit"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.notifications.edit_booking_email') }}</span>
</span>
</button>
</div>
<hr class="my-4"/>
<!-- Enable/disable email notifications -->
<ConfigurationSwitch
@@ -825,35 +821,26 @@ const onClickSaveWashCertificateEmail = async () => {
v-bind:value="SessionUser.user.notifications.email_notifications_enabled.value"
:on-switch="(value) => SessionUser.user.notifications.setEmailNotificationsEnabled(value)"
/>
</ConfigurationCategory>
<!-- Notifications - SMS notifications -->
<ConfigurationCategory
v-if="!SessionUser.isSubuser.value"
class="mt-2"
:module="SessionUser.functions.device.isMobile() ? `` : $t('user_dashboard.profile.title')"
:title="$t('user_dashboard.profile.notifications.title')"
:subtitle="$t('user_dashboard.profile.notifications.sms_subtitle')"
:description="$t('user_dashboard.profile.notifications.description')"
icon="fas fa-sms"
>
<!-- Phone number for SMS notifications -->
<ConfigurationInput
:title="$t('user_dashboard.profile.notifications.sms_phone')"
:description="$t('user_dashboard.profile.notifications.sms_phone_desc')"
v-bind:value="SessionUser.user.phone.number"
:disabled="true"
/>
<!-- Change phone number for SMS notifications -->
<button
class="button is-link is-small mt-2"
@click="onClickSavePhoneNumber"
:disabled="isLoading"
>
<span>
<i class="fas fa-edit"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.notifications.edit_sms_phone') }}</span>
</span>
</button>
<div class="columns is-align-items-flex-start">
<ConfigurationInput
:title="$t('user_dashboard.profile.notifications.sms_phone')"
:description="$t('user_dashboard.profile.notifications.sms_phone_desc')"
v-bind:value="SessionUser.user.phone.number"
:disabled="true"
/>
<!-- Change phone number for SMS notifications -->
<button
class="button is-link ml-16-tablet mt-30-tablet mb-8-mobile"
@click="onClickSavePhoneNumber"
:disabled="isLoading"
>
<span>
<i class="fas fa-edit"></i>
<span class="ml-2">{{ $t('user_dashboard.profile.notifications.edit_sms_phone') }}</span>
</span>
</button>
</div>
<hr class="my-4"/>
<!-- Enable/disable SMS notifications -->
<ConfigurationSwitch
@@ -863,6 +850,7 @@ const onClickSaveWashCertificateEmail = async () => {
:on-switch="(value) => SessionUser.user.notifications.setSmsNotificationsEnabled(value)"
/>
</ConfigurationCategory>
<!-- Notifications - SMS notifications -->
<template v-if="false">
<!-- Microsoft -->
<ConfigurationCategory
@@ -371,32 +371,50 @@ const getTransportIcon = (transport) => {
</div>
</div>
</div>
<!-- Add passkey button -->
<button
class="button is-link ml-16-tablet mt-2"
@click="registerPasskey"
:disabled="isLoading"
>
<span>
<i class="fas fa-plus"></i>
<span class="ml-2">{{ $t('passkeys.add_passkey') }}</span>
</span>
</button>
</div>
<!-- Empty state -->
<div v-else class="notification is-info is-light">
<span class="icon">
<i class="fas fa-info-circle"></i>
</span>
<span>{{ $t('passkeys.no_passkeys') }}</span>
<div v-else class="notification is-info is-light columns is-vcentered">
<span class="content">{{ $t('passkeys.no_passkeys') }}</span>
<!-- Add passkey button -->
<button
class="button is-link ml-16-tablet mt-2"
@click="registerPasskey"
:disabled="isLoading"
>
<span>
<i class="fas fa-plus"></i>
<span class="ml-2">{{ $t('passkeys.add_passkey') }}</span>
</span>
</button>
</div>
<!-- Add passkey button -->
<button
class="button is-link is-small mt-2"
@click="registerPasskey"
:disabled="isLoading"
>
<span>
<i class="fas fa-plus"></i>
<span class="ml-2">{{ $t('passkeys.add_passkey') }}</span>
</span>
</button>
</template>
</div>
</template>
<style scoped>
.notification{
background-color: #f5f5f5;
}
.notification .content {
width: 100%;
}
.passkey-management {
margin-top: 1rem;
}
@@ -145,8 +145,8 @@ const onClickDisable2FA = async () => {
<template>
<div class="two-factor-management">
<!-- 2FA Status Display -->
<div class="status-display mb-4">
<div class="is-flex is-align-items-center">
<div class="status-display mb-4 columns is-vcentered">
<div class="is-flex is-align-items-center fullwidth">
<span class="icon is-medium" :class="is2FAEnabled ? 'has-text-success' : 'has-text-grey'">
<i class="fas fa-shield-alt fa-lg"></i>
</span>
@@ -159,6 +159,18 @@ const onClickDisable2FA = async () => {
</p>
</div>
</div>
<button
v-if="!is2FAEnabled"
class="button is-link ml-16-tablet"
@click="startSetup"
:disabled="isLoading"
:class="{ 'is-loading': isLoading }"
>
<span class="icon">
<i class="fas fa-shield-alt"></i>
</span>
<span>{{ $t('2fa.enable_button') }}</span>
</button>
</div>
<!-- Setup Flow -->
@@ -228,19 +240,6 @@ const onClickDisable2FA = async () => {
<!-- Action Buttons (when not in setup) -->
<div v-else class="buttons">
<button
v-if="!is2FAEnabled"
class="button is-link"
@click="startSetup"
:disabled="isLoading"
:class="{ 'is-loading': isLoading }"
>
<span class="icon">
<i class="fas fa-shield-alt"></i>
</span>
<span>{{ $t('2fa.enable_button') }}</span>
</button>
<button
v-if="is2FAEnabled"
class="button is-danger is-outlined"
@@ -263,11 +262,15 @@ const onClickDisable2FA = async () => {
}
.status-display {
padding: 1rem;
padding: 1.375em 1.5em;
background: #f5f5f5;
border-radius: 8px;
}
.fullwidth {
width: 100%;
}
.setup-flow {
background: #fafafa;
border: 1px solid #e0e0e0;