Skip to content

Commit

Permalink
Merge pull request #148 from ConductionNL/feature/XW-103/Markdown-page
Browse files Browse the repository at this point in the history
feature/XW-103/Markdown-page
  • Loading branch information
remko48 authored Nov 1, 2023
2 parents 143a5fc + a72eeb2 commit dc2d0bb
Show file tree
Hide file tree
Showing 37 changed files with 834 additions and 10 deletions.
33 changes: 32 additions & 1 deletion pwa/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion pwa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@
"react-loading-skeleton": "^3.1.0",
"react-paginate": "^8.1.4",
"react-query": "^3.34.19",
"react-select": "^5.3.2"
"react-select": "^5.3.2",
"showdown": "^2.1.0"
},
"devDependencies": {
"@types/dateformat": "^5.0.0",
Expand All @@ -96,6 +97,7 @@
"@types/react-helmet": "^6.1.5",
"@typescript-eslint/eslint-plugin": "^5.55.0",
"@typescript-eslint/parser": "^5.55.0",
"@types/showdown": "2.0.3",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-react": "^7.32.2",
Expand Down
15 changes: 15 additions & 0 deletions pwa/src/apiService/apiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DEFAULT_FOOTER_CONTENT_URL } from "../templates/templateParts/footer/Fo
// Resources
import OpenWoo from "./resources/openWoo";
import FooterContent from "./resources/footerContent";
import Markdown from "./resources/markdown";

interface PromiseMessage {
loading?: string;
Expand Down Expand Up @@ -41,13 +42,27 @@ export default class APIService {
});
}

public get MarkdownClient(): AxiosInstance {
return axios.create({
baseURL: process.env.GATSBY_BASE_URL ?? undefined,
headers: {
Accept: "application/vnd.github.html",
},
});
}

public get OpenWoo(): OpenWoo {
return new OpenWoo(this.BaseClient, this.Send);
}

public get FooterContent(): FooterContent {
return new FooterContent(this.FooterContentClient, this.Send);
}

public get Markdown(): Markdown {
return new Markdown(this.MarkdownClient, this.Send);
}

// Send method
public Send: TSendFunction = (instance, method, endpoint, payload, promiseMessage) => {
const _payload = JSON.stringify(payload);
Expand Down
17 changes: 17 additions & 0 deletions pwa/src/apiService/resources/markdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { TSendFunction } from "../apiService";
import { AxiosInstance } from "axios";

export default class Markdown {
private _instance: AxiosInstance;
private _send: TSendFunction;
constructor(_instance: AxiosInstance, send: TSendFunction) {
this._instance = _instance;
this._send = send;
}

public getContent = async (filePath: string): Promise<any> => {
const { data } = await this._send(this._instance, "GET", filePath);

return data;
};
}
17 changes: 17 additions & 0 deletions pwa/src/components/ParsedHTML/ParsedHTML.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.container {
margin-block-start: var(--utrecht-space-block-3xl);
}

.container > div > article > *:not(:last-child),
.backLink {
margin-block-end: var(--utrecht-space-block-lg);
}

.backLink:hover {
cursor: pointer;
}

.backLink {
display: flex;
align-items: center;
}
85 changes: 85 additions & 0 deletions pwa/src/components/ParsedHTML/ParsedHTML.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import * as React from "react";
import * as styles from "./ParsedHTML.module.css";
import Parser from "html-react-parser";
import Skeleton from "react-loading-skeleton";
import clsx from "clsx";
import showdown from "showdown";
import { Alert } from "@utrecht/component-library-react/dist/css-module";
import { UseQueryResult } from "react-query";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faArrowLeft, faWarning } from "@fortawesome/free-solid-svg-icons";
import { useHtmlParser } from "../../hooks/htmlParser/useHtmlParser";
import { isHtml } from "../../services/isHtml";
import { Link } from "@utrecht/component-library-react/dist/css-module";
import { navigate } from "gatsby";
import { useTranslation } from "react-i18next";

interface ParsedHTMLProps {
contentQuery: UseQueryResult<any, Error>;
location: string;
layoutClassName?: string;
}

export const ParsedHTML: React.FC<ParsedHTMLProps> = ({ contentQuery, location, layoutClassName }) => {
const { t } = useTranslation();
const { options } = useHtmlParser(location);
let htmlContent;

showdown.setFlavor("github");

if (!isHtml(contentQuery.data)) {
const converter = new showdown.Converter();
htmlContent = `<div><article class="markdown-body entry-content container-lg" itemprop="text">${converter.makeHtml(
contentQuery.data,
)}</article></div>`;
}
if (isHtml(contentQuery.data)) {
htmlContent = contentQuery.data;
}

if (contentQuery.isLoading)
return (
<div className={styles.container}>
<Skeleton height="200px" />
</div>
);

if (contentQuery.isError)
return (
<div className={styles.container}>
<div>
<Link
className={styles.backLink}
href="/"
onClick={(e: any) => {
e.preventDefault(), navigate("/");
}}
tabIndex={0}
>
<FontAwesomeIcon icon={faArrowLeft} /> <span>{t("Back to homepage")}</span>
</Link>
</div>
<Alert icon={<FontAwesomeIcon icon={faWarning} />} type="error">
Oops, something went wrong retrieving the .md file from GitHub.
</Alert>
</div>
);

return (
<div className={clsx(styles.container, layoutClassName && layoutClassName)}>
<div>
<Link
className={styles.backLink}
href="/"
onClick={(e: any) => {
e.preventDefault(), navigate("/");
}}
tabIndex={0}
>
<FontAwesomeIcon icon={faArrowLeft} /> <span>{t("Back to homepage")}</span>
</Link>
</div>
{Parser(htmlContent, options)}
</div>
);
};
28 changes: 28 additions & 0 deletions pwa/src/hooks/htmlParser/alert/getAlert.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.info svg {
fill: var(--utrecht-alert-icon-info-color);
}
.info p {
color: var(--utrecht-alert-info-color);
}

.warning svg {
fill: var(--utrecht-alert-icon-warning-color);
}
.warning p {
color: var(--utrecht-alert-warning-color);
}

.error svg {
fill: var(--utrecht-alert-icon-error-color);
}
.error p {
color: var(--utrecht-alert-error-color);
}

.ok svg {
fill: var(--utrecht-alert-icon-ok-color);
}
.ok p {
color: var(--utrecht-alert-ok-color);
}

34 changes: 34 additions & 0 deletions pwa/src/hooks/htmlParser/alert/getAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as styles from "./getAlert.module.css";
import { Alert } from "@utrecht/component-library-react/dist/css-module";
import { domToReact } from "html-react-parser";

export const getAlert = (children: any, options: any, type: any) => {
switch (true) {
case type.includes("note") || type.includes("info"):
return (
<Alert className={styles.info} type="info">
{domToReact(children, options)}
</Alert>
);
case type.includes("error"):
return (
<Alert className={styles.error} type="error">
{domToReact(children, options)}
</Alert>
);
case type.includes("warning"):
return (
<Alert className={styles.warning} type="warning">
{domToReact(children, options)}
</Alert>
);
case type.includes("succes") || type.includes("ok"):
return (
<Alert className={styles.ok} type="ok">
{domToReact(children, options)}
</Alert>
);
default:
return <Alert type="info">{domToReact(children, options)}</Alert>;
}
};
Loading

0 comments on commit dc2d0bb

Please sign in to comment.