Campo de Observaciones Opcional
✅ Agregado checkbox "Agregar campo observaciones" en QuestionTypeEditor.jsx (sección "Opciones Generales") ✅ Por defecto está marcado (compatibilidad con preguntas existentes) ✅ El campo de observaciones solo se muestra si show_observations !== false ✅ El admin ahora tiene control total sobre si mostrar o no las observaciones 2. Botón "Consultar Asistente IA" Siempre Visible ✅ El botón ahora aparece siempre para preguntas tipo ai_assistant ✅ No depende de que la pregunta tenga fotos habilitadas ✅ Movido a una sección independiente (fuera del bloque de fotos) ✅ Removido el botón duplicado que estaba dentro de la sección de fotos 3. Versiones Actualizadas Frontend: 1.0.89 → 1.0.90 Service Worker: ayutec-v1.0.89 → ayutec-v1.0.90 Backend: Sin cambios (no fue necesario) 📋 Detalles Técnicos App.jsx: Campo de respuesta oculto para photo_only y ai_assistant Botón de Asistente IA en sección dedicada (siempre visible para ai_assistant) Observaciones solo si show_observations !== false y no es photo_only ni ai_assistant QuestionTypeEditor.jsx: Nueva sección "⚙️ Opciones Generales" con checkbox azul Texto de ayuda: "Si está marcado, el mecánico podrá agregar notas adicionales"
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "checklist-frontend",
|
"name": "checklist-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.89",
|
"version": "1.0.90",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Service Worker para PWA con detección de actualizaciones
|
// Service Worker para PWA con detección de actualizaciones
|
||||||
// IMPORTANTE: Actualizar esta versión cada vez que se despliegue una nueva versión
|
// IMPORTANTE: Actualizar esta versión cada vez que se despliegue una nueva versión
|
||||||
const CACHE_NAME = 'ayutec-v1.0.89';
|
const CACHE_NAME = 'ayutec-v1.0.90';
|
||||||
const urlsToCache = [
|
const urlsToCache = [
|
||||||
'/',
|
'/',
|
||||||
'/index.html'
|
'/index.html'
|
||||||
|
|||||||
@@ -4921,8 +4921,8 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-3 sm:space-y-4">
|
<div className="space-y-3 sm:space-y-4">
|
||||||
{/* Answer input based on type - NO mostrar para photo_only */}
|
{/* Answer input based on type - NO mostrar para photo_only ni ai_assistant */}
|
||||||
{currentQuestion.options?.type !== 'photo_only' && (
|
{currentQuestion.options?.type !== 'photo_only' && currentQuestion.options?.type !== 'ai_assistant' && (
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
Respuesta *
|
Respuesta *
|
||||||
@@ -4942,8 +4942,47 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Observations - NO mostrar para photo_only */}
|
{/* Botón de Chat IA - Mostrar SIEMPRE si es tipo ai_assistant */}
|
||||||
{currentQuestion.options?.type !== 'photo_only' && (
|
{currentQuestion.options?.type === 'ai_assistant' && (
|
||||||
|
<div>
|
||||||
|
<QuestionAnswerInput
|
||||||
|
question={currentQuestion}
|
||||||
|
value={answers[currentQuestion.id]?.value}
|
||||||
|
onChange={(newValue) => {
|
||||||
|
setAnswers(prev => ({
|
||||||
|
...prev,
|
||||||
|
[currentQuestion.id]: { ...prev[currentQuestion.id], value: newValue }
|
||||||
|
}))
|
||||||
|
}}
|
||||||
|
onSave={() => setTimeout(() => saveAnswer(currentQuestion.id), 500)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
setShowAIChat(true)
|
||||||
|
// Cargar historial si existe
|
||||||
|
if (answers[currentQuestion.id]?.chatHistory) {
|
||||||
|
setAiChatMessages(answers[currentQuestion.id].chatHistory)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className="w-full mt-3 px-4 py-3 bg-gradient-to-r from-purple-600 to-blue-600 text-white rounded-lg hover:from-purple-700 hover:to-blue-700 transition flex items-center justify-center gap-2 font-semibold shadow-lg"
|
||||||
|
>
|
||||||
|
<span>💬</span>
|
||||||
|
<span>Consultar Asistente IA</span>
|
||||||
|
{answers[currentQuestion.id]?.chatHistory?.length > 0 && (
|
||||||
|
<span className="ml-1 px-2 py-0.5 bg-white/20 rounded-full text-xs">
|
||||||
|
{answers[currentQuestion.id].chatHistory.length} mensajes
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Observations - Mostrar solo si show_observations !== false */}
|
||||||
|
{currentQuestion.options?.type !== 'photo_only' &&
|
||||||
|
currentQuestion.options?.type !== 'ai_assistant' &&
|
||||||
|
currentQuestion.options?.show_observations !== false && (
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
Observaciones (opcional)
|
Observaciones (opcional)
|
||||||
@@ -5024,8 +5063,9 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Analyze Button */}
|
{/* Analyze Button - Solo para ai_mode assisted/full y NO para ai_assistant */}
|
||||||
{(checklist.ai_mode === 'assisted' || checklist.ai_mode === 'full') && (
|
{(checklist.ai_mode === 'assisted' || checklist.ai_mode === 'full') &&
|
||||||
|
currentQuestion.options?.type !== 'ai_assistant' && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => handleAnalyzePhotos(currentQuestion.id)}
|
onClick={() => handleAnalyzePhotos(currentQuestion.id)}
|
||||||
@@ -5045,29 +5085,6 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
|||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Botón para abrir chat IA (si es tipo ai_assistant) */}
|
|
||||||
{currentQuestion.options?.type === 'ai_assistant' && (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => {
|
|
||||||
setShowAIChat(true)
|
|
||||||
// Cargar historial si existe
|
|
||||||
if (answers[currentQuestion.id]?.chatHistory) {
|
|
||||||
setAiChatMessages(answers[currentQuestion.id].chatHistory)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="w-full mt-3 px-4 py-3 bg-gradient-to-r from-purple-600 to-blue-600 text-white rounded-lg hover:from-purple-700 hover:to-blue-700 transition flex items-center justify-center gap-2 font-semibold shadow-lg"
|
|
||||||
>
|
|
||||||
<span>💬</span>
|
|
||||||
<span>Consultar Asistente IA</span>
|
|
||||||
{answers[currentQuestion.id]?.chatHistory?.length > 0 && (
|
|
||||||
<span className="ml-1 px-2 py-0.5 bg-white/20 rounded-full text-xs">
|
|
||||||
{answers[currentQuestion.id].chatHistory.length} mensajes
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -197,6 +197,28 @@ export function QuestionTypeEditor({ value, onChange, maxPoints = 1 }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Opciones Globales */}
|
||||||
|
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
|
||||||
|
<h4 className="font-semibold text-blue-900 mb-3 text-sm">⚙️ Opciones Generales</h4>
|
||||||
|
<div className="space-y-2">
|
||||||
|
{/* Checkbox para campo de observaciones */}
|
||||||
|
<label className="flex items-center gap-2 cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={config.show_observations !== false}
|
||||||
|
onChange={(e) => updateConfig({ show_observations: e.target.checked })}
|
||||||
|
className="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
|
||||||
|
/>
|
||||||
|
<span className="text-sm text-gray-700">
|
||||||
|
📝 Mostrar campo de observaciones al mecánico
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<p className="text-xs text-gray-500 ml-6">
|
||||||
|
Si está marcado, el mecánico podrá agregar notas adicionales en esta pregunta
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Configuración específica según tipo */}
|
{/* Configuración específica según tipo */}
|
||||||
<div className="bg-gray-50 border border-gray-200 rounded-lg p-4">
|
<div className="bg-gray-50 border border-gray-200 rounded-lg p-4">
|
||||||
{/* BOOLEAN */}
|
{/* BOOLEAN */}
|
||||||
|
|||||||
Reference in New Issue
Block a user