| import { useState, useCallback } from 'react'; | |
| const useCrossword = () => { | |
| const [puzzle, setPuzzle] = useState(null); | |
| const [loading, setLoading] = useState(false); | |
| const [error, setError] = useState(null); | |
| const [topics, setTopics] = useState([]); | |
| const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || (import.meta.env.PROD ? '' : 'http://localhost:3000'); | |
| const fetchTopics = useCallback(async () => { | |
| try { | |
| setLoading(true); | |
| const response = await fetch(`${API_BASE_URL}/api/topics`); | |
| if (!response.ok) throw new Error('Failed to fetch topics'); | |
| const data = await response.json(); | |
| setTopics(data); | |
| } catch (err) { | |
| setError(err.message); | |
| } finally { | |
| setLoading(false); | |
| } | |
| }, [API_BASE_URL]); | |
| const generatePuzzle = useCallback(async (selectedTopics, difficulty = 'medium', useAI = false, customSentence = '', multiTheme = true, advancedParams = {}) => { | |
| try { | |
| setLoading(true); | |
| setError(null); | |
| const response = await fetch(`${API_BASE_URL}/api/generate`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| topics: selectedTopics, | |
| difficulty, | |
| useAI, | |
| ...(customSentence && { customSentence }), | |
| multiTheme, | |
| ...(advancedParams.similarityTemperature !== undefined && { | |
| similarityTemperature: advancedParams.similarityTemperature | |
| }), | |
| ...(advancedParams.difficultyWeight !== undefined && { | |
| difficultyWeight: advancedParams.difficultyWeight | |
| }) | |
| }) | |
| }); | |
| if (!response.ok) { | |
| const errorData = await response.json().catch(() => ({})); | |
| throw new Error(errorData.message || 'Failed to generate puzzle'); | |
| } | |
| const puzzleData = await response.json(); | |
| setPuzzle(puzzleData); | |
| return puzzleData; | |
| } catch (err) { | |
| setError(err.message); | |
| return null; | |
| } finally { | |
| setLoading(false); | |
| } | |
| }, [API_BASE_URL]); | |
| const validateAnswers = useCallback(async (userAnswers) => { | |
| try { | |
| const response = await fetch(`${API_BASE_URL}/api/validate`, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| puzzle: puzzle, | |
| answers: userAnswers | |
| }) | |
| }); | |
| if (!response.ok) throw new Error('Failed to validate answers'); | |
| return await response.json(); | |
| } catch (err) { | |
| setError(err.message); | |
| return null; | |
| } | |
| }, [API_BASE_URL, puzzle]); | |
| const resetPuzzle = useCallback(() => { | |
| setPuzzle(null); | |
| setError(null); | |
| }, []); | |
| return { | |
| puzzle, | |
| loading, | |
| error, | |
| topics, | |
| fetchTopics, | |
| generatePuzzle, | |
| validateAnswers, | |
| resetPuzzle | |
| }; | |
| }; | |
| export default useCrossword; |