62 lines
1.5 KiB
TypeScript
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,
|
|
};
|
|
}
|