mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 18:52:56 +00:00
upload
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Box,
|
||||
VStack,
|
||||
Heading,
|
||||
Spinner,
|
||||
Text,
|
||||
useColorModeValue,
|
||||
} from '@chakra-ui/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getPolls, getPoll } from '../../services/polls';
|
||||
import PollCard from './PollCard';
|
||||
|
||||
interface EmbeddedPollProps {
|
||||
articleId?: number;
|
||||
eventId?: number;
|
||||
videoUrl?: string;
|
||||
title?: string;
|
||||
showTitle?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* EmbeddedPoll component - displays polls related to specific content
|
||||
* Use in article pages, event pages, or video pages
|
||||
*/
|
||||
const EmbeddedPoll: React.FC<EmbeddedPollProps> = ({
|
||||
articleId,
|
||||
eventId,
|
||||
videoUrl,
|
||||
title = 'Hlasování',
|
||||
showTitle = true,
|
||||
}) => {
|
||||
const bgSection = useColorModeValue('gray.50', 'gray.900');
|
||||
|
||||
// Build query params based on what's provided
|
||||
const queryParams: any = {};
|
||||
if (articleId) queryParams.article_id = articleId;
|
||||
if (eventId) queryParams.event_id = eventId;
|
||||
if (videoUrl) queryParams.video_url = videoUrl;
|
||||
|
||||
// Fetch polls related to this content
|
||||
const { data: polls, isLoading } = useQuery({
|
||||
queryKey: ['embedded-polls', queryParams],
|
||||
queryFn: () => getPolls(queryParams),
|
||||
enabled: !!(articleId || eventId || videoUrl), // Only fetch if at least one param is provided
|
||||
staleTime: 2 * 60 * 1000,
|
||||
});
|
||||
|
||||
// Get full poll data for each
|
||||
const pollsToDisplay = polls?.slice(0, 3) || []; // Max 3 polls per content
|
||||
|
||||
const { data: pollsData, isLoading: isLoadingPolls } = useQuery({
|
||||
queryKey: ['embedded-polls-details', pollsToDisplay.map((p) => p.id)],
|
||||
queryFn: async () => {
|
||||
const promises = pollsToDisplay.map((poll) => getPoll(poll.id));
|
||||
return await Promise.all(promises);
|
||||
},
|
||||
enabled: pollsToDisplay.length > 0,
|
||||
});
|
||||
|
||||
// Don't render anything if no content identifier provided
|
||||
if (!articleId && !eventId && !videoUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Don't render if loading initially
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Box py={4}>
|
||||
<VStack spacing={2}>
|
||||
<Spinner size="sm" />
|
||||
<Text fontSize="sm" color="gray.500">
|
||||
Načítání hlasování...
|
||||
</Text>
|
||||
</VStack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// Don't render if no polls found
|
||||
if (!polls || polls.length === 0 || !pollsData || pollsData.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box bg={bgSection} py={8} px={4} borderRadius="xl" my={8}>
|
||||
<VStack spacing={6} maxW="3xl" mx="auto">
|
||||
{showTitle && (
|
||||
<Heading size="md" textAlign="center">
|
||||
{title}
|
||||
</Heading>
|
||||
)}
|
||||
|
||||
<VStack spacing={4} w="full">
|
||||
{isLoadingPolls ? (
|
||||
<VStack py={8}>
|
||||
<Spinner />
|
||||
<Text>Načítání...</Text>
|
||||
</VStack>
|
||||
) : (
|
||||
pollsData.map((pollResponse) => (
|
||||
<Box key={pollResponse.poll.id} w="full">
|
||||
<PollCard
|
||||
poll={pollResponse.poll}
|
||||
hasVoted={pollResponse.has_voted}
|
||||
isActive={pollResponse.is_active}
|
||||
canShowResults={pollResponse.can_show_results}
|
||||
/>
|
||||
</Box>
|
||||
))
|
||||
)}
|
||||
</VStack>
|
||||
</VStack>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmbeddedPoll;
|
||||
Reference in New Issue
Block a user