Files
asistente/pages/index.vue
2025-10-22 10:38:38 +02:00

244 lines
8.2 KiB
Vue

<template>
<FormSlice :type="currentSlice.type">
<template v-if="currentSliceComponent">
<transition name="fade" mode="out-in">
<component
:is="currentSliceComponent"
:key="currentSliceId"
:data="currentSlice"
:current-index="currentQuestionIndex"
:total="questionSlices.length"
@previous="goToPrevious"
@next="goToNext($event)"
/>
</transition>
</template>
<br>
</FormSlice>
</template>
<script>
import { surveyData } from "@/data/bravioo.js" // Ajusta la ruta según la ubicación de tu archivo de datos
import FormSlice from "@/components/FormSlice.vue"
import SliceWelcome from "@/components/SliceWelcome.vue"
import SliceQuestion from "@/components/SliceQuestion.vue"
import SliceEnd from "@/components/SliceEnd.vue"
import ButtonCTA from "@/components/ButtonCTA.vue"
import SliceFeedback from "@/components/SliceFeedback.vue"
export default {
components: {
FormSlice,
SliceWelcome,
SliceQuestion,
SliceEnd,
SliceFeedback,
ButtonCTA
},
data() {
return {
surveyData,
currentSliceId: surveyData.slices[0].id,
answers: [],
score: null,
results: null
}
},
computed: {
currentSlice() {
return surveyData.slices.find(s => s.id === this.currentSliceId)
},
currentSliceComponent() {
switch (this.currentSlice.type) {
case "welcome": return "SliceWelcome"
case "question": return "SliceQuestion"
case "feedback": return "SliceFeedback"
case "end": return "SliceEnd"
default: return "SliceQuestion"
}
},
questionSlices() {
return surveyData.slices.filter(s => s.type === "question")
},
currentQuestionIndex() {
return this.questionSlices.findIndex(s => s.id === this.currentSliceId)
},
},
watch: {
currentSlice() {
if (this.currentSlice.type === "feedback") {
this.calculateBlockResult()
}
if (this.currentSlice.type === "end") {
this.calculateFinalScore()
}
}
},
mounted() {
// Al montar, escuchar el evento de recarga/cierre
window.addEventListener("beforeunload", this.clearStorageOnReload)
},
beforeUnmount() {
// Limpiar el listener al desmontar el componente
window.removeEventListener("beforeunload", this.clearStorageOnReload)
},
methods: {
clearStorageOnReload() {
localStorage.removeItem("previous-slices")
localStorage.removeItem("answers")
localStorage.removeItem("score")
localStorage.removeItem("results")
localStorage.removeItem("final-score")
},
goToNext(event) {
if (this.currentSlice.type === "question" && event !== undefined) {
const answerObj = {
sectionId: this.currentSlice.section.id,
sectionTitle: this.currentSlice.section.title,
sliceId: this.currentSlice.id,
value: event.value,
score: event.score,
questionTotalPoints: this.currentSlice.questionTotalPoints || 0,
}
this.saveAnswer(answerObj)
}
const nextConfig = this.currentSlice.next
//console.log("Navegando desde slice:", this.currentSliceId, "con configuración next:", nextConfig)
if (!nextConfig) {
////console.log("Encuesta finalizada", this.answers)
return
}
// Guardar la respuesta en localStorage 'previous-slices' y avanzar a la siguiente pregunta
if (nextConfig) {
const previousSlices = JSON.parse(localStorage.getItem('previous-slices')) || []
previousSlices.push(this.currentSliceId)
localStorage.setItem('previous-slices', JSON.stringify(previousSlices))
}
if (typeof nextConfig === "string") {
// Navegación lineal
this.currentSliceId = nextConfig
} else if (typeof nextConfig === "object") {
// Navegación condicional por valor de respuesta
const nextSlice = nextConfig[event]
if (nextSlice) {
this.currentSliceId = nextSlice
} else {
console.warn("No se encontró siguiente slice para:", event)
}
}
},
goToPrevious() {
// Leer el historial
const previousSlices = JSON.parse(localStorage.getItem('previous-slices')) || []
////console.log("Historial de slices anteriores:", previousSlices)
if (previousSlices.length === 0) {
console.warn("No hay slices anteriores en el historial")
return
}
// Sacar el último paso visitado
const lastSliceId = previousSlices.pop()
const currentAnswer = this.answers.pop() // Eliminar la última respuesta guardada
// Actualizar el historial en localStorage
localStorage.setItem('previous-slices', JSON.stringify(previousSlices))
localStorage.setItem('answers', JSON.stringify(this.answers))
// Cambiar al slice anterior
this.currentSliceId = lastSliceId
},
saveAnswer(payload) {
// payload: { id: "question1", value: "Si" }
////console.log("Guardando respuesta:", payload)
let el;
if (typeof payload !== "object") {
el = {
value: payload,
label: payload,
score: 0,
}
} else {
el = payload
}
////console.log("Guardando respuesta:", el)
this.answers.push(el)
localStorage.setItem("answers", JSON.stringify(this.answers))
},
calculateBlockResult() {
// Calcular el score basado en las respuestas guardadas con el mismo sectionId
const answers = JSON.parse(localStorage.getItem('answers'))
if (answers && answers.length > 0) {
const currentSectionId = this.currentSlice.section.id
const sectionAnswers = answers.filter(a => a.sectionId === currentSectionId)
const sectionScore = sectionAnswers.reduce((acc, curr) => acc + (curr.score || 0), 0)
//console.log(`Score para la sección ${currentSectionId}:`, sectionScore)
// En funcion de la sección, aplicar regla si existe
const evaluate = surveyData.rules[currentSectionId]
const sectionResult = evaluate ? evaluate(sectionScore) : "SIN REGLA"
//console.log(`Resultado para la sección ${currentSectionId}:`, sectionResult)
// Calcular los puntos totales posibles para la sección
const sectionPossibleTotalPoints = sectionAnswers.reduce((acc, curr) => acc + (curr.questionTotalPoints || 0), 0)
//console.log(`Puntos totales posibles para la sección ${currentSectionId}:`, sectionPossibleTotalPoints)
// Guardar el resultado parcial en localStorage
const existingResults = JSON.parse(localStorage.getItem('results')) || []
const updatedResults = existingResults.filter(r => r.sectionId !== currentSectionId) // Eliminar resultado previo de la misma sección
updatedResults.push({ sectionId: currentSectionId, sectionTitle: this.currentSlice.section.title, sectionPossibleTotalPoints: sectionPossibleTotalPoints, score: sectionScore, result: sectionResult })
localStorage.setItem('results', JSON.stringify(updatedResults))
}
},
calculateFinalScore() {
const results = JSON.parse(localStorage.getItem('results'))
if (results && results.length > 0) {
// Calcular el número total de puntos posibles
const totalPossiblePoints = results.reduce((acc, curr) => acc + (curr.sectionPossibleTotalPoints || 0), 0)
// Calcular el score total sumando los scores de cada sección
const totalScore = results.reduce((acc, curr) => acc + (curr.score || 0), 0)
this.score = totalScore
// En funcion del score total, aplicar regla si existe
const finalRecommendations = surveyData.finalRecommendations?.total?.(totalScore) ?? null;
// Guardar el score total en localStorage
localStorage.setItem('final-score', JSON.stringify({ totalPossiblePoints: totalPossiblePoints, score: totalScore, recommendations: finalRecommendations || "" }))
this.results = results
}
}
}
}
</script>
<style scoped>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
.fade-enter-to, .fade-leave-from {
opacity: 1;
}
</style>