UPDATE/REFACTOR: Replace ContentContext with useContent hook;

REFACTOR: Add content type files;
This commit is contained in:
Chris-1010
2025-02-27 01:20:40 +00:00
parent 3f95b35acc
commit 74baa49c04
9 changed files with 178 additions and 158 deletions

View File

@@ -0,0 +1,140 @@
// hooks/useContent.ts
import { useState, useEffect } from "react";
import { useAuth } from "../context/AuthContext";
import { StreamType } from "../types/StreamType";
import { CategoryType } from "../types/CategoryType";
import { UserType } from "../types/UserType";
// Helper function to process API data into our consistent types
const processStreamData = (data: any[]): StreamType[] => {
return data.map((stream) => ({
type: "stream",
id: stream.user_id,
title: stream.title,
username: stream.username,
streamCategory: stream.category_name,
viewers: stream.num_viewers,
thumbnail:
stream.thumbnail ||
`/images/category_thumbnails/${stream.category_name
.toLowerCase()
.replace(/ /g, "_")}.webp`,
}));
};
const processCategoryData = (data: any[]): CategoryType[] => {
return data.map((category) => ({
type: "category",
id: category.category_id,
title: category.category_name,
viewers: category.num_viewers,
thumbnail: `/images/category_thumbnails/${category.category_name
.toLowerCase()
.replace(/ /g, "_")}.webp`,
}));
};
const processUserData = (data: any[]): UserType[] => {
return data.map((user) => ({
type: "user",
id: user.user_id,
title: user.username,
username: user.username,
isLive: user.is_live,
viewers: 0, // This may need to be updated based on your API
thumbnail: user.thumbnail || "/images/pfps/default.webp",
}));
};
// Generic fetch hook that can be used for any content type
export function useFetchContent<T>(
url: string,
processor: (data: any[]) => T[],
dependencies: any[] = []
): { data: T[]; isLoading: boolean; error: string | null } {
const [data, setData] = useState<T[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Error fetching data: ${response.status}`);
}
const rawData = await response.json();
const processedData = processor(rawData);
setData(processedData);
setError(null);
} catch (err) {
console.error("Error fetching content:", err);
setError(err instanceof Error ? err.message : "Unknown error");
} finally {
setIsLoading(false);
}
};
fetchData();
}, dependencies);
return { data, isLoading, error };
}
// Specific hooks for each content type
export function useStreams(customUrl?: string): {
streams: StreamType[];
isLoading: boolean;
error: string | null
} {
const { isLoggedIn } = useAuth();
const url = customUrl || (isLoggedIn
? "/api/streams/recommended"
: "/api/streams/popular/4");
const { data, isLoading, error } = useFetchContent<StreamType>(
url,
processStreamData,
[isLoggedIn, customUrl]
);
return { streams: data, isLoading, error };
}
export function useCategories(customUrl?: string): {
categories: CategoryType[];
isLoading: boolean;
error: string | null
} {
const { isLoggedIn } = useAuth();
const url = customUrl || (isLoggedIn
? "/api/categories/recommended"
: "/api/categories/popular/4");
const { data, isLoading, error } = useFetchContent<CategoryType>(
url,
processCategoryData,
[isLoggedIn, customUrl]
);
return { categories: data, isLoading, error };
}
export function useUsers(customUrl?: string): {
users: UserType[];
isLoading: boolean;
error: string | null
} {
const url = customUrl || "/api/users/popular";
const { data, isLoading, error } = useFetchContent<UserType>(
url,
processUserData,
[customUrl]
);
return { users: data, isLoading, error };
}