aggiunto reddito acessorio

This commit is contained in:
fabio
2026-02-19 18:54:22 +01:00
parent 7f3543fe4c
commit 29b4f99d9f
8 changed files with 172 additions and 1 deletions

View File

@@ -69,6 +69,7 @@ const currentComponent = computed(() => {
if (id === 'children') return defineAsyncComponent(() => import('./steps/ChildrenStep.vue'))
if (id === 'income') return defineAsyncComponent(() => import('./steps/IncomeStep.vue'))
if (id === 'professionalExpenses') return defineAsyncComponent(() => import('./steps/ProfessionalExpensesStep.vue'))
if (id === 'sideIncome') return defineAsyncComponent(() => import('./steps/SideIncomeStep.vue'))
return null
})

View File

@@ -0,0 +1,83 @@
<template>
<q-card flat class="full-width q-pa-none">
<q-card-section class="full-width">
<div class="row items-center">
<div class="col">
<div class="text-h6">{{ t('SID') }}</div>
</div>
<div class="col-auto">
<q-btn flat :label="t('button.prev')" @click="emitPrev" class="q-mr-sm" />
<q-btn color="primary" :label="t('button.next')" @click="saveAndNext" />
</div>
</div>
<q-separator class="q-my-sm" />
<q-form ref="formRef" class="q-gutter-md q-mt-md">
<q-toggle class="q-mb-md" v-model="form.hasSideIncome"
:label="t('sideIncome.hasSideIncome')"
/>
<CommentAttachment
class="q-mt-none"
v-if="form.hasSideIncome"
v-model="form.sideIncomeDocuments"
:label="t('sideIncome.attachments')"
:id="'documents'"
/>
</q-form>
</q-card-section>
</q-card>
</template>
<script setup lang="ts">
import { onMounted, ref, nextTick, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import type { StepDescriptor } from '../../types/types'
import { useSideIncomeStore, type SideIncomeData } from '../../stores/sideIncome'
import CommentAttachment from '../CommentAttachment.vue'
const props = defineProps<{ step?: StepDescriptor }>()
const emit = defineEmits(['next', 'prev'])
const { t } = useI18n()
const store = useSideIncomeStore()
const form = store.data as SideIncomeData
const formRef = ref<{ validate?: () => Promise<boolean> | boolean; resetValidation?: () => void } | null>(null)
onMounted(async () => {
await nextTick()
formRef.value?.resetValidation?.()
})
watch(
() => form,
() => {
store.persist()
},
{ deep: true }
)
async function saveAndNext() {
try {
const ok = await (formRef.value?.validate?.() ?? true)
if (ok === false) return
} catch {
return
}
store.setSideIncome(form)
emit('next', props.step?.next)
}
function emitPrev() {
store.setSideIncome(form)
emit('prev', props.step?.prev)
}
</script>
<style scoped>
.full-width { width: 100%; }
</style>

View File

@@ -1,2 +1,2 @@
// Auto-generated by scripts/generate-commit-info.mjs
export const COMMIT_CODE = "62da803" as const
export const COMMIT_CODE = "7f3543f" as const

View File

@@ -96,6 +96,11 @@ export default {
noAttachments: 'Dokumente anhängen'
},
sideIncome: {
hasSideIncome: 'Haben Sie ein Nebeneinkommen?',
attachments: 'Dokumente anhängen'
},
informazionesualimenti: 'Informationen zu Unterhalt',
inserireindirizzocogniuge: 'Adresse des Ehepartners eingeben',
inserireindirizzopartner: 'Adresse des Partners eingeben',

View File

@@ -112,6 +112,11 @@ export default {
hasCanteenOrVouchers: 'Do you have a canteen or meal vouchers?'
},
sideIncome: {
hasSideIncome: 'Do you have supplementary income?',
attachments: 'Attach documents'
},
informazionesualimenti: 'Alimony information',
inserireindirizzocogniuge: 'Enter spouse address',
inserireindirizzopartner: 'Enter partner address',

View File

@@ -96,6 +96,11 @@ export default {
noAttachments: 'Joindre des documents'
},
sideIncome: {
hasSideIncome: 'Avez-vous un revenu accessoire ?',
attachments: 'Joindre des documents'
},
informazionesualimenti: 'Informations sur la pension alimentaire',
inserireindirizzocogniuge: "Saisir l'adresse du conjoint",
inserireindirizzopartner: "Saisir l'adresse du partenaire",

View File

@@ -112,6 +112,11 @@ export default {
hasCanteenOrVouchers: 'Hai mensa o buoni pasto?'
},
sideIncome: {
hasSideIncome: 'Hai un reddito accessorio?',
attachments: 'Allega i documenti'
},
informazionesualimenti: 'Informazioni su alimenti',
inserireindirizzocogniuge: "Inserire l'indirizzo del coniuge",
inserireindirizzopartner: "Inserire l'indirizzo del partner",

View File

@@ -0,0 +1,67 @@
import { defineStore } from 'pinia'
import { LocalStorage } from 'quasar'
export interface SideIncomeData {
hasSideIncome: boolean,
sideIncomeDocuments: {
comments: string,
attachments: []
}
}
const STORAGE_KEY = 'sideIncome:v1'
const DEFAULT: SideIncomeData = {
hasSideIncome: false,
sideIncomeDocuments: { comments: '', attachments: [] }
}
function isRecord(v: unknown): v is Record<string, unknown> {
return !!v && typeof v === 'object' && !Array.isArray(v)
}
export const useSideIncomeStore = defineStore('sideincomestore', {
state: () => {
try {
let saved: unknown = LocalStorage.getItem(STORAGE_KEY)
if (typeof saved === 'string') {
try {
saved = JSON.parse(saved)
} catch {
saved = null
}
}
if (isRecord(saved)) {
return { data: { ...DEFAULT, ...(saved as Partial<SideIncomeData>) } as SideIncomeData }
}
} catch {
// ignore and fall back to default
}
return { data: { ...DEFAULT } as SideIncomeData }
},
actions: {
persist() {
try {
LocalStorage.set(STORAGE_KEY, this.data)
} catch (err) {
console.error('sideIncome.store: persist error', err)
}
},
getSideIncome() {
return this.data
},
setSideIncome(partial: Partial<SideIncomeData>) {
this.data = { ...this.data, ...partial }
this.persist()
},
replaceSideIncome(payload: SideIncomeData) {
this.data = payload
this.persist()
},
resetSideIncome() {
this.data = { ...DEFAULT }
this.persist()
}
}
})