Files
djledda-web/app/generative-energy/GEDeutschArticle.tsx
Daniel Ledda bcb820f35e nice
2024-10-31 23:46:23 +01:00

76 lines
2.8 KiB
TypeScript

import { h, inject, defineComponent, ref, createTextVNode, type VNode } from 'vue';
import { RouterLink } from 'vue-router';
import useAsyncState from "@/useAsyncState.ts";
export default defineComponent({
name: 'ge-deutsch-article',
props: {
articleName: {
type: String,
required: true,
},
},
async setup(props) {
const currentLang = ref<"en" | "de">("de");
function clickBtn() {
currentLang.value = currentLang.value === "en" ? "de" : "en";
}
const parseDom = inject('dom-parse', (innerHTML: string) => Object.assign(document.createElement('div'), { innerHTML }));
const { result: articleContent, stateIsReady } = useAsyncState('ge-deutsch-article-data', async ({ hostUrl }) => {
const articleResponse = await fetch(`${ hostUrl }/generative-energy/static/content/${ props.articleName }.html`);
return await articleResponse.text();
});
function transformArticleNode(node: Node): VNode | string {
if (node.nodeType === node.ELEMENT_NODE) {
const el = node as Element;
const attrs: Record<string, string> = {};
const children = [...node.childNodes].map(_ => transformArticleNode(_));
if (el.tagName === 'P') {
el.classList.add('text-slab');
children.unshift(h('button', { class: 'swap', onClick: (e) => {
e.target.parentElement.classList.toggle('swap');
} }, '↻'));
}
for (let i = 0; i < el.attributes.length; i++) {
const item = el.attributes.item(i);
if (item) {
attrs[item.name] = item.value;
}
}
return h((node as Element).tagName, attrs, children);
} else {
return createTextVNode(node.textContent ?? '');
}
}
function ArticleContentTransformed() {
if (articleContent.value) {
const dom = parseDom(articleContent.value);
return h('div', {}, [...dom.children].map(_ => transformArticleNode(_)));
}
return <div>Artikel lädt...</div>;
}
await stateIsReady;
return () => <div class="ge-article">
<div class="header">
<RouterLink to={{ name: 'GEDeutsch' }}>Zur Artikelübersicht</RouterLink>
<button onClick={clickBtn}>
Sprache auf <span>{currentLang.value === "en" ? "Deutsch" : "Englisch"}</span> umschalten
</button>
</div>
<article class={`lang-${ currentLang.value }`}>
<ArticleContentTransformed />
</article>
</div>;
}
});