Update package dependencies, enhance README for clarity, and implement new features in the admin panel and script detail pages. Added support for collections, improved script submission previews, and refactored comment handling in the script detail view.

This commit is contained in:
2025-08-15 20:29:02 +01:00
parent 5fdfe3e790
commit ef211ebe0a
27 changed files with 3457 additions and 353 deletions

88
src/hooks/useRatings.ts Normal file
View File

@ -0,0 +1,88 @@
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import * as ratingsApi from '@/lib/api/ratings';
import { showSuccess, showError } from '@/utils/toast';
// Query keys
export const ratingKeys = {
all: ['ratings'] as const,
script: (scriptId: string) => [...ratingKeys.all, 'script', scriptId] as const,
userRating: (scriptId: string, userId: string) => [...ratingKeys.all, 'user', scriptId, userId] as const,
stats: (scriptId: string) => [...ratingKeys.all, 'stats', scriptId] as const,
};
// Get user's rating for a script
export function useUserRating(scriptId: string, userId?: string) {
return useQuery({
queryKey: ratingKeys.userRating(scriptId, userId || ''),
queryFn: () => ratingsApi.getUserRating(scriptId, userId!),
enabled: !!scriptId && !!userId,
staleTime: 5 * 60 * 1000,
});
}
// Get all ratings for a script
export function useScriptRatings(scriptId: string) {
return useQuery({
queryKey: ratingKeys.script(scriptId),
queryFn: () => ratingsApi.getScriptRatings(scriptId),
enabled: !!scriptId,
staleTime: 5 * 60 * 1000,
});
}
// Get rating statistics for a script
export function useScriptRatingStats(scriptId: string) {
return useQuery({
queryKey: ratingKeys.stats(scriptId),
queryFn: () => ratingsApi.getScriptRatingStats(scriptId),
enabled: !!scriptId,
staleTime: 10 * 60 * 1000,
});
}
// Rate script mutation
export function useRateScript() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ratingsApi.rateScript,
onSuccess: (_, variables) => {
// Invalidate related queries
queryClient.invalidateQueries({ queryKey: ratingKeys.script(variables.scriptId) });
queryClient.invalidateQueries({ queryKey: ratingKeys.userRating(variables.scriptId, variables.userId) });
queryClient.invalidateQueries({ queryKey: ratingKeys.stats(variables.scriptId) });
// Also invalidate script details to update average rating
queryClient.invalidateQueries({ queryKey: ['scripts', 'detail', variables.scriptId] });
showSuccess('Rating submitted successfully!');
},
onError: (error: any) => {
showError(error.message || 'Failed to submit rating');
},
});
}
// Delete rating mutation
export function useDeleteRating() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ scriptId, userId }: { scriptId: string; userId: string }) =>
ratingsApi.deleteRating(scriptId, userId),
onSuccess: (_, variables) => {
// Invalidate related queries
queryClient.invalidateQueries({ queryKey: ratingKeys.script(variables.scriptId) });
queryClient.invalidateQueries({ queryKey: ratingKeys.userRating(variables.scriptId, variables.userId) });
queryClient.invalidateQueries({ queryKey: ratingKeys.stats(variables.scriptId) });
// Also invalidate script details to update average rating
queryClient.invalidateQueries({ queryKey: ['scripts', 'detail', variables.scriptId] });
showSuccess('Rating removed successfully!');
},
onError: (error: any) => {
showError(error.message || 'Failed to remove rating');
},
});
}