sintonia_webapp/resources/js/components/content/UserProfile.vue
2025-07-18 14:10:37 +02:00

233 lines
No EOL
6.7 KiB
Vue

<script setup lang="ts">
import {useAuthStore} from '@/stores/auth.store.ts';
import {storeToRefs} from 'pinia';
import {onBeforeMount, ref, reactive} from 'vue';
import {useRouter} from "vue-router";
import axios from "axios";
const router = useRouter();
const authStore = useAuthStore();
const {userData} = storeToRefs(authStore);
const localUserData = reactive({...userData.value});
const emit = defineEmits([
'userProfilePage'
]);
let timezones = ref<string[]>([]);
let roleList = ref<string[]>([]);
const form = ref<HTMLFormElement | null>(null);
const passwordForm = ref<HTMLFormElement | null>(null);
const dialog = ref(false);
const passwordData = reactive({
oldPassword: '',
newPassword: '',
confirmPassword: '',
});
const formRules = {
'emailRules': [(v: string) => !v || /.+@.+\..+/.test(v) || 'E-mail must be a valid format'],
'cellphoneRules': [(v: string) => !v || /^[0-9-()]*$/.test(v) || 'Cellphone must be a valid number'],
'passwordConfirmationRule': [
(v: string) => !!v || 'Password confirmation is required',
(v: string) => v === passwordData.newPassword || 'Passwords do not match'
],
'requiredRule': [(v: string) => !!v || 'This field is required'],
}
const saveUser = async () => {
if (!form.value) return
const {valid} = await form.value.validate();
if (!valid) return
authStore.userData = {...localUserData};
await authStore.updateUser();
};
const goBack = () => {
router.go(-1);
}
const openPasswordDialog = () => {
dialog.value = true;
};
const closePasswordDialog = () => {
dialog.value = false;
passwordForm.value?.reset();
passwordForm.value?.resetValidation();
};
const resetPassword = async () => {
console.log('aaaa')
try {
await axios.put('/api/user/password', passwordData)
console.log('Password changed');
closePasswordDialog()
return
} catch (e) {
const errorMessage = e.response?.data?.error || 'An unexpected error occurred.';
console.error('Error changing password:' + errorMessage);
return
}
};
onBeforeMount(async () => {
await axios.get('/timezoneList').then(response => {
timezones.value = response?.data
})
if (userData.value.role === 'admin') {
await axios.get('/roleList').then(response => {
roleList.value = response?.data
})
}
})
</script>
<template>
<div>
<v-form ref="form">
<v-container>
<v-row>
<v-col cols="12" md="6">
<v-text-field
v-model="localUserData.login"
label="Login"
required
hint="Your public username."
persistent-hint
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="localUserData.email"
:rules="formRules.emailRules"
label="Email Address"
hint="Used for notifications and account recovery."
persistent-hint
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="localUserData.firstName"
label="First Name"
required
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="localUserData.lastName"
label="Last Name"
required
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-text-field
v-model="localUserData.cellPhone"
:rules="formRules.cellphoneRules"
label="Cell Phone"
></v-text-field>
</v-col>
<v-col cols="12" md="6">
<v-autocomplete
v-model="localUserData.timezone"
:items="timezones"
label="Timezone"
hint="Sets the time for all events and schedules."
persistent-hint
></v-autocomplete>
</v-col>
<v-col cols="12" md="6">
<v-select
v-model="localUserData.role"
:items="roleList"
label="Ruolo"
:disabled="userData.role !== 'admin'"
></v-select>
</v-col>
</v-row>
<v-row>
<v-col class="d-flex justify-end">
<v-btn color="secondary" @click="goBack" class="mr-4">
Back
</v-btn>
<v-btn color="primary" @click="saveUser">
Save Changes
</v-btn>
<v-btn color="error" @click="openPasswordDialog">
Reset Password
</v-btn>
</v-col>
</v-row>
</v-container>
</v-form>
<v-dialog v-model="dialog" persistent max-width="600px">
<v-card>
<v-card-title>
<span class="text-h5">Reset Your Password</span>
</v-card-title>
<v-card-text>
<p class="text-subtitle-1 mb-4">
Please be sure about the new password you are choosing. Password recovery via email is not implemented yet,
so
a forgotten password cannot be recovered.
</p>
</v-card-text>
<v-form ref="passwordForm" @submit.prevent="resetPassword">
<v-container>
<v-row>
<v-col cols="12">
<v-text-field
v-model="passwordData.oldPassword"
label="Old Password"
type="password"
:rules="formRules.requiredRule"
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
v-model="passwordData.newPassword"
label="New Password"
type="password"
:rules="formRules.requiredRule"
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
v-model="passwordData.confirmPassword"
label="Confirm New Password"
type="password"
:rules="formRules.passwordConfirmationRule"
required
></v-text-field>
</v-col>
</v-row>
</v-container>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue-darken-1" variant="text" @click="closePasswordDialog">
Cancel
</v-btn>
<v-btn type="submit" color="blue-darken-1" variant="tonal">
Confirm
</v-btn>
</v-card-actions>
</v-form>
</v-card>
</v-dialog>
</div>
</template>