Spaces:
Configuration error
Configuration error
| import React, { useState, useCallback, useRef, useEffect } from 'react'; | |
| import type { AlchemicalResult, ChatMessage } from '../types'; | |
| import { getSocraticResponse } from '../services/hermeticEngine'; | |
| import Spinner from './ui/Spinner'; | |
| type Tab = 'mirror' | 'quintessence' | 'dialogue'; | |
| interface Props { | |
| result: AlchemicalResult; | |
| } | |
| const TabButton: React.FC<{ active: boolean; onClick: () => void; children: React.ReactNode }> = ({ active, onClick, children }) => ( | |
| <button | |
| onClick={onClick} | |
| className={`font-serif px-4 py-2 text-lg transition-all duration-300 border-b-2 ${ | |
| active | |
| ? 'text-white border-[#a9a3f4]' | |
| : 'text-gray-500 border-transparent hover:text-white' | |
| }`} | |
| > | |
| {children} | |
| </button> | |
| ); | |
| const DialogueTab: React.FC<{ result: AlchemicalResult }> = ({ result }) => { | |
| const [history, setHistory] = useState<ChatMessage[]>([]); | |
| const [userInput, setUserInput] = useState(''); | |
| const [isThinking, setIsThinking] = useState(false); | |
| const chatEndRef = useRef<HTMLDivElement>(null); | |
| useEffect(() => { | |
| chatEndRef.current?.scrollIntoView({ behavior: 'smooth' }); | |
| }, [history]); | |
| const handleSend = useCallback(() => { | |
| if (!userInput.trim() && history.length > 0) return; | |
| const userMessage: ChatMessage = { sender: 'user', text: userInput }; | |
| setHistory(prev => [...prev, userMessage]); | |
| setUserInput(''); | |
| setIsThinking(true); | |
| setTimeout(() => { | |
| const aethelredResponse = getSocraticResponse(result, history); | |
| setHistory(prev => [...prev, aethelredResponse]); | |
| setIsThinking(false); | |
| }, 1500 + Math.random() * 500); | |
| }, [userInput, result, history]); | |
| useEffect(() => { | |
| // Initial message from Aethelred | |
| setIsThinking(true); | |
| setTimeout(() => { | |
| const initialQuestion = getSocraticResponse(result, []); | |
| setHistory([initialQuestion]); | |
| setIsThinking(false); | |
| }, 1000); | |
| }, [result]); | |
| return ( | |
| <div className="flex flex-col h-[500px] bg-[#111111] p-4 rounded-b-lg"> | |
| <div className="flex-grow overflow-y-auto pr-2"> | |
| {history.map((msg, index) => ( | |
| <div key={index} className={`flex ${msg.sender === 'user' ? 'justify-end' : 'justify-start'} mb-4`}> | |
| <div className={`max-w-xs md:max-w-md p-3 rounded-lg ${msg.sender === 'user' ? 'bg-[#a9a3f4] text-black' : 'bg-[#2a2a2a] text-gray-300'}`}> | |
| <p className="font-serif text-lg">{msg.text}</p> | |
| </div> | |
| </div> | |
| ))} | |
| {isThinking && ( | |
| <div className="flex justify-start mb-4"> | |
| <div className="max-w-xs md:max-w-md p-3 rounded-lg bg-[#2a2a2a] text-gray-300 flex items-center"> | |
| <Spinner/> | |
| </div> | |
| </div> | |
| )} | |
| <div ref={chatEndRef} /> | |
| </div> | |
| <div className="mt-4 flex"> | |
| <input | |
| type="text" | |
| value={userInput} | |
| onChange={(e) => setUserInput(e.target.value)} | |
| onKeyPress={(e) => e.key === 'Enter' && !isThinking && handleSend()} | |
| placeholder="Responde o pregunta..." | |
| className="flex-grow p-3 bg-[#181818] border border-gray-700 rounded-l-md focus:outline-none focus:ring-1 focus:ring-[#a9a3f4] text-white" | |
| disabled={isThinking} | |
| /> | |
| <button onClick={handleSend} disabled={isThinking} className="px-6 py-2 bg-[#a9a3f4] text-black rounded-r-md font-bold hover:bg-white disabled:bg-gray-600 transition-colors"> | |
| Enviar | |
| </button> | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default function ReflectionView({ result }: Props) { | |
| const [activeTab, setActiveTab] = useState<Tab>('mirror'); | |
| return ( | |
| <div className="w-full bg-[#181818] rounded-lg shadow-2xl shadow-black/30"> | |
| <nav className="flex justify-around border-b border-gray-700"> | |
| <TabButton active={activeTab === 'mirror'} onClick={() => setActiveTab('mirror')}>El Espejo Hermético</TabButton> | |
| <TabButton active={activeTab === 'quintessence'} onClick={() => setActiveTab('quintessence')}>La Quintaesencia</TabButton> | |
| <TabButton active={activeTab === 'dialogue'} onClick={() => setActiveTab('dialogue')}>El Diálogo Alquímico</TabButton> | |
| </nav> | |
| <div className="p-4 md:p-8 min-h-[500px]"> | |
| {activeTab === 'mirror' && ( | |
| <div className="text-center animate-fade-in"> | |
| <h3 className="font-serif text-3xl text-[#a9a3f4] mb-4">{result.mirror.archetype}</h3> | |
| <div className="grid md:grid-cols-2 gap-8 mt-8"> | |
| <div> | |
| <h4 className="font-serif text-2xl text-white border-b-2 border-green-400 pb-2 mb-3">Principio en Luz</h4> | |
| <p className="text-xl font-bold mb-2">{result.mirror.principleInLight.name}</p> | |
| <p className="text-gray-400 italic">{result.mirror.principleInLight.description}</p> | |
| </div> | |
| <div> | |
| <h4 className="font-serif text-2xl text-white border-b-2 border-red-400 pb-2 mb-3">Principio en Sombra</h4> | |
| <p className="text-xl font-bold mb-2">{result.mirror.principleInShadow.name}</p> | |
| <p className="text-gray-400 italic">{result.mirror.principleInShadow.description}</p> | |
| </div> | |
| </div> | |
| </div> | |
| )} | |
| {activeTab === 'quintessence' && ( | |
| <div className="flex items-center justify-center h-full min-h-[400px] animate-fade-in"> | |
| <p className="font-serif text-2xl md:text-3xl text-center max-w-2xl leading-relaxed italic text-gray-300"> | |
| "{result.quintessence}" | |
| </p> | |
| </div> | |
| )} | |
| {activeTab === 'dialogue' && <DialogueTab result={result} />} | |
| </div> | |
| </div> | |
| ); | |
| } |