200 lines
6.0 KiB
Vue
200 lines
6.0 KiB
Vue
<script setup lang="ts">
|
|
definePageMeta({
|
|
middleware: 'auth'
|
|
})
|
|
|
|
useHead({ title: 'Modifica Profilo - Visione' })
|
|
|
|
const { user, updateProfile, syncUser } = useAuth()
|
|
const router = useRouter()
|
|
|
|
const formData = reactive({
|
|
first_name: user.value?.first_name || '',
|
|
last_name: user.value?.last_name || '',
|
|
phone: user.value?.phone || ''
|
|
})
|
|
|
|
const isLoading = ref(false)
|
|
const errorMessage = ref('')
|
|
const successMessage = ref('')
|
|
|
|
const canSubmit = computed(() => {
|
|
return formData.first_name.trim().length > 0 && formData.last_name.trim().length > 0
|
|
})
|
|
|
|
const handleSubmit = async () => {
|
|
if (!canSubmit.value) return
|
|
|
|
isLoading.value = true
|
|
errorMessage.value = ''
|
|
successMessage.value = ''
|
|
|
|
try {
|
|
const res = await updateProfile({
|
|
first_name: formData.first_name,
|
|
last_name: formData.last_name,
|
|
phone: formData.phone || undefined
|
|
})
|
|
|
|
if (res.ok || res.user) {
|
|
await syncUser()
|
|
successMessage.value = 'Profilo aggiornato con successo.'
|
|
setTimeout(() => {
|
|
router.push('/profile')
|
|
}, 1500)
|
|
}
|
|
} catch (error: any) {
|
|
errorMessage.value = error.data?.message || 'Errore durante l\'aggiornamento del profilo.'
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="py-5">
|
|
<div class="container">
|
|
<div class="row justify-content-center">
|
|
<div class="col-12 col-lg-8 col-xl-6">
|
|
<div class="card card-bg border-0 shadow-sm">
|
|
<div class="card-body p-4 p-lg-5">
|
|
<div class="d-flex align-items-center mb-3">
|
|
<NuxtLink to="/profile" class="btn btn-sm btn-link text-decoration-none ps-0 me-3">
|
|
<BIIcon name="it-arrow-left" size="sm" />
|
|
</NuxtLink>
|
|
<h1 class="h3 mb-0">Modifica Profilo</h1>
|
|
</div>
|
|
<p class="text-muted mb-4">
|
|
Aggiorna i tuoi dati personali. Email e Codice Fiscale non sono modificabili.
|
|
</p>
|
|
|
|
<form @submit.prevent="handleSubmit" class="d-grid gap-4">
|
|
<div class="input-field">
|
|
<label for="first_name" class="form-label">Nome</label>
|
|
<div class="input-field-control">
|
|
<BIIcon name="it-user" size="sm" class="input-field-icon" />
|
|
<input
|
|
id="first_name"
|
|
v-model="formData.first_name"
|
|
type="text"
|
|
class="form-control"
|
|
required
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="last_name" class="form-label">Cognome</label>
|
|
<div class="input-field-control">
|
|
<BIIcon name="it-user" size="sm" class="input-field-icon" />
|
|
<input
|
|
id="last_name"
|
|
v-model="formData.last_name"
|
|
type="text"
|
|
class="form-control"
|
|
required
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-field">
|
|
<label for="phone" class="form-label">Telefono (opzionale)</label>
|
|
<div class="input-field-control">
|
|
<BIIcon name="it-telephone" size="sm" class="input-field-icon" />
|
|
<input
|
|
id="phone"
|
|
v-model="formData.phone"
|
|
type="tel"
|
|
class="form-control"
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-field opacity-50">
|
|
<label class="form-label">Email</label>
|
|
<div class="input-field-control">
|
|
<BIIcon name="it-mail" size="sm" class="input-field-icon" />
|
|
<input
|
|
type="email"
|
|
class="form-control disabled"
|
|
:value="user?.email"
|
|
disabled
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-field opacity-50">
|
|
<label class="form-label">Codice Fiscale</label>
|
|
<div class="input-field-control">
|
|
<BIIcon name="it-card" size="sm" class="input-field-icon" />
|
|
<input
|
|
type="text"
|
|
class="form-control disabled"
|
|
:value="user?.fiscal_code"
|
|
disabled
|
|
>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="errorMessage" class="alert alert-danger mb-0" role="alert">
|
|
{{ errorMessage }}
|
|
</div>
|
|
|
|
<div v-if="successMessage" class="alert alert-success mb-0" role="alert">
|
|
{{ successMessage }}
|
|
</div>
|
|
|
|
<button
|
|
type="submit"
|
|
class="btn btn-primary w-100 py-2 mt-2"
|
|
:disabled="!canSubmit || isLoading"
|
|
>
|
|
<span v-if="isLoading" class="spinner-border spinner-border-sm me-2"></span>
|
|
{{ isLoading ? 'Aggiornamento in corso...' : 'Salva modifiche' }}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.input-field {
|
|
display: grid;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
.input-field-control {
|
|
align-items: center;
|
|
background: #fff;
|
|
border: 1px solid #c5d0db;
|
|
border-radius: 8px;
|
|
display: grid;
|
|
gap: 0.5rem;
|
|
grid-template-columns: auto minmax(0, 1fr);
|
|
padding-left: 0.875rem;
|
|
}
|
|
|
|
.input-field-control:focus-within {
|
|
border-color: #06c;
|
|
box-shadow: 0 0 0 2px rgba(0, 102, 204, 0.16);
|
|
}
|
|
|
|
.input-field-icon {
|
|
color: #5c6f82;
|
|
}
|
|
|
|
.input-field-control .form-control {
|
|
background: transparent;
|
|
border: 0;
|
|
border-radius: 0;
|
|
box-shadow: none;
|
|
min-width: 0;
|
|
padding-left: 0;
|
|
padding-right: 0;
|
|
}
|
|
</style>
|