diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx
index 97fc640..0d713ee 100644
--- a/src/components/AppLayout.tsx
+++ b/src/components/AppLayout.tsx
@@ -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";
diff --git a/src/components/LanguageSwitcher.tsx b/src/components/LanguageSwitcher.tsx
new file mode 100644
index 0000000..eb32629
--- /dev/null
+++ b/src/components/LanguageSwitcher.tsx
@@ -0,0 +1,43 @@
+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 } = props;
+ return (
+
+
+
+ This content is not available in the currently selected language. You
+ can select one the following languages instead:
+
+
+ {locales.map((locale, index) => (
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/graphql/operation.graphql b/src/graphql/operation.graphql
index b6d3730..0e9f958 100644
--- a/src/graphql/operation.graphql
+++ b/src/graphql/operation.graphql
@@ -1301,3 +1301,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
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/graphql/operations-types.ts b/src/graphql/operations-types.ts
index 245677f..4b7f99a 100644
--- a/src/graphql/operations-types.ts
+++ b/src/graphql/operations-types.ts
@@ -1737,3 +1737,77 @@ export type GetPostsPreviewQuery = {
}>;
};
};
+
+export type GetPostLanguagesQueryVariables = Exact<{
+ slug: InputMaybe;
+}>;
+
+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;
+}>;
+
+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 };
+ };
+ };
+ }>;
+ };
+ }>;
+ };
+};
diff --git a/src/graphql/operations.ts b/src/graphql/operations.ts
index 74a55f2..260b81e 100644
--- a/src/graphql/operations.ts
+++ b/src/graphql/operations.ts
@@ -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,19 @@ export async function getPostsPreview(
const query = getQueryFromOperations("getPostsPreview");
return await graphQL(query, JSON.stringify(variables));
}
+
+export async function getPostLanguages(
+ variables: GetPostLanguagesQueryVariables
+): Promise {
+ const query = getQueryFromOperations("getPostLanguages");
+ console.log(query);
+ return await graphQL(query, JSON.stringify(variables));
+}
+
+export async function getContentLanguages(
+ variables: GetContentLanguagesQueryVariables
+): Promise {
+ const query = getQueryFromOperations("getContentLanguages");
+ console.log(query);
+ return await graphQL(query, JSON.stringify(variables));
+}
diff --git a/src/pages/contents/[slug]/read.tsx b/src/pages/contents/[slug]/read.tsx
index 25573b2..745e4c3 100644
--- a/src/pages/contents/[slug]/read.tsx
+++ b/src/pages/contents/[slug]/read.tsx
@@ -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 {
- {content.text_set.length > 0 && content.text_set[0].text && (
+ {locales.includes(router.locale || "en") ? (
+ ) : (
+
)}
@@ -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,
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 0e002ab..e771302 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,7 +1,8 @@
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";
@@ -10,10 +11,11 @@ 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 = (
@@ -25,8 +27,15 @@ export default function Home(props: HomeProps): JSX.Element {
Discover • Analyse • Translate • Archive
- {post.translations.length > 0 && (
+ {locales.includes(router.locale || "en") ? (
+ ) : (
+
)}
);
@@ -45,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,
diff --git a/src/pages/news/[slug].tsx b/src/pages/news/[slug].tsx
index 3ee7b54..bafb633 100644
--- a/src/pages/news/[slug].tsx
+++ b/src/pages/news/[slug].tsx
@@ -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 {
- {post.translations.length > 0 && post.translations[0].body && (
+ {locales.includes(router.locale || "en") ? (
+ ) : (
+
)}
);
@@ -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,