REFACTOR: Correct loading handling in `AllCategoriesPage`; REFACTOR: Update to `ResultsPage`
102 lines
2.9 KiB
TypeScript
102 lines
2.9 KiB
TypeScript
import React, { useEffect, useState, useRef } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import ListRow from "../components/Layout/ListRow";
|
|
import DynamicPageContent from "../components/Layout/DynamicPageContent";
|
|
import { fetchContentOnScroll } from "../hooks/fetchContentOnScroll";
|
|
import LoadingScreen from "../components/Layout/LoadingScreen";
|
|
|
|
interface CategoryData {
|
|
type: "category";
|
|
id: number;
|
|
title: string;
|
|
viewers: number;
|
|
thumbnail: string;
|
|
}
|
|
const AllCategoriesPage: React.FC = () => {
|
|
const [categories, setCategories] = useState<CategoryData[]>([]);
|
|
const navigate = useNavigate();
|
|
const [categoryOffset, setCategoryOffset] = useState(0);
|
|
const [noCategories, setNoCategories] = useState(12);
|
|
const [hasMoreData, setHasMoreData] = useState(true);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const listRowRef = useRef<any>(null);
|
|
|
|
const fetchCategories = async () => {
|
|
if (isLoading) return;
|
|
|
|
try {
|
|
const response = await fetch(
|
|
`/api/categories/popular/${noCategories}/${categoryOffset}`
|
|
);
|
|
if (!response.ok) {
|
|
throw new Error("Failed to fetch categories");
|
|
}
|
|
const data = await response.json();
|
|
|
|
if (data.length === 0) {
|
|
setHasMoreData(false);
|
|
return [];
|
|
}
|
|
|
|
setCategoryOffset((prev) => prev + data.length);
|
|
|
|
const processedCategories = data.map((category: any) => ({
|
|
type: "category" as const,
|
|
id: category.category_id,
|
|
title: category.category_name,
|
|
viewers: category.num_viewers,
|
|
thumbnail: `/images/category_thumbnails/${category.category_name
|
|
.toLowerCase()
|
|
.replace(/ /g, "_")}.webp`,
|
|
}));
|
|
|
|
setCategories((prev) => [...prev, ...processedCategories]);
|
|
return processedCategories;
|
|
} catch (error) {
|
|
console.error("Error fetching categories:", error);
|
|
return [];
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchCategories();
|
|
}, []);
|
|
|
|
const loadOnScroll = async () => {
|
|
if (hasMoreData && listRowRef.current) {
|
|
const newCategories = await fetchCategories();
|
|
if (newCategories?.length > 0) {
|
|
listRowRef.current.addMoreItems(newCategories);
|
|
}
|
|
}
|
|
};
|
|
|
|
fetchContentOnScroll(loadOnScroll, hasMoreData);
|
|
|
|
if (hasMoreData && !categories.length) return <LoadingScreen />;
|
|
|
|
const handleCategoryClick = (categoryName: string) => {
|
|
console.log(categoryName);
|
|
navigate(`/category/${categoryName}`);
|
|
};
|
|
|
|
return (
|
|
<DynamicPageContent className="min-h-screen">
|
|
<ListRow
|
|
ref={listRowRef}
|
|
type="category"
|
|
title="All Categories"
|
|
items={categories}
|
|
onItemClick={handleCategoryClick}
|
|
extraClasses="bg-[var(--recommend)] text-center"
|
|
itemExtraClasses="w-[20vw]"
|
|
wrap={true}
|
|
/>
|
|
</DynamicPageContent>
|
|
);
|
|
};
|
|
|
|
export default AllCategoriesPage;
|