fix: Corregir lógica de preguntas condicionales - frontend v1.0.20

- Sin valor por defecto en respuestas (usuario debe elegir)
- setAnswers funcional para evitar condiciones de carrera
- visibleQuestions actualizado en tiempo real
- Sub-preguntas se muestran/ocultan dinámicamente según respuesta padre
This commit is contained in:
2025-11-21 02:28:27 -03:00
parent b730c4f7c2
commit 678a8cd24b
2 changed files with 42 additions and 37 deletions

View File

@@ -38,7 +38,7 @@ services:
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4 command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
frontend: frontend:
image: dymai/syntria-frontend:1.0.19 image: dymai/syntria-frontend:1.0.20
container_name: syntria-frontend-prod container_name: syntria-frontend-prod
restart: always restart: always
depends_on: depends_on:

View File

@@ -2015,11 +2015,11 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
console.log('Questions loaded:', questionsData.length, 'questions') console.log('Questions loaded:', questionsData.length, 'questions')
setQuestions(questionsData) setQuestions(questionsData)
// Initialize answers object // Initialize answers object - empty values to force user interaction
const initialAnswers = {} const initialAnswers = {}
questionsData.forEach(q => { questionsData.forEach(q => {
initialAnswers[q.id] = { initialAnswers[q.id] = {
value: q.type === 'pass_fail' ? 'pass' : '', value: '', // No default value - user must choose
observations: '', observations: '',
photos: [] photos: []
} }
@@ -2102,7 +2102,7 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
const question = questions.find(q => q.id === questionId) const question = questions.find(q => q.id === questionId)
const answer = answers[questionId] const answer = answers[questionId]
if (!answer?.value) return // Don't save empty answers if (!answer?.value && answer?.value !== '') return // Don't save if no value
try { try {
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
@@ -2155,10 +2155,10 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
} }
// Mark as saved // Mark as saved
setAnswers({ setAnswers(prev => ({
...answers, ...prev,
[questionId]: { ...answers[questionId], saved: true } [questionId]: { ...prev[questionId], saved: true }
}) }))
} }
} catch (error) { } catch (error) {
console.error('Error saving answer:', error) console.error('Error saving answer:', error)
@@ -2415,7 +2415,9 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
} }
} }
const currentQuestion = questions[currentQuestionIndex] // Get visible questions based on conditional logic
const visibleQuestions = getVisibleQuestions()
const currentQuestion = visibleQuestions[currentQuestionIndex]
return ( return (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4"> <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
@@ -2641,10 +2643,11 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
value="pass" value="pass"
checked={answers[currentQuestion.id]?.value === 'pass'} checked={answers[currentQuestion.id]?.value === 'pass'}
onChange={(e) => { onChange={(e) => {
setAnswers({ const newValue = e.target.value
...answers, setAnswers(prev => ({
[currentQuestion.id]: { ...answers[currentQuestion.id], value: e.target.value } ...prev,
}) [currentQuestion.id]: { ...prev[currentQuestion.id], value: newValue }
}))
setTimeout(() => saveAnswer(currentQuestion.id), 500) setTimeout(() => saveAnswer(currentQuestion.id), 500)
}} }}
className="mr-2" className="mr-2"
@@ -2657,10 +2660,11 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
value="fail" value="fail"
checked={answers[currentQuestion.id]?.value === 'fail'} checked={answers[currentQuestion.id]?.value === 'fail'}
onChange={(e) => { onChange={(e) => {
setAnswers({ const newValue = e.target.value
...answers, setAnswers(prev => ({
[currentQuestion.id]: { ...answers[currentQuestion.id], value: e.target.value } ...prev,
}) [currentQuestion.id]: { ...prev[currentQuestion.id], value: newValue }
}))
setTimeout(() => saveAnswer(currentQuestion.id), 500) setTimeout(() => saveAnswer(currentQuestion.id), 500)
}} }}
className="mr-2" className="mr-2"
@@ -2674,10 +2678,11 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
<select <select
value={answers[currentQuestion.id]?.value} value={answers[currentQuestion.id]?.value}
onChange={(e) => { onChange={(e) => {
setAnswers({ const newValue = e.target.value
...answers, setAnswers(prev => ({
[currentQuestion.id]: { ...answers[currentQuestion.id], value: e.target.value } ...prev,
}) [currentQuestion.id]: { ...prev[currentQuestion.id], value: newValue }
}))
setTimeout(() => saveAnswer(currentQuestion.id), 500) setTimeout(() => saveAnswer(currentQuestion.id), 500)
}} }}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
@@ -2694,10 +2699,10 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
type="number" type="number"
step="0.01" step="0.01"
value={answers[currentQuestion.id]?.value} value={answers[currentQuestion.id]?.value}
onChange={(e) => setAnswers({ onChange={(e) => setAnswers(prev => ({
...answers, ...prev,
[currentQuestion.id]: { ...answers[currentQuestion.id], value: e.target.value } [currentQuestion.id]: { ...prev[currentQuestion.id], value: e.target.value }
})} }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
placeholder="Ingrese un valor numérico" placeholder="Ingrese un valor numérico"
/> />
@@ -2706,10 +2711,10 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
{currentQuestion.type === 'status' && ( {currentQuestion.type === 'status' && (
<select <select
value={answers[currentQuestion.id]?.value} value={answers[currentQuestion.id]?.value}
onChange={(e) => setAnswers({ onChange={(e) => setAnswers(prev => ({
...answers, ...prev,
[currentQuestion.id]: { ...answers[currentQuestion.id], value: e.target.value } [currentQuestion.id]: { ...prev[currentQuestion.id], value: e.target.value }
})} }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
> >
<option value="">Seleccionar...</option> <option value="">Seleccionar...</option>
@@ -2722,10 +2727,10 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
{currentQuestion.type === 'text' && ( {currentQuestion.type === 'text' && (
<textarea <textarea
value={answers[currentQuestion.id]?.value} value={answers[currentQuestion.id]?.value}
onChange={(e) => setAnswers({ onChange={(e) => setAnswers(prev => ({
...answers, ...prev,
[currentQuestion.id]: { ...answers[currentQuestion.id], value: e.target.value } [currentQuestion.id]: { ...prev[currentQuestion.id], value: e.target.value }
})} }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
rows="3" rows="3"
placeholder="Ingrese su respuesta" placeholder="Ingrese su respuesta"
@@ -2740,10 +2745,10 @@ function InspectionModal({ checklist, user, onClose, onComplete }) {
</label> </label>
<textarea <textarea
value={answers[currentQuestion.id]?.observations} value={answers[currentQuestion.id]?.observations}
onChange={(e) => setAnswers({ onChange={(e) => setAnswers(prev => ({
...answers, ...prev,
[currentQuestion.id]: { ...answers[currentQuestion.id], observations: e.target.value } [currentQuestion.id]: { ...prev[currentQuestion.id], observations: e.target.value }
})} }))}
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500" className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
rows="2" rows="2"
placeholder="Notas adicionales..." placeholder="Notas adicionales..."