feat: add user profile settings page and fix navigation link
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user