Spaces:
Runtime error
Runtime error
| <html lang="es"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Generador de Actividades Fonoaudiológicas | DeepSeek</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://unpkg.com/lucide-react@latest/dist/umd/lucide-react.js"></script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); | |
| * { | |
| box-sizing: border-box; | |
| margin: 0; | |
| padding: 0; | |
| } | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background: linear-gradient(135deg, #dbeafe 0%, #e0e7ff 100%); | |
| min-height: 100vh; | |
| } | |
| .deepseek-gradient { | |
| background: linear-gradient(135deg, #1d4ed8 0%, #2563eb 100%); | |
| } | |
| .glass { | |
| background: rgba(255, 255, 255, 0.7); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| } | |
| .loading-spinner { | |
| border: 2px solid #f3f3f3; | |
| border-top: 2px solid #3b82f6; | |
| border-radius: 50%; | |
| width: 20px; | |
| height: 20px; | |
| animation: spin 1s linear infinite; | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| .fade-in { | |
| animation: fadeIn 0.5s ease-in; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; } | |
| to { opacity: 1; } | |
| } | |
| .result-section { | |
| max-height: calc(100vh - 150px); | |
| overflow-y: auto; | |
| } | |
| @media (max-width: 1024px) { | |
| .main-grid { | |
| grid-template-columns: 1fr ; | |
| } | |
| .result-section { | |
| max-height: none; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 min-h-screen"> | |
| <div id="root" class="max-w-7xl mx-auto px-4 py-8"></div> | |
| <script type="text/babel"> | |
| const { useState, useCallback } = React; | |
| const { FileText, User, Target, Clock, Users, Settings, BookOpen, Download, Sparkles, ChevronDown, ChevronUp, Upload, X, FileCheck, Brain } = LucideReact; | |
| const SpeechTherapyGenerator = () => { | |
| const [formData, setFormData] = useState({ | |
| userDescription: '', | |
| specificObjective: '', | |
| duration: '', | |
| sessionType: 'individual', | |
| isPediatric: false, | |
| additionalContext: { | |
| customContext: '' | |
| }, | |
| references: [] | |
| }); | |
| const [generatedActivity, setGeneratedActivity] = useState(null); | |
| const [isGenerating, setIsGenerating] = useState(false); | |
| const [showAdvanced, setShowAdvanced] = useState(false); | |
| const [uploadedFiles, setUploadedFiles] = useState([]); | |
| const bloomLevels = [ | |
| { level: 'Recordar', description: 'Reconocer, listar, describir, identificar' }, | |
| { level: 'Comprender', description: 'Interpretar, resumir, inferir, parafrasear' }, | |
| { level: 'Aplicar', description: 'Ejecutar, implementar, demostrar, utilizar' }, | |
| { level: 'Analizar', description: 'Diferenciar, organizar, relacionar, comparar' }, | |
| { level: 'Evaluar', description: 'Revisar, formular hipótesis, criticar, experimentar' }, | |
| { level: 'Crear', description: 'Generar, planear, producir, diseñar' } | |
| ]; | |
| const handleInputChange = (field, value) => { | |
| if (field.includes('.')) { | |
| const [parent, child] = field.split('.'); | |
| setFormData(prev => ({ | |
| ...prev, | |
| [parent]: { | |
| ...prev[parent], | |
| [child]: value | |
| } | |
| })); | |
| } else { | |
| setFormData(prev => ({ | |
| ...prev, | |
| [field]: value | |
| })); | |
| } | |
| }; | |
| const handleFileUpload = useCallback((event) => { | |
| const files = Array.from(event.target.files); | |
| const validFiles = files.filter(file => | |
| file.type === 'application/pdf' && file.size <= 50 * 1024 * 1024 | |
| ); | |
| if (validFiles.length !== files.length) { | |
| alert('Solo se permiten archivos PDF con un tamaño máximo de 50MB'); | |
| } | |
| setUploadedFiles(prev => [...prev, ...validFiles]); | |
| setFormData(prev => ({ | |
| ...prev, | |
| references: [...prev.references, ...validFiles] | |
| })); | |
| }, []); | |
| const removeFile = (index) => { | |
| setUploadedFiles(prev => prev.filter((_, i) => i !== index)); | |
| setFormData(prev => ({ | |
| ...prev, | |
| references: prev.references.filter((_, i) => i !== index) | |
| })); | |
| }; | |
| const generateSMARTObjective = (objective, age, duration) => { | |
| const ageGroup = age < 36 ? 'preescolar' : age < 144 ? 'escolar' : 'adolescente/adulto'; | |
| const timeFrame = duration < 30 ? 'corto plazo' : duration < 60 ? 'mediano plazo' : 'largo plazo'; | |
| return `El paciente ${ageGroup} logrará ${objective} con un 80% de precisión durante ${duration} minutos, utilizando apoyo visual/auditivo según necesidad, medible a través de registro de respuestas correctas en ${timeFrame}.`; | |
| }; | |
| const analyzeAdditionalContext = (contextText) => { | |
| if (!contextText) return {}; | |
| const context = contextText.toLowerCase(); | |
| const info = {}; | |
| // Extraer tipo de material de forma más flexible | |
| const materialKeywords = { | |
| 'visual': ['tarjetas visuales', 'imágenes', 'pictogramas', 'láminas', 'fotos', 'dibujos', 'visual'], | |
| 'auditivo': ['grabaciones', 'música', 'sonidos', 'audio', 'canciones', 'melodías', 'auditivo'], | |
| 'táctil': ['texturas', 'objetos', 'táctil', 'manipulativo', 'concreto', 'palpar', 'tocar'], | |
| 'digital': ['aplicaciones', 'apps', 'tablet', 'computadora', 'software', 'digital', 'tecnología', 'dispositivo'] | |
| }; | |
| for (const [type, keywords] of Object.entries(materialKeywords)) { | |
| if (keywords.some(keyword => context.includes(keyword))) { | |
| info.materialType = type; | |
| // Extraer detalles específicos del material | |
| const materialMatch = contextText.match(new RegExp(`(${keywords.join('|')}).{0,30}`, 'i')); | |
| if (materialMatch) info.materialDetails = materialMatch[0]; | |
| break; | |
| } | |
| } | |
| // Extraer estrategia de intervención de forma más flexible | |
| const strategyKeywords = { | |
| 'Terapia Miofuncional': ['miofuncional', 'orofacial', 'muscular oral'], | |
| 'Método Bobath': ['bobath', 'neurodesarrollo', 'neuromotor'], | |
| 'Prompt': ['prompt', 'táctil-kinestésico', 'apoyo táctil'], | |
| 'Melodic Intonation Therapy': ['melodic intonation', 'mit', 'terapia melódica', 'entonación melódica'], | |
| 'Lee Silverman Voice Treatment': ['lsvt', 'lee silverman', 'voz fuerte', 'parkinson'], | |
| 'Comunicación Total': ['comunicación total', 'multimodal', 'signos'], | |
| 'Sistemas Aumentativos': ['saac', 'aumentativo', 'alternativo', 'comunicación aumentativa'], | |
| 'VitalStim': ['vitalstim', 'estimulación eléctrica', 'disfagia'], | |
| 'Terapia de Ritmo': ['ritmo', 'melodía', 'musical', 'rítmica'], | |
| 'Método Multisensorial': ['multisensorial', 'varios sentidos', 'integración sensorial'] | |
| }; | |
| for (const [strategy, keywords] of Object.entries(strategyKeywords)) { | |
| if |