mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-05 03:02:56 +00:00
upload
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
import { Box, Text, VStack, HStack, Image, Skeleton, Link as ChakraLink, Icon } from '@chakra-ui/react';
|
||||
import { FaNewspaper, FaUser, FaCalendarAlt } from 'react-icons/fa';
|
||||
import { Link as RouterLink } from 'react-router-dom';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { api } from '../../services/api';
|
||||
import { Widget } from './Widget';
|
||||
import { format, parseISO } from 'date-fns';
|
||||
import { cs } from 'date-fns/locale';
|
||||
import { Article } from '../../types';
|
||||
|
||||
export const ArticlesWidget = () => {
|
||||
const { data: articles = [], isLoading, error } = useQuery<Article[]>({
|
||||
queryKey: ['recentArticles'],
|
||||
queryFn: async () => {
|
||||
try {
|
||||
const { data } = await api.get('/articles', {
|
||||
params: {
|
||||
limit: 3,
|
||||
include: 'author',
|
||||
sort: '-createdAt',
|
||||
published: true
|
||||
}
|
||||
});
|
||||
return data.data || [];
|
||||
} catch (err) {
|
||||
console.error('Error fetching articles:', err);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
staleTime: 5 * 60 * 1000, // 5 minutes
|
||||
});
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Widget title="Poslední články" icon={FaNewspaper}>
|
||||
<VStack spacing={4} align="stretch">
|
||||
{[1, 2, 3].map((i) => (
|
||||
<Box key={i}>
|
||||
<Skeleton height="120px" mb={2} borderRadius="md" />
|
||||
<Skeleton height="20px" mb={2} width="80%" />
|
||||
<Skeleton height="16px" width="60%" />
|
||||
</Box>
|
||||
))}
|
||||
</VStack>
|
||||
</Widget>
|
||||
);
|
||||
}
|
||||
|
||||
if (error || !articles.length) {
|
||||
return (
|
||||
<Widget title="Poslední články" icon={FaNewspaper}>
|
||||
<VStack p={4} spacing={4}>
|
||||
<Box p={4} bg="gray.50" borderRadius="md" textAlign="center" w="full">
|
||||
<Icon as={FaNewspaper} boxSize={6} color="gray.400" mb={2} />
|
||||
<Text color="gray.500">Žádné články nebyly nalezeny</Text>
|
||||
</Box>
|
||||
</VStack>
|
||||
</Widget>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Widget title="Poslední články" icon={FaNewspaper}>
|
||||
<VStack spacing={3} align="stretch" divider={<Box borderBottomWidth="1px" borderColor="gray.100" />}>
|
||||
{articles.map((article) => (
|
||||
<ChakraLink
|
||||
key={article.id}
|
||||
as={RouterLink}
|
||||
to={`/clanky/${article.slug}`}
|
||||
_hover={{ textDecoration: 'none' }}
|
||||
display="block"
|
||||
>
|
||||
<Box _hover={{ bg: 'gray.50' }} borderRadius="md" p={2}>
|
||||
<HStack align="flex-start" spacing={3}>
|
||||
<Box
|
||||
flexShrink={0}
|
||||
width="60px"
|
||||
height="60px"
|
||||
bg="gray.100"
|
||||
borderRadius="md"
|
||||
overflow="hidden"
|
||||
position="relative"
|
||||
>
|
||||
{article.imageUrl ? (
|
||||
<Image
|
||||
src={article.imageUrl}
|
||||
alt={article.title}
|
||||
width="100%"
|
||||
height="100%"
|
||||
objectFit="cover"
|
||||
/>
|
||||
) : (
|
||||
<Box
|
||||
width="100%"
|
||||
height="100%"
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
bg="gray.200"
|
||||
>
|
||||
<Icon as={FaNewspaper} color="gray.400" boxSize={5} />
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
<Box flex={1} minW={0}>
|
||||
<Text fontWeight="medium" fontSize="sm" noOfLines={2} mb={1}>
|
||||
{article.title}
|
||||
</Text>
|
||||
<HStack spacing={3} fontSize="xs" color="gray.500">
|
||||
<HStack spacing={1}>
|
||||
<Icon as={FaUser} boxSize={3} />
|
||||
<Text>{article.author.name}</Text>
|
||||
</HStack>
|
||||
<HStack spacing={1}>
|
||||
<Icon as={FaCalendarAlt} boxSize={3} />
|
||||
<Text>
|
||||
{format(parseISO(article.createdAt), 'd. M. yyyy', {
|
||||
locale: cs,
|
||||
})}
|
||||
</Text>
|
||||
</HStack>
|
||||
</HStack>
|
||||
</Box>
|
||||
</HStack>
|
||||
</Box>
|
||||
</ChakraLink>
|
||||
))}
|
||||
<Box textAlign="right" mt={2}>
|
||||
<ChakraLink
|
||||
as={RouterLink}
|
||||
to="/admin/clanky"
|
||||
color="blue.500"
|
||||
fontWeight="medium"
|
||||
fontSize="sm"
|
||||
_hover={{ textDecoration: 'underline' }}
|
||||
>
|
||||
Zobrazit všechny články →
|
||||
</ChakraLink>
|
||||
</Box>
|
||||
</VStack>
|
||||
</Widget>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user