aggiunto lo store ProfessionalExpenses
This commit is contained in:
@@ -63,7 +63,6 @@
|
||||
v-if="form.eatsOut"
|
||||
v-model="form.hasCanteenOrVouchers"
|
||||
:label="t('professionalExpenses.hasCanteenOrVouchers')"
|
||||
:rules="[requiredWhenEatsOut]"
|
||||
class="q-mt-md"
|
||||
/>
|
||||
</div>
|
||||
@@ -78,9 +77,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, onMounted, ref, nextTick, watch, computed } from 'vue'
|
||||
import { onMounted, ref, nextTick, watch, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import type { StepDescriptor } from '../../types/types'
|
||||
import { useProfessionalExpensesStore, type ProfessionalExpensesData } from '../../stores/professionalExpenses'
|
||||
|
||||
type CommuteMethod = 'CAR' | 'BUS' | 'BIKE' | 'WALK'
|
||||
|
||||
@@ -94,6 +94,7 @@ type ProfessionalExpensesForm = {
|
||||
hasCanteenOrVouchers: boolean
|
||||
}
|
||||
|
||||
const store = useProfessionalExpensesStore()
|
||||
|
||||
const props = defineProps<{ step?: StepDescriptor }>()
|
||||
const emit = defineEmits(['next', 'prev'])
|
||||
@@ -120,15 +121,7 @@ const minLength = (n: number, msg?: string) => (v: unknown) => {
|
||||
|
||||
|
||||
|
||||
const form = reactive<ProfessionalExpensesForm>({
|
||||
expensesChanged: false,
|
||||
workplaceDescription: '',
|
||||
commuteMethod: null,
|
||||
commuteKm: null,
|
||||
lunchAtHome: false,
|
||||
eatsOut: false,
|
||||
hasCanteenOrVouchers: false
|
||||
})
|
||||
const form = store.data as ProfessionalExpensesForm
|
||||
|
||||
const commuteMethodOptions = computed<Array<{ label: string; value: CommuteMethod }>>(() => [
|
||||
{ label: t('professionalExpenses.commuteMethodOptions.car'), value: 'CAR' },
|
||||
@@ -137,11 +130,6 @@ const commuteMethodOptions = computed<Array<{ label: string; value: CommuteMetho
|
||||
{ label: t('professionalExpenses.commuteMethodOptions.walk'), value: 'WALK' }
|
||||
])
|
||||
|
||||
const requiredWhenEatsOut = (v: boolean | null) => {
|
||||
if (!form.eatsOut) return true
|
||||
return v !== null || t('validation.required')
|
||||
}
|
||||
|
||||
/* const professionalExpensesSchema = {
|
||||
fields: [
|
||||
{ key: "expensesChanged", type: "boolean", required: true },
|
||||
@@ -160,10 +148,13 @@ onMounted(async () => {
|
||||
formRef.value?.resetValidation?.()
|
||||
})
|
||||
|
||||
// persist when expensesChanged toggles
|
||||
watch(() => form.expensesChanged, () => {
|
||||
//store.setChildren(buildPayload())
|
||||
})
|
||||
watch(
|
||||
() => form,
|
||||
() => {
|
||||
store.persist()
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
watch(() => form.eatsOut, (value) => {
|
||||
if (!value) form.hasCanteenOrVouchers = false
|
||||
@@ -179,10 +170,12 @@ async function saveAndNext() {
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
store.setProfessionalExpenses(form as ProfessionalExpensesData)
|
||||
emit('next', props.step?.next)
|
||||
}
|
||||
|
||||
function emitPrev() {
|
||||
store.setProfessionalExpenses(form as ProfessionalExpensesData)
|
||||
emit('prev', props.step?.prev)
|
||||
}
|
||||
|
||||
|
||||
81
app/src/stores/professionalExpenses.ts
Normal file
81
app/src/stores/professionalExpenses.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { LocalStorage } from 'quasar'
|
||||
|
||||
export type CommuteMethod = 'CAR' | 'BUS' | 'BIKE' | 'WALK'
|
||||
|
||||
export interface ProfessionalExpensesData {
|
||||
expensesChanged: boolean
|
||||
workplaceDescription: string
|
||||
commuteMethod: CommuteMethod | null
|
||||
commuteKm: number | null
|
||||
lunchAtHome: boolean
|
||||
eatsOut: boolean
|
||||
hasCanteenOrVouchers: boolean
|
||||
}
|
||||
|
||||
const STORAGE_KEY = 'professionalExpenses:v1'
|
||||
|
||||
const DEFAULT: ProfessionalExpensesData = {
|
||||
expensesChanged: false,
|
||||
workplaceDescription: '',
|
||||
commuteMethod: null,
|
||||
commuteKm: null,
|
||||
lunchAtHome: false,
|
||||
eatsOut: false,
|
||||
hasCanteenOrVouchers: false
|
||||
}
|
||||
|
||||
function isRecord(v: unknown): v is Record<string, unknown> {
|
||||
return !!v && typeof v === 'object' && !Array.isArray(v)
|
||||
}
|
||||
|
||||
export const useProfessionalExpensesStore = defineStore('professionalexpensesstore', {
|
||||
state: () => {
|
||||
try {
|
||||
let saved: unknown = LocalStorage.getItem(STORAGE_KEY)
|
||||
if (typeof saved === 'string') {
|
||||
try {
|
||||
saved = JSON.parse(saved)
|
||||
} catch {
|
||||
saved = null
|
||||
}
|
||||
}
|
||||
if (isRecord(saved)) {
|
||||
const merged = { ...DEFAULT, ...(saved as Partial<ProfessionalExpensesData>) } as ProfessionalExpensesData
|
||||
return {
|
||||
data: {
|
||||
...merged,
|
||||
hasCanteenOrVouchers: merged.hasCanteenOrVouchers === true
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore and fall back to default
|
||||
}
|
||||
return { data: { ...DEFAULT } as ProfessionalExpensesData }
|
||||
},
|
||||
actions: {
|
||||
persist() {
|
||||
try {
|
||||
LocalStorage.set(STORAGE_KEY, this.data)
|
||||
} catch (err) {
|
||||
console.error('professionalExpenses.store: persist error', err)
|
||||
}
|
||||
},
|
||||
getProfessionalExpenses() {
|
||||
return this.data
|
||||
},
|
||||
setProfessionalExpenses(partial: Partial<ProfessionalExpensesData>) {
|
||||
this.data = { ...this.data, ...partial }
|
||||
this.persist()
|
||||
},
|
||||
replaceProfessionalExpenses(payload: ProfessionalExpensesData) {
|
||||
this.data = payload
|
||||
this.persist()
|
||||
},
|
||||
resetProfessionalExpenses() {
|
||||
this.data = { ...DEFAULT }
|
||||
this.persist()
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user