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",
|
"name": "checklist-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"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.1.0';
|
const CACHE_NAME = 'ayutec-v1.2.0';
|
||||||
const urlsToCache = [
|
const urlsToCache = [
|
||||||
'/',
|
'/',
|
||||||
'/index.html'
|
'/index.html'
|
||||||
|
|||||||
@@ -2957,8 +2957,8 @@ function ChecklistsTab({ checklists, user, onChecklistCreated, onStartInspection
|
|||||||
</select>
|
</select>
|
||||||
<p className="mt-1 text-xs text-gray-500">
|
<p className="mt-1 text-xs text-gray-500">
|
||||||
{editChecklistData.ai_mode === 'off' && '❌ El mecánico completa todo manualmente'}
|
{editChecklistData.ai_mode === 'off' && '❌ El mecánico completa todo manualmente'}
|
||||||
{editChecklistData.ai_mode === 'assisted' && '💡 IA sugiere respuestas, el mecánico confirma'}
|
{editChecklistData.ai_mode === 'assisted' && '💡 Asistente sugiere respuestas, el mecánico confirma'}
|
||||||
{editChecklistData.ai_mode === 'copilot' && '🤖 IA completa automáticamente, el mecánico revisa'}
|
{editChecklistData.ai_mode === 'copilot' && '🤖 Asistente completa automáticamente, el mecánico revisa'}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -3597,7 +3597,7 @@ function InspectionDetailModal({ inspection, user, onClose, onUpdate, onContinue
|
|||||||
{user?.role === 'admin' && answer.ai_analysis && (
|
{user?.role === 'admin' && answer.ai_analysis && (
|
||||||
<div className="bg-purple-50 border border-purple-200 rounded p-3">
|
<div className="bg-purple-50 border border-purple-200 rounded p-3">
|
||||||
<div className="flex items-center gap-2 mb-2">
|
<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>
|
||||||
<div className="text-xs text-purple-900 space-y-1">
|
<div className="text-xs text-purple-900 space-y-1">
|
||||||
{Array.isArray(answer.ai_analysis) ? (
|
{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 {
|
} finally {
|
||||||
setAiAnalyzing(false)
|
setAiAnalyzing(false)
|
||||||
}
|
}
|
||||||
@@ -4956,10 +4956,11 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Número de OR
|
Número de OR *
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
required
|
||||||
value={vehicleData.or_number}
|
value={vehicleData.or_number}
|
||||||
onChange={(e) => setVehicleData({ ...vehicleData, or_number: e.target.value })}
|
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"
|
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"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShowAIChat(true)
|
setShowAIChat(true)
|
||||||
// Cargar historial si existe
|
// SIEMPRE inicializar - cargar historial guardado O array vacío para nueva sesión
|
||||||
if (answers[currentQuestion.id]?.chatHistory) {
|
setAiChatMessages(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"
|
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>💬</span>
|
||||||
<span>Consultar Asistente IA</span>
|
<span>Consultar Asistente</span>
|
||||||
{answers[currentQuestion.id]?.chatHistory?.length > 0 && (
|
{answers[currentQuestion.id]?.chatHistory?.length > 0 && (
|
||||||
<span className="ml-1 px-2 py-0.5 bg-white/20 rounded-full text-xs">
|
<span className="ml-1 px-2 py-0.5 bg-white/20 rounded-full text-xs">
|
||||||
{answers[currentQuestion.id].chatHistory.length} mensajes
|
{answers[currentQuestion.id].chatHistory.length} mensajes
|
||||||
@@ -5282,7 +5281,7 @@ function InspectionModal({ checklist, existingInspection, user, onClose, onCompl
|
|||||||
const confirmChange = window.confirm(
|
const confirmChange = window.confirm(
|
||||||
`⚠️ ADVERTENCIA DE COHERENCIA\n\n` +
|
`⚠️ ADVERTENCIA DE COHERENCIA\n\n` +
|
||||||
`Tu respuesta: "${answer.value}"\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` +
|
`La imagen muestra:\n${aiData.observations || 'Sin detalles'}\n\n` +
|
||||||
`¿Deseas cambiar tu respuesta antes de continuar?\n\n` +
|
`¿Deseas cambiar tu respuesta antes de continuar?\n\n` +
|
||||||
`• Presiona CANCELAR para revisar y cambiar tu respuesta\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(
|
const confirmChange = window.confirm(
|
||||||
`⚠️ ADVERTENCIA DE COHERENCIA\n\n` +
|
`⚠️ ADVERTENCIA DE COHERENCIA\n\n` +
|
||||||
`Tu respuesta: "${answer.value}"\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` +
|
`La imagen muestra:\n${aiData.observations || 'Sin detalles'}\n\n` +
|
||||||
`¿Deseas cambiar tu respuesta antes de completar?\n\n` +
|
`¿Deseas cambiar tu respuesta antes de completar?\n\n` +
|
||||||
`• Presiona CANCELAR para revisar y cambiar tu respuesta\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 items-start justify-between gap-3">
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<div className="flex items-center gap-2 mb-2">
|
<div className="flex items-center gap-2 mb-2">
|
||||||
<span className="text-3xl">💬</span>
|
<img
|
||||||
<h3 className="text-lg sm:text-xl font-bold">Asistente IA</h3>
|
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>
|
</div>
|
||||||
<p className="text-sm sm:text-base text-purple-100 line-clamp-2">
|
<p className="text-sm sm:text-base text-purple-100 line-clamp-2">
|
||||||
{question.text}
|
{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">
|
<div className="flex-1 overflow-y-auto p-4 sm:p-6 space-y-4 bg-gray-50">
|
||||||
{messages.length === 0 && (
|
{messages.length === 0 && (
|
||||||
<div className="text-center py-12">
|
<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">
|
<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>
|
||||||
<p className="text-gray-500 text-xs sm:text-sm">
|
<p className="text-gray-500 text-xs sm:text-sm">
|
||||||
He analizado las fotos anteriores. ¿En qué puedo ayudarte?
|
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') {
|
if (questionType === 'ai_assistant') {
|
||||||
return (
|
return (
|
||||||
<div className="p-4 bg-gradient-to-r from-purple-50 to-blue-50 border-2 border-purple-200 rounded-lg">
|
<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">
|
<div className="flex items-center gap-2 mb-2">
|
||||||
<span className="text-2xl">💬</span>
|
<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>
|
</div>
|
||||||
<p className="text-sm text-purple-700 mb-2">
|
<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.
|
El asistente ha analizado las fotos anteriores y está listo para ayudarte.
|
||||||
</p>
|
</p>
|
||||||
<div className="text-xs text-purple-600 bg-white/50 rounded px-2 py-1">
|
<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: 'date', label: '📅 Fecha', icon: '📆' },
|
||||||
{ value: 'time', label: '🕐 Hora', icon: '⏰' },
|
{ value: 'time', label: '🕐 Hora', icon: '⏰' },
|
||||||
{ value: 'photo_only', label: '📸 Solo Fotografía', 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 = [
|
const STATUS_OPTIONS = [
|
||||||
@@ -543,9 +543,9 @@ export function QuestionTypeEditor({ value, onChange, maxPoints = 1 }) {
|
|||||||
<div className="flex items-start gap-3">
|
<div className="flex items-start gap-3">
|
||||||
<span className="text-3xl">💬</span>
|
<span className="text-3xl">💬</span>
|
||||||
<div>
|
<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">
|
<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.
|
Configura qué preguntas anteriores usar y el comportamiento del asistente.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</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"
|
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">
|
<p className="text-xs text-indigo-300 font-medium hover:text-indigo-200">
|
||||||
Ayutec v1.1.0
|
Ayutec v1.2.0
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user