Files
cruciverba_1/webapp/components/use-crossword-data.ts

62 lines
1.5 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { getMockCrosswordResponse } from "@/lib/mock-crossword";
import type { Locale } from "@/lib/i18n";
import type { CrosswordResponse } from "@/lib/types";
type UseCrosswordDataResult = {
crossword: CrosswordResponse | null;
errorMessage: string;
isLoading: boolean;
};
export function useCrosswordData(id: string, locale: Locale): UseCrosswordDataResult {
const [crossword, setCrossword] = useState<CrosswordResponse | null>(
id === "demo-transport" ? getMockCrosswordResponse(locale) : null,
);
const [errorMessage, setErrorMessage] = useState("");
const [isLoading, setIsLoading] = useState(id !== "demo-transport");
useEffect(() => {
if (id === "demo-transport") {
setIsLoading(false);
return;
}
let cancelled = false;
setIsLoading(true);
setErrorMessage("");
fetch(`/api/crosswords/${id}`)
.then(async (response) => {
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return response.json();
})
.then((payload: CrosswordResponse) => {
if (!cancelled) {
setCrossword(payload);
setIsLoading(false);
}
})
.catch((error) => {
if (!cancelled) {
setErrorMessage(error instanceof Error ? error.message : "Unexpected error");
setIsLoading(false);
}
});
return () => {
cancelled = true;
};
}, [id, locale]);
return {
crossword,
errorMessage,
isLoading,
};
}