mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 02:32:57 +00:00
update
This commit is contained in:
@@ -3,6 +3,7 @@ import { useParams } from 'react-router-dom';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { getProduct, addToCart, EshopProductVariant } from '../services/eshopApi';
|
||||
import { Box, Heading, Text, Image, Badge, HStack, VStack, Button, Select, useToast } from '@chakra-ui/react';
|
||||
import { sanitizeRichHtml } from '../utils/sanitizeHtml';
|
||||
|
||||
const formatPrice = (cents: number, currency: string) => {
|
||||
const value = cents / 100;
|
||||
@@ -20,6 +21,7 @@ const ProductDetailPage: React.FC = () => {
|
||||
enabled: !!slug,
|
||||
});
|
||||
const [variantId, setVariantId] = useState<number | undefined>(undefined);
|
||||
const descriptionHtml = React.useMemo(() => sanitizeRichHtml(data?.description_html), [data?.description_html]);
|
||||
|
||||
if (isLoading) return <Text>Načítání produktu…</Text>;
|
||||
if (isError || !data) return <Text>Produkt nebyl nalezen.</Text>;
|
||||
@@ -76,9 +78,9 @@ const ProductDetailPage: React.FC = () => {
|
||||
<Button colorScheme="blue" onClick={handleAddToCart} maxW="260px">
|
||||
Přidat do košíku
|
||||
</Button>
|
||||
{data.description_html && (
|
||||
{descriptionHtml && (
|
||||
<Box mt={4} fontSize="sm" color="gray.700">
|
||||
<div dangerouslySetInnerHTML={{ __html: data.description_html }} />
|
||||
<div dangerouslySetInnerHTML={{ __html: descriptionHtml }} />
|
||||
</Box>
|
||||
)}
|
||||
</VStack>
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
/// <reference types="react-scripts" />
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
const ADDITIONAL_TAGS = ['iframe'];
|
||||
const ADDITIONAL_ATTRS = ['allow', 'allowfullscreen', 'class', 'rel', 'style', 'target'];
|
||||
|
||||
export function sanitizeRichHtml(html: string | null | undefined): string {
|
||||
const sanitized = DOMPurify.sanitize(html ?? '', {
|
||||
USE_PROFILES: { html: true },
|
||||
ADD_TAGS: ADDITIONAL_TAGS,
|
||||
ADD_ATTR: ADDITIONAL_ATTRS,
|
||||
});
|
||||
|
||||
if (typeof window === 'undefined' || !sanitized) {
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
const template = window.document.createElement('template');
|
||||
template.innerHTML = sanitized;
|
||||
|
||||
template.content.querySelectorAll<HTMLAnchorElement>('a[target="_blank"]').forEach((anchor) => {
|
||||
const rel = new Set((anchor.getAttribute('rel') ?? '').split(/\s+/).filter(Boolean));
|
||||
rel.add('noopener');
|
||||
rel.add('noreferrer');
|
||||
anchor.setAttribute('rel', Array.from(rel).join(' '));
|
||||
});
|
||||
|
||||
return template.innerHTML;
|
||||
}
|
||||
Reference in New Issue
Block a user