koel/resources/assets/js/components/profile-preferences/ProfileForm.vue

174 lines
4.4 KiB
Vue
Raw Normal View History

2022-04-15 14:24:30 +00:00
<template>
2022-04-21 22:51:48 +00:00
<form data-testid="update-profile-form" @submit.prevent="update">
2024-03-30 16:49:25 +00:00
<AlertBox v-if="currentUser.sso_provider">
<template v-if="currentUser.sso_provider === 'Reverse Proxy'">
Youre authenticated by a reverse proxy.
</template>
<template v-else>
Youre logging in via Single Sign On provided by <strong>{{ currentUser.sso_provider }}</strong>.
</template>
2024-03-30 16:49:25 +00:00
You can still update your name and avatar here.
</AlertBox>
2024-03-19 22:48:12 +00:00
<div class="profile form-row">
<div class="left">
2024-03-30 16:49:25 +00:00
<div v-if="!currentUser.sso_provider" class="form-row">
2024-03-19 22:48:12 +00:00
<label>
Current Password
<input
v-model="profile.current_password"
v-koel-focus
name="current_password"
placeholder="Required to update your profile"
required
type="password"
data-testid="currentPassword"
>
</label>
</div>
<div class="form-row">
<label>
Name
2024-03-30 16:49:25 +00:00
<input id="inputProfileName" v-model="profile.name" data-testid="name" name="name" required type="text">
2024-03-19 22:48:12 +00:00
</label>
</div>
<div class="form-row">
<label>
Email Address
<input
2024-03-30 16:49:25 +00:00
id="inputProfileEmail"
v-model="profile.email"
:readonly="currentUser.sso_provider"
2024-03-19 22:48:12 +00:00
data-testid="email"
2024-03-30 16:49:25 +00:00
name="email"
required
type="email"
2024-03-19 22:48:12 +00:00
>
</label>
</div>
2024-03-30 16:49:25 +00:00
<div v-if="!currentUser.sso_provider" class="form-row">
2024-03-19 22:48:12 +00:00
<label>
New Password
<PasswordField
v-model="profile.new_password"
autocomplete="new-password"
data-testid="newPassword"
minlength="10"
placeholder="Leave empty to keep current password"
/>
<span class="password-rules help">
Min. 10 characters. Should be a mix of characters, numbers, and symbols.
</span>
</label>
</div>
</div>
<EditableProfileAvatar :profile="profile" />
2022-04-15 14:24:30 +00:00
</div>
<div class="form-row">
2022-04-21 22:51:48 +00:00
<Btn class="btn-submit" type="submit">Save</Btn>
<span v-if="isDemo" class="demo-notice">
2022-04-15 14:24:30 +00:00
Changes will not be saved in the demo version.
</span>
</div>
</form>
</template>
2022-04-15 17:00:08 +00:00
<script lang="ts" setup>
import { onMounted, ref } from 'vue'
2024-01-18 11:13:05 +00:00
import { authService, UpdateCurrentProfileData } from '@/services'
import { logger, parseValidationError } from '@/utils'
2024-03-30 16:49:25 +00:00
import { useDialogBox, useMessageToaster, useAuthorization } from '@/composables'
2022-04-15 14:24:30 +00:00
import Btn from '@/components/ui/Btn.vue'
2023-08-20 22:35:58 +00:00
import PasswordField from '@/components/ui/PasswordField.vue'
2024-03-19 22:48:12 +00:00
import EditableProfileAvatar from '@/components/profile-preferences/EditableProfileAvatar.vue'
2024-03-30 16:49:25 +00:00
import AlertBox from '@/components/ui/AlertBox.vue'
2022-04-15 14:24:30 +00:00
const { toastSuccess } = useMessageToaster()
const { showErrorDialog } = useDialogBox()
2024-03-19 22:48:12 +00:00
const profile = ref<UpdateCurrentProfileData>({} as UpdateCurrentProfileData)
2022-04-15 14:24:30 +00:00
const isDemo = window.IS_DEMO
2024-03-30 16:49:25 +00:00
const { currentUser } = useAuthorization()
2022-04-15 17:00:08 +00:00
onMounted(() => {
profile.value = {
2024-03-30 16:49:25 +00:00
name: currentUser.value.name,
email: currentUser.value.email,
avatar: currentUser.value.avatar,
2022-04-15 17:00:08 +00:00
current_password: null
2022-04-15 14:24:30 +00:00
}
})
2022-04-15 17:00:08 +00:00
const update = async () => {
if (!profile.value) {
throw Error()
}
if (isDemo) {
toastSuccess('Profile updated.')
2022-04-29 20:15:10 +00:00
return
}
2022-04-15 17:00:08 +00:00
try {
2024-01-18 11:13:05 +00:00
await authService.updateProfile(Object.assign({}, profile.value))
2022-04-15 17:00:08 +00:00
profile.value.current_password = null
delete profile.value.new_password
toastSuccess('Profile updated.')
} catch (error: any) {
const msg = error.response.status === 422 ? parseValidationError(error.response.data)[0] : 'Unknown error.'
2024-03-19 22:48:12 +00:00
await showErrorDialog(msg, 'Error')
logger.log(error)
2022-04-15 17:00:08 +00:00
}
}
2022-04-15 14:24:30 +00:00
</script>
<style lang="scss" scoped>
2023-08-20 22:35:58 +00:00
form {
2024-03-19 22:48:12 +00:00
width: 66%;
2023-08-20 22:35:58 +00:00
2024-03-30 16:49:25 +00:00
@media (max-width: 1024px) {
width: 100%;
}
2023-08-20 22:35:58 +00:00
input {
width: 100%;
2022-04-15 14:24:30 +00:00
}
2024-03-19 22:48:12 +00:00
.profile {
display: flex;
align-items: flex-start;
gap: 2.5rem;
2024-03-30 16:49:25 +00:00
@media (max-width: 1024px) {
flex-direction: column;
}
2024-03-19 22:48:12 +00:00
.left {
width: 50%;
2024-03-30 16:49:25 +00:00
@media (max-width: 1024px) {
width: 100%;
}
2024-03-19 22:48:12 +00:00
}
}
2022-04-15 14:24:30 +00:00
}
.password-rules {
2022-07-22 16:15:30 +00:00
display: block;
2022-04-15 14:24:30 +00:00
margin-top: .75rem;
}
2022-04-29 20:15:10 +00:00
.demo-notice {
font-size: .95rem;
opacity: .7;
margin-left: 5px;
}
2022-04-15 14:24:30 +00:00
</style>