Merge pull request #15 from Accords-Library/develop

Improved About us section + message when content not available in a language
This commit is contained in:
DrMint 2022-03-20 14:51:52 +01:00 committed by GitHub
commit 00ff7be736
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 713 additions and 134 deletions

View File

@ -3,7 +3,7 @@ module.exports = {
swcMinify: true,
reactStrictMode: true,
i18n: {
locales: ["en", "fr", "ja", "es"],
locales: ["en", "fr", "ja", "es", "pt-br"],
defaultLocale: "en",
},
images: {

View File

@ -1,7 +1,4 @@
import {
GetWebsiteInterfaceQuery,
StrapiImage,
} from "graphql/operations-types";
import { StrapiImage } from "graphql/operations-types";
import MainPanel from "./Panels/MainPanel";
import Head from "next/head";
import { useSwipeable } from "react-swipeable";

View File

@ -0,0 +1,40 @@
import {
GetLanguagesQuery,
GetWebsiteInterfaceQuery,
} from "graphql/operations-types";
import { NextRouter } from "next/router";
import { prettyLanguage } from "queries/helpers";
import Button from "./Button";
type HorizontalLineProps = {
className?: string;
locales: string[];
router: NextRouter;
languages: GetLanguagesQuery["languages"]["data"];
langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"];
};
export default function HorizontalLine(
props: HorizontalLineProps
): JSX.Element {
const { locales, router, langui } = props;
return (
<div className="w-full grid place-content-center">
<div className="flex flex-col place-items-center text-center gap-4 my-12 border-2 border-mid rounded-xl p-8 max-w-lg">
<p>{langui.language_switch_message}</p>
<div className="flex flex-wrap flex-row gap-2">
{locales.map((locale, index) => (
<Button
key={index}
active={locale === router.locale}
href={router.asPath}
locale={locale}
>
{prettyLanguage(locale, props.languages)}
</Button>
))}
</div>
</div>
</div>
);
}

View File

@ -5,18 +5,22 @@ import LightBox from "components/LightBox";
import ToolTip from "components/ToolTip";
import { useAppLayout } from "contexts/AppLayoutContext";
import Markdown from "markdown-to-jsx";
import { NextRouter } from "next/router";
import { slugify } from "queries/helpers";
import React, { useState } from "react";
type ScenBreakProps = {
type MarkdawnProps = {
className?: string;
text: string;
router: NextRouter;
};
export default function Markdawn(props: ScenBreakProps): JSX.Element {
export default function Markdawn(props: MarkdawnProps): JSX.Element {
const appLayout = useAppLayout();
const text = preprocessMarkDawn(props.text);
const { router } = props;
const [lightboxOpen, setLightboxOpen] = useState(false);
const [lightboxImages, setLightboxImages] = useState([""]);
const [lightboxIndex, setLightboxIndex] = useState(0);
@ -43,12 +47,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
children: React.ReactNode;
}) => {
return (
<div className="flex flex-row place-items-center place-content-center gap-3">
<h1 id={props.id} style={props.style}>
{props.children}
</h1>
<h1 id={props.id} style={props.style}>
{props.children}
<HeaderToolTip id={props.id} />
</div>
</h1>
);
},
},
@ -59,12 +61,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
children: React.ReactNode;
}) => {
return (
<div className="flex flex-row place-items-center place-content-center gap-3">
<h2 id={props.id} style={props.style}>
{props.children}
</h2>
<h2 id={props.id} style={props.style}>
{props.children}
<HeaderToolTip id={props.id} />
</div>
</h2>
);
},
},
@ -75,12 +75,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
children: React.ReactNode;
}) => {
return (
<div className="flex flex-row place-items-center place-content-center gap-3">
<h3 id={props.id} style={props.style}>
{props.children}
</h3>
<h3 id={props.id} style={props.style}>
{props.children}
<HeaderToolTip id={props.id} />
</div>
</h3>
);
},
},
@ -91,12 +89,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
children: React.ReactNode;
}) => {
return (
<div className="flex flex-row place-items-center place-content-center gap-3">
<h4 id={props.id} style={props.style}>
{props.children}
</h4>
<h4 id={props.id} style={props.style}>
{props.children}
<HeaderToolTip id={props.id} />
</div>
</h4>
);
},
},
@ -107,12 +103,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
children: React.ReactNode;
}) => {
return (
<div className="flex flex-row place-items-center place-content-center gap-3">
<h5 id={props.id} style={props.style}>
{props.children}
</h5>
<h5 id={props.id} style={props.style}>
{props.children}
<HeaderToolTip id={props.id} />
</div>
</h5>
);
},
},
@ -123,12 +117,10 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
children: React.ReactNode;
}) => {
return (
<div className="flex flex-row place-items-center place-content-center gap-3">
<h6 id={props.id} style={props.style}>
{props.children}
</h6>
<h6 id={props.id} style={props.style}>
{props.children}
<HeaderToolTip id={props.id} />
</div>
</h6>
);
},
},
@ -151,6 +143,28 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
);
},
},
IntraLink: {
component: (props: {
children: React.ReactNode;
target?: string;
page?: string;
}) => {
const slug = props.target
? slugify(props.target)
: slugify(props.children?.toString());
return (
<a
onClick={() =>
router.replace(
`${props.page ? props.page : ""}#${slug}`
)
}
>
{props.children}
</a>
);
},
},
player: {
component: () => {
return (
@ -219,6 +233,25 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
);
},
},
blockquote: {
component: (props: {
children: React.ReactNode;
cite?: string;
}) => {
return (
<blockquote>
{props.cite ? (
<>
&ldquo;{props.children}&rdquo;
<cite> {props.cite}</cite>
</>
) : (
props.children
)}
</blockquote>
);
},
},
img: {
component: (props: {
alt: string;
@ -230,7 +263,7 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
}) => {
return (
<div
className="my-8 cursor-pointer"
className="my-8 cursor-pointer"
onClick={() => {
setLightboxOpen(true);
setLightboxImages([
@ -280,8 +313,12 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element {
function HeaderToolTip(props: { id: string }) {
return (
<ToolTip content={"Copy anchor link"} trigger="mouseenter">
<ToolTip content={"Copied! 👍"} trigger="click">
<ToolTip
content={"Copy anchor link"}
trigger="mouseenter"
className="text-sm"
>
<ToolTip content={"Copied! 👍"} trigger="click" className="text-sm">
<span
className="material-icons transition-color hover:text-dark cursor-pointer"
onClick={() => {
@ -301,6 +338,8 @@ function HeaderToolTip(props: { id: string }) {
}
export function preprocessMarkDawn(text: string): string {
if (!text) return "";
let scenebreakIndex = 0;
const visitedSlugs: string[] = [];

View File

@ -49,7 +49,7 @@ function TOCLevel(props: TOCLevelProps): JSX.Element {
>
<span className="text-dark">{`${parentNumbering}${
childIndex + 1
}.`}</span>
}.`}</span>{" "}
<a onClick={() => router.replace(`#${child.slug}`)}>
{<abbr title={child.title}>{child.title}</abbr>}
</a>

View File

@ -64,7 +64,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
} flex-wrap gap-2`}
>
<ToolTip
content={<h3 className="text-2xl">{"Open settings"}</h3>}
content={<h3 className="text-2xl">{langui.open_settings}</h3>}
placement="right"
className="text-left"
disabled={!appLayout.mainPanelReduced}
@ -91,7 +91,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
{router.locale && (
<ToolTip
content={<h3 className="text-2xl">{"Change language"}</h3>}
content={<h3 className="text-2xl">{langui.change_language}</h3>}
placement="right"
className="text-left"
disabled={!appLayout.mainPanelReduced}
@ -110,7 +110,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
)}
<ToolTip
content={<h3 className="text-2xl">{"Open search"}</h3>}
content={<h3 className="text-2xl">{langui.open_search}</h3>}
placement="right"
className="text-left"
disabled={!appLayout.mainPanelReduced}
@ -155,18 +155,17 @@ export default function MainPanel(props: MainPanelProps): JSX.Element {
onClick={() => appLayout.setMainPanelOpen(false)}
/>
{/*
<NavOption
url="/wiki"
icon="travel_explore"
title={langui.wiki}
subtitle={langui.wiki_short_description}
reduced={appLayout.mainPanelReduced && isDesktop}
onClick={() => appLayout.setMainPanelOpen(false)}
/>
{/*
<NavOption
url="/chronicles"
icon="watch_later"

View File

@ -12,7 +12,6 @@ export type PopupProps = {
};
export default function Popup(props: PopupProps): JSX.Element {
return (
<div
className={`fixed inset-0 z-50 grid place-content-center transition-[backdrop-filter] duration-500 ${

View File

@ -115,6 +115,16 @@ query getWebsiteInterface($language_code: String) {
content
result
results
language_switch_message
open_settings
change_language
open_search
chronology
accords_handbook
legality
members
sharing_policy
contact_us
}
}
}
@ -1301,3 +1311,57 @@ query getPostsPreview($language_code: String) {
}
}
}
query getPostLanguages($slug: String) {
posts(filters: { slug: { eq: $slug } }) {
data {
attributes {
translations {
language {
data {
attributes {
code
}
}
}
}
}
}
}
}
query getContentLanguages($slug: String) {
contents(filters: { slug: { eq: $slug } }) {
data {
attributes {
text_set {
language {
data {
attributes {
code
}
}
}
}
video_set {
language {
data {
attributes {
code
}
}
}
}
audio_set {
language {
data {
attributes {
code
}
}
}
}
}
}
}
}

View File

@ -204,6 +204,16 @@ export type GetWebsiteInterfaceQuery = {
content: string;
result: string;
results: string;
language_switch_message: string;
open_settings: string;
change_language: string;
open_search: string;
chronology: string;
accords_handbook: string;
legality: string;
members: string;
sharing_policy: string;
contact_us: string;
};
}>;
};
@ -1737,3 +1747,77 @@ export type GetPostsPreviewQuery = {
}>;
};
};
export type GetPostLanguagesQueryVariables = Exact<{
slug: InputMaybe<Scalars["String"]>;
}>;
export type GetPostLanguagesQuery = {
__typename: "Query";
posts: {
__typename: "PostEntityResponseCollection";
data: Array<{
__typename: "PostEntity";
attributes: {
__typename: "Post";
translations: Array<{
__typename: "ComponentTranslationsPosts";
language: {
__typename: "LanguageEntityResponse";
data: {
__typename: "LanguageEntity";
attributes: { __typename: "Language"; code: string };
};
};
}>;
};
}>;
};
};
export type GetContentLanguagesQueryVariables = Exact<{
slug: InputMaybe<Scalars["String"]>;
}>;
export type GetContentLanguagesQuery = {
__typename: "Query";
contents: {
__typename: "ContentEntityResponseCollection";
data: Array<{
__typename: "ContentEntity";
attributes: {
__typename: "Content";
text_set: Array<{
__typename: "ComponentSetsTextSet";
language: {
__typename: "LanguageEntityResponse";
data: {
__typename: "LanguageEntity";
attributes: { __typename: "Language"; code: string };
};
};
}>;
video_set: Array<{
__typename: "ComponentSetsVideoSet";
language: {
__typename: "LanguageEntityResponse";
data: {
__typename: "LanguageEntity";
attributes: { __typename: "Language"; code: string };
};
};
}>;
audio_set: Array<{
__typename: "ComponentSetsAudioSet";
language: {
__typename: "LanguageEntityResponse";
data: {
__typename: "LanguageEntity";
attributes: { __typename: "Language"; code: string };
};
};
}>;
};
}>;
};
};

View File

@ -3,6 +3,8 @@ import { readFileSync } from "fs";
import {
GetChronologyItemsQuery,
GetChronologyItemsQueryVariables,
GetContentLanguagesQuery,
GetContentLanguagesQueryVariables,
GetContentQuery,
GetContentQueryVariables,
GetContentsQuery,
@ -23,6 +25,8 @@ import {
GetLibraryItemsPreviewQueryVariables,
GetLibraryItemsSlugsQuery,
GetLibraryItemsSlugsQueryVariables,
GetPostLanguagesQuery,
GetPostLanguagesQueryVariables,
GetPostQuery,
GetPostQueryVariables,
GetPostsPreviewQuery,
@ -168,3 +172,17 @@ export async function getPostsPreview(
const query = getQueryFromOperations("getPostsPreview");
return await graphQL(query, JSON.stringify(variables));
}
export async function getPostLanguages(
variables: GetPostLanguagesQueryVariables
): Promise<GetPostLanguagesQuery> {
const query = getQueryFromOperations("getPostLanguages");
return await graphQL(query, JSON.stringify(variables));
}
export async function getContentLanguages(
variables: GetContentLanguagesQueryVariables
): Promise<GetContentLanguagesQuery> {
const query = getQueryFromOperations("getContentLanguages");
return await graphQL(query, JSON.stringify(variables));
}

View File

@ -1,8 +1,10 @@
import type { AppProps } from "next/app";
import "tailwind.css";
import "@fontsource/zen-maru-gothic/500.css";
import "@fontsource/zen-maru-gothic/900.css";
import "@fontsource/vollkorn/700.css";
import "@fontsource/opendyslexic/400.css";
import "@fontsource/opendyslexic/700.css";
import "@fontsource/material-icons";
import { AppContextProvider } from "contexts/AppLayoutContext";

View File

@ -0,0 +1,102 @@
import AppLayout from "components/AppLayout";
import LanguageSwitcher from "components/LanguageSwitcher";
import Markdawn from "components/Markdown/Markdawn";
import TOC from "components/Markdown/TOC";
import ReturnButton, {
ReturnButtonType,
} from "components/PanelComponents/ReturnButton";
import ContentPanel from "components/Panels/ContentPanel";
import SubPanel from "components/Panels/SubPanel";
import { getPost, getPostLanguages } from "graphql/operations";
import { GetPostQuery } from "graphql/operations-types";
import { GetStaticProps } from "next";
import { useRouter } from "next/router";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { prettySlug } from "queries/helpers";
interface AccordsHandbookProps extends AppStaticProps {
post: GetPostQuery["posts"]["data"][number]["attributes"];
locales: string[];
}
export default function AccordsHandbook(
props: AccordsHandbookProps
): JSX.Element {
const { langui, post, locales } = props;
const router = useRouter();
const subPanel = (
<SubPanel>
<ReturnButton
href="/about-us"
displayOn={ReturnButtonType.Desktop}
langui={langui}
title={langui.about_us}
horizontalLine
/>
{post.translations.length > 0 && post.translations[0].body && (
<TOC
text={post.translations[0].body}
router={router}
title={post.translations[0].title}
/>
)}
</SubPanel>
);
const contentPanel = (
<ContentPanel>
<ReturnButton
href="/about-us"
displayOn={ReturnButtonType.Mobile}
langui={langui}
title={langui.about_us}
className="mb-10"
/>
{locales.includes(router.locale || "en") ? (
<Markdawn router={router} text={post.translations[0].body} />
) : (
<LanguageSwitcher
locales={locales}
router={router}
languages={props.languages}
langui={props.langui}
/>
)}
</ContentPanel>
);
return (
<AppLayout
navTitle={
post.translations.length > 0
? post.translations[0].title
: prettySlug(post.slug)
}
subPanel={subPanel}
contentPanel={contentPanel}
{...props}
/>
);
}
export const getStaticProps: GetStaticProps = async (context) => {
const slug = "accords-handbook";
const props: AccordsHandbookProps = {
...(await getAppStaticProps(context)),
post: (
await getPost({
slug: slug,
language_code: context.locale || "en",
})
).posts.data[0].attributes,
locales: (
await getPostLanguages({ slug: slug })
).posts.data[0].attributes.translations.map((translation) => {
return translation.language.data.attributes.code;
}),
};
return {
props: props,
};
};

View File

@ -16,15 +16,19 @@ export default function AboutUs(props: AboutUsProps): JSX.Element {
title={langui.about_us}
description={langui.about_us_description}
/>
<NavOption title="Accords Handbook" url="/about-us/handbook" border />
<NavOption
title="Site information"
url="/about-us/site-information"
title={langui.accords_handbook}
url="/about-us/accords-handbook"
border
/>
<NavOption title="FAQ" url="/about-us/faq" border />
<NavOption title="Sharing Policy" url="/about-us/sharing-policy" border />
<NavOption title="Contact us" url="/about-us/contact" border />
<NavOption title={langui.legality} url="/about-us/legality" border />
<NavOption title={langui.members} url="/about-us/members" border />
<NavOption
title={langui.sharing_policy}
url="/about-us/sharing-policy"
border
/>
<NavOption title={langui.contact_us} url="/about-us/contact" border />
</SubPanel>
);
return (

View File

@ -0,0 +1,100 @@
import AppLayout from "components/AppLayout";
import LanguageSwitcher from "components/LanguageSwitcher";
import Markdawn from "components/Markdown/Markdawn";
import TOC from "components/Markdown/TOC";
import ReturnButton, {
ReturnButtonType,
} from "components/PanelComponents/ReturnButton";
import ContentPanel from "components/Panels/ContentPanel";
import SubPanel from "components/Panels/SubPanel";
import { getPost, getPostLanguages } from "graphql/operations";
import { GetPostQuery } from "graphql/operations-types";
import { GetStaticProps } from "next";
import { useRouter } from "next/router";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { prettySlug } from "queries/helpers";
interface SiteInfoProps extends AppStaticProps {
post: GetPostQuery["posts"]["data"][number]["attributes"];
locales: string[];
}
export default function SiteInformation(props: SiteInfoProps): JSX.Element {
const { langui, post, locales } = props;
const router = useRouter();
const subPanel = (
<SubPanel>
<ReturnButton
href="/about-us"
displayOn={ReturnButtonType.Desktop}
langui={langui}
title={langui.about_us}
horizontalLine
/>
{post.translations.length > 0 && post.translations[0].body && (
<TOC
text={post.translations[0].body}
router={router}
title={post.translations[0].title}
/>
)}
</SubPanel>
);
const contentPanel = (
<ContentPanel>
<ReturnButton
href="/about-us"
displayOn={ReturnButtonType.Mobile}
langui={langui}
title={langui.about_us}
className="mb-10"
/>
{locales.includes(router.locale || "en") ? (
<Markdawn router={router} text={post.translations[0].body} />
) : (
<LanguageSwitcher
locales={locales}
router={router}
languages={props.languages}
langui={props.langui}
/>
)}
</ContentPanel>
);
return (
<AppLayout
navTitle={
post.translations.length > 0
? post.translations[0].title
: prettySlug(post.slug)
}
subPanel={subPanel}
contentPanel={contentPanel}
{...props}
/>
);
}
export const getStaticProps: GetStaticProps = async (context) => {
const slug = "legality";
const props: SiteInfoProps = {
...(await getAppStaticProps(context)),
post: (
await getPost({
slug: slug,
language_code: context.locale || "en",
})
).posts.data[0].attributes,
locales: (
await getPostLanguages({ slug: slug })
).posts.data[0].attributes.translations.map((translation) => {
return translation.language.data.attributes.code;
}),
};
return {
props: props,
};
};

View File

@ -0,0 +1,100 @@
import AppLayout from "components/AppLayout";
import LanguageSwitcher from "components/LanguageSwitcher";
import Markdawn from "components/Markdown/Markdawn";
import TOC from "components/Markdown/TOC";
import ReturnButton, {
ReturnButtonType,
} from "components/PanelComponents/ReturnButton";
import ContentPanel from "components/Panels/ContentPanel";
import SubPanel from "components/Panels/SubPanel";
import { getPost, getPostLanguages } from "graphql/operations";
import { GetPostQuery } from "graphql/operations-types";
import { GetStaticProps } from "next";
import { useRouter } from "next/router";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { prettySlug } from "queries/helpers";
interface SharingPolicyProps extends AppStaticProps {
post: GetPostQuery["posts"]["data"][number]["attributes"];
locales: string[];
}
export default function SharingPolicy(props: SharingPolicyProps): JSX.Element {
const { langui, post, locales } = props;
const router = useRouter();
const subPanel = (
<SubPanel>
<ReturnButton
href="/about-us"
displayOn={ReturnButtonType.Desktop}
langui={langui}
title={langui.about_us}
horizontalLine
/>
{post.translations.length > 0 && post.translations[0].body && (
<TOC
text={post.translations[0].body}
router={router}
title={post.translations[0].title}
/>
)}
</SubPanel>
);
const contentPanel = (
<ContentPanel>
<ReturnButton
href="/about-us"
displayOn={ReturnButtonType.Mobile}
langui={langui}
title={langui.about_us}
className="mb-10"
/>
{locales.includes(router.locale || "en") ? (
<Markdawn router={router} text={post.translations[0].body} />
) : (
<LanguageSwitcher
locales={locales}
router={router}
languages={props.languages}
langui={props.langui}
/>
)}
</ContentPanel>
);
return (
<AppLayout
navTitle={
post.translations.length > 0
? post.translations[0].title
: prettySlug(post.slug)
}
subPanel={subPanel}
contentPanel={contentPanel}
{...props}
/>
);
}
export const getStaticProps: GetStaticProps = async (context) => {
const slug = "sharing-policy";
const props: SharingPolicyProps = {
...(await getAppStaticProps(context)),
post: (
await getPost({
slug: "sharing-policy",
language_code: context.locale || "en",
})
).posts.data[0].attributes,
locales: (
await getPostLanguages({ slug: slug })
).posts.data[0].attributes.translations.map((translation) => {
return translation.language.data.attributes.code;
}),
};
return {
props: props,
};
};

View File

@ -1,60 +0,0 @@
import AppLayout from "components/AppLayout";
import Markdawn from "components/Markdown/Markdawn";
import ReturnButton, {
ReturnButtonType,
} from "components/PanelComponents/ReturnButton";
import ContentPanel from "components/Panels/ContentPanel";
import { getPost } from "graphql/operations";
import { GetPostQuery } from "graphql/operations-types";
import { GetStaticProps } from "next";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { prettySlug } from "queries/helpers";
interface SiteInfoProps extends AppStaticProps {
post: GetPostQuery["posts"]["data"][number]["attributes"];
}
export default function SiteInformation(props: SiteInfoProps): JSX.Element {
const { langui, post } = props;
const contentPanel = (
<ContentPanel>
<ReturnButton
href="/about-us"
displayOn={ReturnButtonType.Both}
langui={langui}
title={langui.about_us}
className="mb-10"
/>
{post.translations.length > 0 && (
<Markdawn text={post.translations[0].body} />
)}
</ContentPanel>
);
return (
<AppLayout
navTitle={
post.translations.length > 0
? post.translations[0].title
: prettySlug(post.slug)
}
contentPanel={contentPanel}
{...props}
/>
);
}
export const getStaticProps: GetStaticProps = async (context) => {
const props: SiteInfoProps = {
...(await getAppStaticProps(context)),
post: (
await getPost({
slug: "site-information",
language_code: context.locale || "en",
})
).posts.data[0].attributes,
};
return {
props: props,
};
};

View File

@ -1,5 +1,9 @@
import { GetStaticPaths, GetStaticProps } from "next";
import { getContentsSlugs, getContentText } from "graphql/operations";
import {
getContentLanguages,
getContentsSlugs,
getContentText,
} from "graphql/operations";
import { GetContentTextQuery } from "graphql/operations-types";
import ContentPanel from "components/Panels/ContentPanel";
import HorizontalLine from "components/HorizontalLine";
@ -25,15 +29,17 @@ import RecorderChip from "components/RecorderChip";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import TOC from "components/Markdown/TOC";
import ToolTip from "components/ToolTip";
import LanguageSwitcher from "components/LanguageSwitcher";
interface ContentReadProps extends AppStaticProps {
content: GetContentTextQuery["contents"]["data"][number]["attributes"];
contentId: GetContentTextQuery["contents"]["data"][number]["id"];
locales: string[];
}
export default function ContentRead(props: ContentReadProps): JSX.Element {
useTesting(props);
const { langui, content, languages } = props;
const { langui, content, languages, locales } = props;
const router = useRouter();
const subPanel = (
@ -186,8 +192,15 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
<HorizontalLine />
{content.text_set.length > 0 && content.text_set[0].text && (
<Markdawn text={content.text_set[0].text} />
{locales.includes(router.locale || "en") ? (
<Markdawn router={router} text={content.text_set[0].text} />
) : (
<LanguageSwitcher
locales={locales}
router={router}
languages={props.languages}
langui={props.langui}
/>
)}
</div>
</ContentPanel>
@ -235,9 +248,10 @@ export default function ContentRead(props: ContentReadProps): JSX.Element {
}
export const getStaticProps: GetStaticProps = async (context) => {
const slug = context.params?.slug?.toString() || "";
const content = (
await getContentText({
slug: context.params?.slug?.toString() || "",
slug: slug,
language_code: context.locale || "en",
})
).contents.data[0];
@ -245,6 +259,11 @@ export const getStaticProps: GetStaticProps = async (context) => {
...(await getAppStaticProps(context)),
content: content.attributes,
contentId: content.id,
locales: (
await getContentLanguages({ slug: slug })
).contents.data[0].attributes.text_set.map((translation) => {
return translation.language.data.attributes.code;
}),
};
return {
props: props,

View File

@ -7,11 +7,13 @@ import { useCallback, useState } from "react";
import Markdawn from "components/Markdown/Markdawn";
import Script from "next/script";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { useRouter } from "next/router";
interface EditorProps extends AppStaticProps {}
export default function Editor(props: EditorProps): JSX.Element {
const { langui } = props;
const router = useRouter();
const handleInput = useCallback((e) => {
setMarkdown(e.target.value);
@ -76,7 +78,7 @@ export default function Editor(props: EditorProps): JSX.Element {
<div>
<h2>Preview</h2>
<div className="bg-mid rounded-xl p-8">
<Markdawn className="max-w-full" text={markdown} />
<Markdawn router={router} className="max-w-full" text={markdown} />
</div>
</div>
</div>

View File

@ -1,18 +1,23 @@
import AppLayout from "components/AppLayout";
import LanguageSwitcher from "components/LanguageSwitcher";
import Markdawn from "components/Markdown/Markdawn";
import ContentPanel from "components/Panels/ContentPanel";
import { getPost } from "graphql/operations";
import { getPost, getPostLanguages } from "graphql/operations";
import { GetPostQuery } from "graphql/operations-types";
import { GetStaticProps } from "next";
import { useRouter } from "next/router";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { prettySlug } from "queries/helpers";
interface HomeProps extends AppStaticProps {
post: GetPostQuery["posts"]["data"][number]["attributes"];
locales: string[];
}
export default function Home(props: HomeProps): JSX.Element {
const { post } = props;
const { post, locales } = props;
const router = useRouter();
const contentPanel = (
<ContentPanel>
<div className="grid place-items-center place-content-center w-full gap-5 text-center">
@ -22,8 +27,15 @@ export default function Home(props: HomeProps): JSX.Element {
Discover Analyse Translate Archive
</h2>
</div>
{post.translations.length > 0 && (
<Markdawn text={post.translations[0].body} />
{locales.includes(router.locale || "en") ? (
<Markdawn router={router} text={post.translations[0].body} />
) : (
<LanguageSwitcher
locales={locales}
router={router}
languages={props.languages}
langui={props.langui}
/>
)}
</ContentPanel>
);
@ -42,14 +54,20 @@ export default function Home(props: HomeProps): JSX.Element {
}
export const getStaticProps: GetStaticProps = async (context) => {
const slug = "home";
const props: HomeProps = {
...(await getAppStaticProps(context)),
post: (
await getPost({
slug: "home",
slug: slug,
language_code: context.locale || "en",
})
).posts.data[0].attributes,
locales: (
await getPostLanguages({ slug: slug })
).posts.data[0].attributes.translations.map((translation) => {
return translation.language.data.attributes.code;
}),
};
return {
props: props,

View File

@ -2,6 +2,7 @@ import AppLayout from "components/AppLayout";
import Chip from "components/Chip";
import ThumbnailHeader from "components/Content/ThumbnailHeader";
import HorizontalLine from "components/HorizontalLine";
import LanguageSwitcher from "components/LanguageSwitcher";
import Markdawn from "components/Markdown/Markdawn";
import TOC from "components/Markdown/TOC";
import ReturnButton, {
@ -11,7 +12,7 @@ import ContentPanel from "components/Panels/ContentPanel";
import SubPanel from "components/Panels/SubPanel";
import RecorderChip from "components/RecorderChip";
import ToolTip from "components/ToolTip";
import { getPost, getPostsSlugs } from "graphql/operations";
import { getPost, getPostLanguages, getPostsSlugs } from "graphql/operations";
import { GetPostQuery, StrapiImage } from "graphql/operations-types";
import { GetStaticPaths, GetStaticProps } from "next";
import { useRouter } from "next/router";
@ -21,10 +22,11 @@ import { prettySlug, getStatusDescription } from "queries/helpers";
interface PostProps extends AppStaticProps {
post: GetPostQuery["posts"]["data"][number]["attributes"];
postId: GetPostQuery["posts"]["data"][number]["id"];
locales: string[];
}
export default function LibrarySlug(props: PostProps): JSX.Element {
const { post, postId, langui } = props;
const { post, locales, langui } = props;
const router = useRouter();
const thumbnail: StrapiImage | undefined =
@ -107,8 +109,15 @@ export default function LibrarySlug(props: PostProps): JSX.Element {
<HorizontalLine />
{post.translations.length > 0 && post.translations[0].body && (
<Markdawn text={post.translations[0].body} />
{locales.includes(router.locale || "en") ? (
<Markdawn router={router} text={post.translations[0].body} />
) : (
<LanguageSwitcher
locales={locales}
router={router}
languages={props.languages}
langui={props.langui}
/>
)}
</ContentPanel>
);
@ -130,9 +139,10 @@ export default function LibrarySlug(props: PostProps): JSX.Element {
}
export const getStaticProps: GetStaticProps = async (context) => {
const slug = context.params?.slug?.toString() || "";
const post = (
await getPost({
slug: context.params?.slug?.toString() || "",
slug: slug,
language_code: context.locale || "en",
})
).posts.data[0];
@ -140,6 +150,11 @@ export const getStaticProps: GetStaticProps = async (context) => {
...(await getAppStaticProps(context)),
post: post.attributes,
postId: post.id,
locales: (
await getPostLanguages({ slug: slug })
).posts.data[0].attributes.translations.map((translation) => {
return translation.language.data.attributes.code;
}),
};
return {
props: props,

View File

@ -5,7 +5,9 @@ import AppLayout from "components/AppLayout";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import { GetPostsPreviewQuery } from "graphql/operations-types";
import { getPostsPreview } from "graphql/operations";
import ContentPanel, { ContentPanelWidthSizes } from "components/Panels/ContentPanel";
import ContentPanel, {
ContentPanelWidthSizes,
} from "components/Panels/ContentPanel";
import PostsPreview from "components/News/PostsPreview";
interface NewsProps extends AppStaticProps {

View File

@ -17,6 +17,9 @@ import {
import InsetBox from "components/InsetBox";
import { useRouter } from "next/router";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import ReturnButton, {
ReturnButtonType,
} from "components/PanelComponents/ReturnButton";
interface ChronologyProps extends AppStaticProps {
chronologyItems: GetChronologyItemsQuery["chronologyItems"]["data"];
@ -60,6 +63,14 @@ export default function Chronology(props: ChronologyProps): JSX.Element {
const subPanel = (
<SubPanel>
<ReturnButton
href="/wiki"
title={langui.wiki}
langui={langui}
displayOn={ReturnButtonType.Desktop}
horizontalLine
/>
{chronologyEras.map((era) => (
<NavOption
key={era.id}
@ -80,6 +91,14 @@ export default function Chronology(props: ChronologyProps): JSX.Element {
const contentPanel = (
<ContentPanel>
<ReturnButton
href="/wiki"
title={langui.wiki}
langui={langui}
displayOn={ReturnButtonType.Mobile}
className="mb-10"
/>
{chronologyItemYearGroups.map((era, eraIndex) => (
<>
<InsetBox

View File

@ -3,6 +3,8 @@ import PanelHeader from "components/PanelComponents/PanelHeader";
import { GetStaticProps } from "next";
import AppLayout from "components/AppLayout";
import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps";
import HorizontalLine from "components/HorizontalLine";
import NavOption from "components/PanelComponents/NavOption";
interface WikiProps extends AppStaticProps {}
@ -15,6 +17,7 @@ export default function Wiki(props: WikiProps): JSX.Element {
title={langui.wiki}
description={langui.wiki_description}
/>
<NavOption title="Chronology" url="/wiki/chronology" border />
</SubPanel>
);

View File

@ -274,8 +274,9 @@ export function getStatusDescription(
}
}
export function slugify(str: string): string {
return str
export function slugify(string: string | undefined): string {
if (!string) return "";
return string
.replace(/[ÀÁÂÃÄÅàáâãäåæÆ]/g, "a")
.replace(/[çÇ]/g, "c")
.replace(/[ðÐ]/g, "d")

View File

@ -54,7 +54,7 @@
.formatted h4,
.formatted h5,
.formatted h6 {
@apply text-center;
@apply text-center flex gap-3 justify-center;
}
.formatted h1 {
@ -94,6 +94,10 @@
@apply my-2 text-justify;
}
.formatted strong {
@apply font-black;
}
.formatted footer {
@apply border-t-[3px] border-dotted pt-6;
}
@ -122,6 +126,14 @@
@apply list-decimal pl-4;
}
.formatted blockquote {
@apply border-2 border-mid rounded-lg p-5 text-center my-8;
}
.formatted blockquote cite {
@apply text-dark block;
}
/* INPUT */
input {