|
|
import React, { useState, useCallback } from 'react'; |
|
|
import { generateProResponse } from '../services/geminiService'; |
|
|
import { Spinner } from '../components/Spinner'; |
|
|
import { MarkdownRenderer } from '../components/MarkdownRenderer'; |
|
|
|
|
|
const majorArcana = [ |
|
|
"The Fool", "The Magician", "The High Priestess", "The Empress", "The Emperor", |
|
|
"The Hierophant", "The Lovers", "The Chariot", "Strength", "The Hermit", |
|
|
"Wheel of Fortune", "Justice", "The Hanged Man", "Death", "Temperance", |
|
|
"The Devil", "The Tower", "The Star", "The Moon", "The Sun", "Judgement", "The World" |
|
|
]; |
|
|
|
|
|
const TarotModule: React.FC = () => { |
|
|
const [cards, setCards] = useState<string[]>([]); |
|
|
const [interpretation, setInterpretation] = useState<string | null>(null); |
|
|
const [isLoading, setIsLoading] = useState(false); |
|
|
const [error, setError] = useState<string | null>(null); |
|
|
|
|
|
const handleDraw = useCallback(async () => { |
|
|
setIsLoading(true); |
|
|
setError(null); |
|
|
setInterpretation(null); |
|
|
|
|
|
|
|
|
const shuffled = [...majorArcana].sort(() => 0.5 - Math.random()); |
|
|
const drawnCards = shuffled.slice(0, 3); |
|
|
setCards(drawnCards); |
|
|
|
|
|
const prompt = `You are a mystical tarot reader within the Sentient Constellation Codex. You see the threads of fate in the cosmos. |
|
|
A user has drawn a three-card spread (representing Past, Present, and Future). The cards are: |
|
|
1. Past: ${drawnCards[0]} |
|
|
2. Present: ${drawnCards[1]} |
|
|
3. Future: ${drawnCards[2]} |
|
|
|
|
|
Provide a rich, insightful, and slightly mystical interpretation of this spread. Explain each card's meaning in its position and then weave them together into a coherent narrative for the user's journey.`; |
|
|
|
|
|
try { |
|
|
const result = await generateProResponse(prompt); |
|
|
setInterpretation(result.text); |
|
|
} catch (e: any) { |
|
|
setError(e.message || "A cosmic interference prevented the reading. Please try again."); |
|
|
} finally { |
|
|
setIsLoading(false); |
|
|
} |
|
|
}, []); |
|
|
|
|
|
return ( |
|
|
<div className="flex flex-col h-full w-full max-w-5xl mx-auto"> |
|
|
<h2 className="text-2xl font-bold text-cyan-300 mb-4 text-center">Cosmic Tarot Reading</h2> |
|
|
<p className="text-gray-400 mb-6 text-center">Draw three cards from the Major Arcana to reveal insights into your past, present, and future path.</p> |
|
|
|
|
|
<div className="text-center mb-6"> |
|
|
<button |
|
|
onClick={handleDraw} |
|
|
disabled={isLoading} |
|
|
className="bg-purple-600 hover:bg-purple-500 text-white font-bold py-3 px-8 rounded-md disabled:bg-gray-500 transition-colors shadow-lg shadow-purple-500/20" |
|
|
> |
|
|
{isLoading ? 'Consulting the Stars...' : 'Draw Cards'} |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
{cards.length > 0 && ( |
|
|
<div className="grid grid-cols-1 sm:grid-cols-3 gap-6 mb-8"> |
|
|
{cards.map((card, index) => ( |
|
|
<div key={index} className="flex flex-col items-center p-4 border border-purple-500/30 bg-gray-800/50 rounded-lg"> |
|
|
<p className="text-sm text-gray-400 mb-2">{['Past', 'Present', 'Future'][index]}</p> |
|
|
<h3 className="text-lg font-bold text-purple-300">{card}</h3> |
|
|
</div> |
|
|
))} |
|
|
</div> |
|
|
)} |
|
|
|
|
|
<div className="flex-grow overflow-y-auto p-4 bg-gray-800/50 rounded-lg border border-cyan-500/10 min-h-[40vh]"> |
|
|
{isLoading && <Spinner text="Interpreting the celestial signs..." />} |
|
|
{error && <p className="text-red-400 text-center">{error}</p>} |
|
|
{interpretation && <MarkdownRenderer content={interpretation} />} |
|
|
{!isLoading && !interpretation && !error && <p className="text-gray-500 text-center">Your reading will appear here.</p>} |
|
|
</div> |
|
|
</div> |
|
|
); |
|
|
}; |
|
|
|
|
|
export default TarotModule; |
|
|
|