MediaContextHandle

Ручка для взаимодействия с медиа контентом
This commit is contained in:
degradin 2025-05-07 13:34:54 +03:00
parent c760b48719
commit 068794b4a6

View File

@ -1,117 +1,90 @@
import { createContext, useContext, useState, useCallback } from "react";
import {
getTrendingMedia,
getMediaById,
searchMedia,
} from "../services/mediaService";
import React, { createContext, useContext, useState } from 'react';
import { searchMedia, getMediaDetails, validateMediaData, formatMediaData } from '../services/mediaService';
import { createMedia } from '../services/supabase';
const MediaContext = createContext();
export function useMedia() {
export const useMedia = () => {
const context = useContext(MediaContext);
if (!context) {
throw new Error("useMedia must be used within a MediaProvider");
throw new Error('useMedia must be used within a MediaProvider');
}
return context;
}
};
export function MediaProvider({ children }) {
const [trendingMovies, setTrendingMovies] = useState([]);
const [trendingTvShows, setTrendingTvShows] = useState([]);
const [trendingGames, setTrendingGames] = useState([]);
const [currentMedia, setCurrentMedia] = useState(null);
export const MediaProvider = ({ children }) => {
const [searchResults, setSearchResults] = useState([]);
const [selectedMedia, setSelectedMedia] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [searchResults, setSearchResults] = useState([]);
const fetchTrendingMedia = useCallback(async () => {
setLoading(true);
setError(null);
const handleSearch = async (query, type = 'movie') => {
try {
const [movies, tvShows, games] = await Promise.all([
getTrendingMedia("movie"),
getTrendingMedia("tv"),
getTrendingMedia("game"),
]);
setTrendingMovies(movies || []);
setTrendingTvShows(tvShows || []);
setTrendingGames(games || []);
} catch (err) {
setError(err.message || "Failed to fetch trending media");
console.error("Fetch trending error:", err);
// Сброс состояний на случай частичного успеха
setTrendingMovies([]);
setTrendingTvShows([]);
setTrendingGames([]);
setLoading(true);
setError(null);
const results = await searchMedia(query, type);
setSearchResults(results);
} catch (error) {
console.error('Search error:', error);
setError('Ошибка при поиске медиа');
} finally {
setLoading(false);
}
}, []);
const fetchMediaDetails = useCallback(async (id) => {
if (!id) {
setError("Invalid media ID");
return;
}
setLoading(true);
setError(null);
setCurrentMedia(null);
};
const handleSelectMedia = async (tmdbId, type) => {
try {
const data = await getMediaById(id);
if (!data) {
throw new Error("Media not found");
setLoading(true);
setError(null);
const details = await getMediaDetails(tmdbId, type);
setSelectedMedia(details);
} catch (error) {
console.error('Error fetching media details:', error);
setError('Ошибка при получении деталей медиа');
} finally {
setLoading(false);
}
};
const handleCreateMedia = async (mediaData) => {
try {
setLoading(true);
setError(null);
// Валидация данных
const errors = validateMediaData(mediaData);
if (errors.length > 0) {
throw new Error(errors.join('\n'));
}
setCurrentMedia(data);
} catch (err) {
setError(err.message || "Failed to fetch media details");
console.error("Fetch details error:", err);
// Форматирование данных
const formattedData = formatMediaData(mediaData);
// Создание медиа
const newMedia = await createMedia(formattedData);
return newMedia;
} catch (error) {
console.error('Error creating media:', error);
setError(error.message || 'Ошибка при создании медиа');
throw error;
} finally {
setLoading(false);
}
}, []);
const handleSearch = useCallback(async (query) => {
if (!query || !query.trim()) {
setSearchResults([]);
return;
}
setLoading(true);
setError(null);
try {
const results = await searchMedia(query);
setSearchResults(Array.isArray(results) ? results : []);
} catch (err) {
setError(err.message || "Search failed");
console.error("Search error:", err);
setSearchResults([]);
} finally {
setLoading(false);
}
}, []);
};
const value = {
trendingMovies,
trendingTvShows,
trendingGames,
currentMedia,
searchResults,
selectedMedia,
loading,
error,
searchResults,
fetchTrendingMedia,
fetchMediaDetails,
handleSearch,
clearError: () => setError(null),
clearCurrentMedia: () => setCurrentMedia(null),
clearSearchResults: () => setSearchResults([]),
handleSelectMedia,
handleCreateMedia
};
return (
<MediaContext.Provider value={value}>{children}</MediaContext.Provider>
<MediaContext.Provider value={value}>
{children}
</MediaContext.Provider>
);
}
};