Ahora funciona así:
Inspección nueva, Pregunta 1 (Frenos): Abro chat → aiChatMessages = [] (vacío) Pregunto sobre frenos Cierro → se guarda en answers[pregunta1].chatHistory Misma inspección, Pregunta 2 (Neumáticos): Abro chat → aiChatMessages = [] (vacío, porque esta pregunta no tiene historial) Chat limpio, sin mezclar con frenos ✅ Vuelvo a Pregunta 1: Abro chat → aiChatMessages = [historial guardado] Veo mi conversación anterior sobre frenos ✅ Nueva inspección en otro momento: Todas las preguntas empiezan con aiChatMessages = [] No se mezcla con inspecciones anteriores ✅
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "checklist-frontend",
|
||||
"private": true,
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Service Worker para PWA con detección de actualizaciones
|
||||
// IMPORTANTE: Actualizar esta versión cada vez que se despliegue una nueva versión
|
||||
const CACHE_NAME = 'ayutec-v1.1.0';
|
||||
const CACHE_NAME = 'ayutec-v1.2.0';
|
||||
const urlsToCache = [
|
||||
'/',
|
||||
'/index.html'
|
||||
|
||||
@@ -2957,8 +2957,8 @@ function ChecklistsTab({ checklists, user, onChecklistCreated, onStartInspection
|
||||
</select>
|
||||
<p className="mt-1 text-xs text-gray-500">
|
||||
{editChecklistData.ai_mode === 'off' && '❌ El mecánico completa todo manualmente'}
|
||||
{editChecklistData.ai_mode === 'assisted' && '💡 IA sugiere respuestas, el mecánico confirma'}
|
||||
{editChecklistData.ai_mode === 'copilot' && '🤖 IA completa automáticamente, el mecánico revisa'}
|
||||
{editChecklistData.ai_mode === 'assisted' && '💡 Asistente sugiere respuestas, el mecánico confirma'}
|
||||
{editChecklistData.ai_mode === 'copilot' && '🤖 Asistente completa automáticamente, el mecánico revisa'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -3597,7 +3597,7 @@ function InspectionDetailModal({ inspection, user, onClose, onUpdate, onContinue
|
||||
{user?.role === 'admin' && answer.ai_analysis && (
|
||||
<div className="bg-purple-50 border border-purple-200 rounded p-3">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-xs text-purple-800 font-semibold">🤖 Análisis de IA</span>
|
||||
<span className="text-xs text-purple-800 font-semibold">🤖 Análisis Ayutec</span>
|
||||
</div>
|
||||
<div className="text-xs text-purple-900 space-y-1">
|
||||
{Array.isArray(answer.ai_analysis) ? (
|
||||
@@ -4755,7 +4755,7 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
||||
}
|
||||
}))
|
||||
|
||||
alert('✅ Documentos cargados (sin análisis IA)')
|
||||
alert('✅ Documentos cargados (sin análisis del asistente)')
|
||||
} finally {
|
||||
setAiAnalyzing(false)
|
||||
}
|
||||
@@ -4956,10 +4956,11 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Número de OR
|
||||
Número de OR *
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
required
|
||||
value={vehicleData.or_number}
|
||||
onChange={(e) => setVehicleData({ ...vehicleData, or_number: e.target.value })}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500"
|
||||
@@ -5086,15 +5087,13 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
||||
type="button"
|
||||
onClick={() => {
|
||||
setShowAIChat(true)
|
||||
// Cargar historial si existe
|
||||
if (answers[currentQuestion.id]?.chatHistory) {
|
||||
setAiChatMessages(answers[currentQuestion.id].chatHistory)
|
||||
}
|
||||
// SIEMPRE inicializar - cargar historial guardado O array vacío para nueva sesión
|
||||
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>
|
||||
<span>Consultar Asistente</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
|
||||
@@ -5282,7 +5281,7 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
||||
const confirmChange = window.confirm(
|
||||
`⚠️ ADVERTENCIA DE COHERENCIA\n\n` +
|
||||
`Tu respuesta: "${answer.value}"\n` +
|
||||
`Análisis de IA sugiere: "${aiData.expected_answer}"\n\n` +
|
||||
`Asistente sugiere: "${aiData.expected_answer}"\n\n` +
|
||||
`La imagen muestra:\n${aiData.observations || 'Sin detalles'}\n\n` +
|
||||
`¿Deseas cambiar tu respuesta antes de continuar?\n\n` +
|
||||
`• Presiona CANCELAR para revisar y cambiar tu respuesta\n` +
|
||||
@@ -5328,7 +5327,7 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
||||
const confirmChange = window.confirm(
|
||||
`⚠️ ADVERTENCIA DE COHERENCIA\n\n` +
|
||||
`Tu respuesta: "${answer.value}"\n` +
|
||||
`Análisis de IA sugiere: "${aiData.expected_answer}"\n\n` +
|
||||
`Asistente sugiere: "${aiData.expected_answer}"\n\n` +
|
||||
`La imagen muestra:\n${aiData.observations || 'Sin detalles'}\n\n` +
|
||||
`¿Deseas cambiar tu respuesta antes de completar?\n\n` +
|
||||
`• Presiona CANCELAR para revisar y cambiar tu respuesta\n` +
|
||||
@@ -5595,8 +5594,12 @@ function AIAssistantChatModal({ question, inspection, allAnswers, messages, setM
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-3xl">💬</span>
|
||||
<h3 className="text-lg sm:text-xl font-bold">Asistente IA</h3>
|
||||
<img
|
||||
src="/ayutec_logo.png"
|
||||
alt="Ayutec"
|
||||
className="w-8 h-8 object-contain bg-white rounded p-1"
|
||||
/>
|
||||
<h3 className="text-lg sm:text-xl font-bold">Asistente Ayutec</h3>
|
||||
</div>
|
||||
<p className="text-sm sm:text-base text-purple-100 line-clamp-2">
|
||||
{question.text}
|
||||
@@ -5623,9 +5626,15 @@ function AIAssistantChatModal({ question, inspection, allAnswers, messages, setM
|
||||
<div className="flex-1 overflow-y-auto p-4 sm:p-6 space-y-4 bg-gray-50">
|
||||
{messages.length === 0 && (
|
||||
<div className="text-center py-12">
|
||||
<div className="text-6xl mb-4">🤖</div>
|
||||
<div className="mb-4 flex justify-center">
|
||||
<img
|
||||
src="/ayutec_logo.png"
|
||||
alt="Ayutec"
|
||||
className="w-16 h-16 object-contain bg-white rounded-lg p-2 shadow-lg"
|
||||
/>
|
||||
</div>
|
||||
<p className="text-gray-600 text-sm sm:text-base mb-2">
|
||||
¡Hola! Soy tu asistente técnico.
|
||||
¡Hola! Soy tu Asistente Ayutec.
|
||||
</p>
|
||||
<p className="text-gray-500 text-xs sm:text-sm">
|
||||
He analizado las fotos anteriores. ¿En qué puedo ayudarte?
|
||||
|
||||
@@ -292,16 +292,16 @@ export function QuestionAnswerInput({ question, value, onChange, onSave }) {
|
||||
)
|
||||
}
|
||||
|
||||
// AI_ASSISTANT (Chat con IA)
|
||||
// AI_ASSISTANT (Chat con asistente)
|
||||
if (questionType === 'ai_assistant') {
|
||||
return (
|
||||
<div className="p-4 bg-gradient-to-r from-purple-50 to-blue-50 border-2 border-purple-200 rounded-lg">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-2xl">💬</span>
|
||||
<h4 className="font-semibold text-purple-900">Asistente IA Disponible</h4>
|
||||
<h4 className="font-semibold text-purple-900">Asistente Disponible</h4>
|
||||
</div>
|
||||
<p className="text-sm text-purple-700 mb-2">
|
||||
Haz clic en el botón "💬 Consultar Asistente" debajo para abrir el chat con IA.
|
||||
Haz clic en el botón "💬 Consultar Asistente" debajo para abrir el chat.
|
||||
El asistente ha analizado las fotos anteriores y está listo para ayudarte.
|
||||
</p>
|
||||
<div className="text-xs text-purple-600 bg-white/50 rounded px-2 py-1">
|
||||
|
||||
@@ -24,7 +24,7 @@ const QUESTION_TYPES = [
|
||||
{ value: 'date', label: '📅 Fecha', icon: '📆' },
|
||||
{ value: 'time', label: '🕐 Hora', icon: '⏰' },
|
||||
{ value: 'photo_only', label: '📸 Solo Fotografía', icon: '📷' },
|
||||
{ value: 'ai_assistant', label: '🤖 Asistente IA (Chat)', icon: '💬' }
|
||||
{ value: 'ai_assistant', label: '🤖 Asistente (Chat)', icon: '💬' }
|
||||
]
|
||||
|
||||
const STATUS_OPTIONS = [
|
||||
@@ -543,9 +543,9 @@ export function QuestionTypeEditor({ value, onChange, maxPoints = 1 }) {
|
||||
<div className="flex items-start gap-3">
|
||||
<span className="text-3xl">💬</span>
|
||||
<div>
|
||||
<h4 className="font-semibold text-blue-900 mb-1">Asistente IA Conversacional</h4>
|
||||
<h4 className="font-semibold text-blue-900 mb-1">Asistente Conversacional</h4>
|
||||
<p className="text-sm text-blue-700">
|
||||
El mecánico podrá chatear con IA usando fotos de preguntas anteriores como contexto.
|
||||
El mecánico podrá chatear con el asistente usando fotos de preguntas anteriores como contexto.
|
||||
Configura qué preguntas anteriores usar y el comportamiento del asistente.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -153,7 +153,7 @@ export default function Sidebar({ user, activeTab, setActiveTab, sidebarOpen, se
|
||||
className="w-10 h-10 object-contain bg-white rounded p-1"
|
||||
/>
|
||||
<p className="text-xs text-indigo-300 font-medium hover:text-indigo-200">
|
||||
Ayutec v1.1.0
|
||||
Ayutec v1.2.0
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user