File "Article.jsx"
Full Path: /home/fresvfqn/waterdamagerestorationandrepairsmithtown.com/wp-content/plugins/extendify/src/HelpCenter/components/knowledge-base/Article.jsx
File size: 5.34 KB
MIME-type: text/x-java
Charset: utf-8
import apiFetch from '@wordpress/api-fetch';
import { Spinner } from '@wordpress/components';
import { useState, useEffect, useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import parse from 'html-react-parser';
import { useSupportArticle } from '@help-center/hooks/useSupportArticles';
import { useKnowledgeBaseStore } from '@help-center/state/knowledge-base';
export const Article = () => {
const { articles, pushArticle, popArticle, updateTitle } =
useKnowledgeBaseStore();
const [openedErrorUrl, setOpenedErrorUrl] = useState();
const [fetching, setFetching] = useState(false);
const articleRef = useRef();
const slug = articles?.[0]?.slug;
const { data: article, error, loading } = useSupportArticle(slug);
const title = article?.title;
const getArticleRedirect = (url) =>
apiFetch({
path: `/extendify/v1/help-center/get-redirect?path=${url}`,
});
useEffect(() => {
if (!error) return setOpenedErrorUrl(false);
// If there's an error, then open the url once
if (openedErrorUrl) return;
setOpenedErrorUrl(true);
popArticle();
window.open(
`https://wordpress.org/documentation/article/${slug}`,
'_blank',
);
}, [error, slug, openedErrorUrl, popArticle]);
useEffect(() => {
if (!slug || !title) return;
updateTitle(slug, title);
}, [title, updateTitle, slug]);
useEffect(() => {
if (!articleRef.current) return;
const links = articleRef.current?.querySelectorAll('a');
// a small fix to make sure the images fit within the modal
const figures = articleRef.current?.querySelectorAll('figure');
const images = articleRef.current?.querySelectorAll('img');
figures.forEach((figure) => {
figure.classList.add('mx-auto');
figure.classList.add('my-4');
figure.classList.add('block');
figure.classList.add('w-full');
figure.classList.remove('wp-block-image');
});
images.forEach((image) => {
image.classList.add('object-contain');
image.classList.add('max-w-[400px]');
image.classList.add('max-h-[250px]');
});
const handleInternal = async (e) => {
e.preventDefault();
// In that case, event.ctrlKey does the trick.
if (e.ctrlKey || e.metaKey) {
e.stopPropagation();
return window.open(e.target.href, '_blank');
}
// Could be the parent element so check both
const link = e.target?.href ?? e.target?.closest('a')?.href;
const { pathname } = new URL(link);
const slug = pathname.split('/').filter(Boolean)?.at(-1);
// Both the new docs site and the old may have redirects
setFetching(true);
const data = await getArticleRedirect(pathname);
setFetching(false);
if (!data) {
// If nothing useful was returned, it could be the new docs site
if (pathname.startsWith('/documentation/article/')) {
return pushArticle({ slug, title: undefined });
}
// But if not then just open the link in a new tab
return window.open(`https://wordpress.org${pathname}`, '_blank');
}
// Finally load the article
pushArticle({ slug: data.split('/').filter(Boolean)?.at(-1) });
};
const handleExternal = (e) => {
e.preventDefault();
window.open(e.target.href, '_blank');
};
const handleNoOp = (e) => e.preventDefault();
links.forEach((link) => {
const { hash, host, pathname } = new URL(link.href);
// Hash links should be disabled since they don't work properly
if (
(hash && host === window.location.host) ||
pathname.startsWith('/support/category')
) {
link.addEventListener('click', handleNoOp);
link.setAttribute('aria-disabled', 'true');
link.classList.add('link-disabled');
return;
}
// if link is to an image or a file, remove it
const pattern = /\.(jpg|jpeg|png|gif|pdf|doc|docx|xls|xlsx|ppt|pptx)$/;
if (pathname.match(pattern)) {
link.addEventListener('click', handleNoOp);
return;
}
if (
pathname.startsWith('/documentation/article') ||
pathname.startsWith('/support/article')
) {
link.addEventListener('click', handleInternal);
return;
}
// If the link is something else, then open in a new tab
link.addEventListener('click', handleExternal);
const svg =
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" class="components-external-link__icon css-rvs7bx esh4a730" aria-hidden="true" focusable="false"><path d="M18.2 17c0 .7-.6 1.2-1.2 1.2H7c-.7 0-1.2-.6-1.2-1.2V7c0-.7.6-1.2 1.2-1.2h3.2V4.2H7C5.5 4.2 4.2 5.5 4.2 7v10c0 1.5 1.2 2.8 2.8 2.8h10c1.5 0 2.8-1.2 2.8-2.8v-3.6h-1.5V17zM14.9 3v1.5h3.7l-6.4 6.4 1.1 1.1 6.4-6.4v3.7h1.5V3h-6.3z"></path></svg>';
const svgEl = document.createElement('span');
svgEl.innerHTML = svg;
link.appendChild(svgEl);
});
return () => {
links.forEach((link) => {
link?.removeEventListener('click', handleInternal);
link?.removeEventListener('click', handleExternal);
link?.removeEventListener('click', handleNoOp);
});
};
}, [article, pushArticle]);
if (loading || fetching) {
return (
<div className="p-8 text-center text-base">
<Spinner />
</div>
);
}
if (error) {
return (
<div className="p-8 text-center text-base">
{__('There was an error loading this article', 'extendify-local')}
</div>
);
}
return (
<article
ref={articleRef}
className="extendify-documentation w-full"
data-test="kb-article-content">
<h1 className="m-0 text-3xl">{title}</h1>
{article?.content && parse(article?.content)}
</article>
);
};