diff --git a/package-lock.json b/package-lock.json index 8718301..3c95d9e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,6 @@ "turndown": "^7.1.1" }, "devDependencies": { - "@tailwindcss/typography": "^0.5.2", "@types/node": "17.0.21", "@types/react": "17.0.40", "@types/react-dom": "^17.0.13", @@ -455,20 +454,6 @@ "integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==", "dev": true }, - "node_modules/@tailwindcss/typography": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz", - "integrity": "sha512-coq8DBABRPFcVhVIk6IbKyyHUt7YTEC/C992tatFB+yEx5WGBQrCgsSFjxHUr8AWXphWckadVJbominEduYBqw==", - "dev": true, - "dependencies": { - "lodash.castarray": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || insiders" - } - }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -2405,18 +2390,6 @@ "node": ">=4" } }, - "node_modules/lodash.castarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", - "integrity": "sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU=", - "dev": true - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -3950,17 +3923,6 @@ "integrity": "sha512-JLo+Y592QzIE+q7Dl2pMUtt4q8SKYI5jDrZxrozEQxnGVOyYE+GWK9eLkwTaeN9DDctlaRAQ3TBmzZ1qdLE30A==", "dev": true }, - "@tailwindcss/typography": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.2.tgz", - "integrity": "sha512-coq8DBABRPFcVhVIk6IbKyyHUt7YTEC/C992tatFB+yEx5WGBQrCgsSFjxHUr8AWXphWckadVJbominEduYBqw==", - "dev": true, - "requires": { - "lodash.castarray": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2" - } - }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -5394,18 +5356,6 @@ "path-exists": "^3.0.0" } }, - "lodash.castarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", - "integrity": "sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", diff --git a/package.json b/package.json index 20c6682..661ba85 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "turndown": "^7.1.1" }, "devDependencies": { - "@tailwindcss/typography": "^0.5.2", "@types/node": "17.0.21", "@types/react": "17.0.40", "@types/react-dom": "^17.0.13", diff --git a/src/components/Content/ThumbnailHeader.tsx b/src/components/Content/ThumbnailHeader.tsx index 5ae6da6..b9bfd44 100644 --- a/src/components/Content/ThumbnailHeader.tsx +++ b/src/components/Content/ThumbnailHeader.tsx @@ -2,10 +2,11 @@ import { GetContentQuery, GetWebsiteInterfaceQuery, } from "graphql/operations-types"; -import { prettySlug } from "queries/helpers"; +import { prettyinlineTitle, prettySlug, slugify } from "queries/helpers"; import Button from "components/Button"; import Img, { ImageQuality } from "components/Img"; import InsetBox from "components/InsetBox"; +import Chip from "components/Chip"; export type ThumbnailHeaderProps = { content: { @@ -39,7 +40,18 @@ export default function ThumbnailHeader(
)} -
+
0 + ? prettyinlineTitle( + content.titles[0].pre_title, + content.titles[0].title, + content.titles[0].subtitle + ) + : prettySlug(content.slug) + )} + className="grid place-items-center text-center" + > {content.titles.length > 0 ? ( <>

{content.titles[0].pre_title}

@@ -54,22 +66,26 @@ export default function ThumbnailHeader(
{content.type && ( -
+

{langui.type}

- +
+ + {content.type.data.attributes.titles.length > 0 + ? content.type.data.attributes.titles[0].title + : prettySlug(content.type.data.attributes.slug)} + +
)} {content.categories.data.length > 0 && ( -
+

{langui.categories}

- {content.categories.data.map((category) => ( - - ))} +
+ {content.categories.data.map((category) => ( + {category.attributes.name} + ))} +
)}
diff --git a/src/components/Markdown/Markdawn.tsx b/src/components/Markdown/Markdawn.tsx index 38bf661..6414a1e 100644 --- a/src/components/Markdown/Markdawn.tsx +++ b/src/components/Markdown/Markdawn.tsx @@ -1,6 +1,9 @@ +import HorizontalLine from "components/HorizontalLine"; +import InsetBox from "components/InsetBox"; import { useAppLayout } from "contexts/AppLayoutContext"; import Markdown from "markdown-to-jsx"; -import SceneBreak from "./SceneBreak"; +import { slugify } from "queries/helpers"; +import React from "react"; type ScenBreakProps = { className?: string; @@ -9,15 +12,31 @@ type ScenBreakProps = { export default function Markdawn(props: ScenBreakProps): JSX.Element { const appLayout = useAppLayout(); + const text = preprocessMarkDawn(props.text); - if (props.text) { + if (text) { return ( { + return
; + }, + }, + SceneBreak: { + component: (props: { id: string }) => { + return ( +
+ * * * +
+ ); + }, }, player: { component: () => { @@ -28,12 +47,80 @@ export default function Markdawn(props: ScenBreakProps): JSX.Element { ); }, }, + Transcript: { + component: (props) => { + return ( +
+ {props.children} +
+ ); + }, + }, + Line: { + component: (props) => { + return ( + <> + + {props.name} + +

{props.children}

+ + ); + }, + }, + InsetBox: { + component: (props) => { + return {props.children}; + }, + }, + li: { + component: (props: { children: React.ReactNode }) => { + return ( +
  • 100 + ? "my-4" + : "" + } + > + {props.children} +
  • + ); + }, + }, + Highlight: { + component: (props: { children: React.ReactNode }) => { + return {props.children}; + }, + }, + footer: { + component: (props: { children: React.ReactNode }) => { + return ( + <> + +
    {props.children}
    + + ); + }, + }, }, }} > - {props.text} + {text}
    ); } return <>; } + +export function preprocessMarkDawn(text: string): string { + let scenebreakIndex = 0; + const result = text.split("\n").map((line) => { + if (line === "* * *" || line === "---") { + scenebreakIndex++; + return ``; + } + return line; + }); + return result.join("\n"); +} diff --git a/src/components/Markdown/SceneBreak.tsx b/src/components/Markdown/SceneBreak.tsx deleted file mode 100644 index a636120..0000000 --- a/src/components/Markdown/SceneBreak.tsx +++ /dev/null @@ -1,15 +0,0 @@ -type ScenBreakProps = { - className?: string; -}; - -export default function SceneBreak(props: ScenBreakProps): JSX.Element { - return ( -
    - * * * -
    - ); -} diff --git a/src/components/Markdown/TOC.tsx b/src/components/Markdown/TOC.tsx new file mode 100644 index 0000000..ff0c15f --- /dev/null +++ b/src/components/Markdown/TOC.tsx @@ -0,0 +1,153 @@ +import { slugify } from "queries/helpers"; +import { preprocessMarkDawn } from "./Markdawn"; + +type TOCProps = { + text: string; + title?: string; +}; + +export default function TOC(props: TOCProps): JSX.Element { + const toc = getTocFromMarkdawn(preprocessMarkDawn(props.text), props.title); + + return ( +
    +

    Table of content

    +
      +
    1. + + {{toc.title}} + +
    2. + {toc.children.map((h2, h2Index) => ( + <> +
    3. + {`${h2Index + 1}. `} + + {{h2.title}} + +
    4. +
        + {h2.children.map((h3, h3Index) => ( +
      1. + {`${h2Index + 1}.${ + h3Index + 1 + }. `} + + {{h3.title}} + +
      2. + ))} +
      + + ))} +
    +
    + ); +} + +export type TOC = { + title: string; + slug: string; + children: TOC[]; +}; + +export function getTocFromMarkdawn(text: string, title?: string): TOC { + if (!title) title = "Return to top"; + let toc: TOC = { title: title, slug: slugify(title) || "", children: [] }; + let h2 = -1; + let h3 = -1; + let h4 = -1; + let h5 = -1; + let scenebreak = 0; + let scenebreakIndex = 0; + text.split("\n").map((line) => { + if (line.startsWith("# ")) { + toc.slug = slugify(line); + } else if (line.startsWith("## ")) { + toc.children.push({ + title: line.slice("## ".length), + slug: slugify(line), + children: [], + }); + h2++; + h3 = -1; + h4 = -1; + h5 = -1; + scenebreak = 0; + } else if (line.startsWith("### ")) { + toc.children[h2].children.push({ + title: line.slice("### ".length), + slug: slugify(line), + children: [], + }); + h3++; + h4 = -1; + h5 = -1; + scenebreak = 0; + } else if (line.startsWith("#### ")) { + toc.children[h2].children[h3].children.push({ + title: line.slice("#### ".length), + slug: slugify(line), + children: [], + }); + h4++; + h5 = -1; + scenebreak = 0; + } else if (line.startsWith("##### ")) { + toc.children[h2].children[h3].children[h4].children.push({ + title: line.slice("##### ".length), + slug: slugify(line), + children: [], + }); + h5++; + scenebreak = 0; + } else if (line.startsWith("###### ")) { + toc.children[h2].children[h3].children[h4].children[h5].children.push({ + title: line.slice("###### ".length), + slug: slugify(line), + children: [], + }); + } else if (line.startsWith(`= 0) { + toc.children[h2].children[h3].children[h4].children[h5].children.push({ + title: `Scene break ${scenebreak}`, + slug: slugify(`scene-break-${scenebreakIndex}`), + children: [], + }); + } else if (h4 >= 0) { + toc.children[h2].children[h3].children[h4].children.push({ + title: `Scene break ${scenebreak}`, + slug: slugify(`scene-break-${scenebreakIndex}`), + children: [], + }); + } else if (h3 >= 0) { + toc.children[h2].children[h3].children.push({ + title: `Scene break ${scenebreak}`, + slug: slugify(`scene-break-${scenebreakIndex}`), + children: [], + }); + } else if (h2 >= 0) { + toc.children[h2].children.push({ + title: `Scene break ${scenebreak}`, + slug: slugify(`scene-break-${scenebreakIndex}`), + children: [], + }); + } else { + toc.children.push({ + title: `Scene break ${scenebreak}`, + slug: slugify(`scene-break-${scenebreakIndex}`), + children: [], + }); + } + } + }); + return toc; +} diff --git a/src/components/Panels/ContentPanel.tsx b/src/components/Panels/ContentPanel.tsx index 5b0dfa5..513f864 100644 --- a/src/components/Panels/ContentPanel.tsx +++ b/src/components/Panels/ContentPanel.tsx @@ -12,12 +12,15 @@ export enum ContentPanelWidthSizes { export default function ContentPanel(props: ContentPanelProps): JSX.Element { const width = props.width ? props.width : ContentPanelWidthSizes.default; const widthCSS = - width === ContentPanelWidthSizes.default ? "max-w-[45rem]" : "w-full"; - const prose = props.autoformat ? "prose text-justify" : ""; + width === ContentPanelWidthSizes.default ? "max-w-2xl" : "w-full"; return (
    -
    +
    {props.children}
    diff --git a/src/components/Panels/MainPanel.tsx b/src/components/Panels/MainPanel.tsx index f1928fa..5ea88c6 100644 --- a/src/components/Panels/MainPanel.tsx +++ b/src/components/Panels/MainPanel.tsx @@ -117,6 +117,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element { onClick={() => appLayout.setMainPanelOpen(false)} /> + {/* + appLayout.setMainPanelOpen(false)} /> + + */} @@ -147,7 +151,7 @@ export default function MainPanel(props: MainPanelProps): JSX.Element { reduced={appLayout.mainPanelReduced && isDesktop} onClick={() => appLayout.setMainPanelOpen(false)} /> - + {/* appLayout.setMainPanelOpen(false)} /> + + */} appLayout.setMainPanelOpen(false)} /> + {/* + appLayout.setMainPanelOpen(false)} /> + + */} +
    )} + + {content.text_set.length > 0 && content.text_set[0].text && ( + <> + + 0 + ? prettyinlineTitle( + content.titles[0].pre_title, + content.titles[0].title, + content.titles[0].subtitle + ) + : prettySlug(content.slug) + } + /> + + )} ); const contentPanel = ( @@ -157,7 +176,7 @@ export default function ContentRead(props: ContentReadProps): JSX.Element { - {content.text_set.length > 0 && ( + {content.text_set.length > 0 && content.text_set[0].text && ( )}
    diff --git a/src/pages/contents/index.tsx b/src/pages/contents/index.tsx index be8b767..77fe5ed 100644 --- a/src/pages/contents/index.tsx +++ b/src/pages/contents/index.tsx @@ -3,7 +3,10 @@ import SubPanel from "components/Panels/SubPanel"; import ContentPanel, { ContentPanelWidthSizes, } from "components/Panels/ContentPanel"; -import { GetContentsQuery } from "graphql/operations-types"; +import { + GetContentsQuery, + GetWebsiteInterfaceQuery, +} from "graphql/operations-types"; import { getContents } from "graphql/operations"; import PanelHeader from "components/PanelComponents/PanelHeader"; import AppLayout from "components/AppLayout"; @@ -12,6 +15,7 @@ import { prettyinlineTitle, prettySlug } from "queries/helpers"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; import Select from "components/Select"; import { useEffect, useState } from "react"; +import Chip from "components/Chip"; interface ContentsProps extends AppStaticProps { contents: GetContentsQuery["contents"]["data"]; @@ -25,11 +29,11 @@ export default function Contents(props: ContentsProps): JSX.Element { const [groupingMethod, setGroupingMethod] = useState(-1); const [groups, setGroups] = useState( - getGroups(groupingMethod, contents) + getGroups(langui, groupingMethod, contents) ); useEffect(() => { - setGroups(getGroups(groupingMethod, contents)); + setGroups(getGroups(langui, groupingMethod, contents)); }, [langui, groupingMethod, contents]); const subPanel = ( @@ -61,9 +65,14 @@ export default function Contents(props: ContentsProps): JSX.Element { {name && (

    {name} + {`${items.length} ${ + items.length <= 1 + ? langui.result.toLowerCase() + : langui.results.toLowerCase() + }`}

    )}
    { }; function getGroups( + langui: GetWebsiteInterfaceQuery["websiteInterfaces"]["data"][number]["attributes"], groupByType: number, items: ContentsProps["contents"] ): GroupContentItems { @@ -150,11 +160,11 @@ function getGroups( typeGroup.set("Bakuken", []); typeGroup.set("YoRHa", []); typeGroup.set("YoRHa Boys", []); - typeGroup.set("No category", []); + typeGroup.set(langui.no_category, []); items.map((item) => { if (item.attributes.categories.data.length === 0) { - typeGroup.get("No category")?.push(item); + typeGroup.get(langui.no_category)?.push(item); } else { item.attributes.categories.data.map((category) => { typeGroup.get(category.attributes.name)?.push(item); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 374325c..5bdd564 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,146 +1,48 @@ import AppLayout from "components/AppLayout"; +import Markdawn from "components/Markdown/Markdawn"; 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 HomeProps extends AppStaticProps {} +interface HomeProps extends AppStaticProps { + post: GetPostQuery["posts"]["data"][number]["attributes"]; +} export default function Home(props: HomeProps): JSX.Element { + const { post } = props; const contentPanel = ( - -
    -
    -

    Accord’s Library

    -

    Discover • Analyse • Translate • Archive

    -
    - -

    What is this?

    -

    - Accord’s Library aims at gathering and archiving all of Yoko - Taro’s work. Yoko Taro is a Japanese video game director and - scenario writer. He is best-known for his work on the NieR and - Drakengard (Drag-on Dragoon) franchises. To complement his games, Yoko - Taro likes to publish side materials in the form of books, novellas, - artbooks, stage plays, manga, drama CDs, and comics. Those side - materials can be very difficult to find. His work goes all the way back - to 2003, and most of them are out of print after having been released - solely in Japan, sometimes in limited quantities. Their prices on the - second hand market have skyrocketed, ranging all the way to hundreds if - not thousand of dollars for the rarest items.  -

    -

    - This is where this library takes its meaning, in trying to help the - community grow by providing translators, writers, and wiki’s - contributors a simple way to access these records filled with stories, - artworks, and knowledge. -

    -

    - We are a small group of Yoko Taro’s fans that decided to join - forces and create a website and a community. Our motto is{" "} - Discover • Analyze • Translate • Archive (D.A.T.A. for - short). We started with the goal of gathering and archiving as much - side-materials/merch as possible. But since then, our ambition grew and - we decided to create a full-fledged website that will also include news - articles, lore, summaries, translations, and transcriptions. Hopefully - one day, we will be up there in the list of notable resources for - Drakengard and NieR fans. -

    -

    What’s on this website?

    -

    - - The Compendium - - : This is where we will list every NieR/DOD/other Yoko Tato merch, - games, books, novel, stage play, CD... well everything! For each, we - will provide photos and/or scans of the content, information about what - it is, when and how it was released, size, initial price... -

    -

    - - News - - : Yes because we also want to create our own content! So there you will - find translations, transcriptions, unboxing, news about future - merch/game releases, maybe some guides. We don’t see this website - as being purely a showcase of our work, but also of the community, and - as such, we will be accepting applications for becoming contributors on - the website. For the applicant, there is no deadline or article quota, - it merely means that we will have access to the website Post Writing - tools and will be able to submit a draft that can be published once - verified by an editor. Anyway, that’s at least the plan, we will - think more about this until the website’s official launch. -

    -

    - - Data - - : There we will publish lore/knowledge about the Yokoverse: Dictionary, - Timeline, Weapons Stories, Game summaries... We have not yet decided how - deep we want to go as they are already quite a few resources out there.{" "} -

    -

    - - - Gallery - - - : A fully tagged Danbooru-styled gallery with currently more than a - thousand unique artworks. If you are unfamiliar with this kind of - gallery, it comes with a powerful search function that allows you to - search for specific images: want to search for images with both Caim and - Inuart, just type{" "} - - - Caim Inuart - - - . If you want images of Devola OR Popola, you can use a comma{" "} - - - Popola,Devola - - - . You can also negate a tag: i.e. images of 9S without any pods around, - search for{" "} - - - 9S -Pods - - - . Anyway, there is a lot more to it, you can click on "Syntax - help" next to the Search button for even neater functions. Btw, you - can create an account to favorite, upvote/downvote posts, or if you want - to help tagging them. There isn’t currently a way for new users to - upload images, you’ll have to contact us first and we can decide - to enable this function on your account. -

    + + {post.translations.length > 0 && ( + + )} ); - return ; + return ( + 0 + ? post.translations[0].title + : prettySlug(post.slug) + } + contentPanel={contentPanel} + {...props} + /> + ); } export const getStaticProps: GetStaticProps = async (context) => { const props: HomeProps = { ...(await getAppStaticProps(context)), + post: ( + await getPost({ + slug: "home", + language_code: context.locale || "en", + }) + ).posts.data[0].attributes, }; return { props: props, diff --git a/src/pages/library/[slug].tsx b/src/pages/library/[slug].tsx index d37c98a..7fcd1fe 100644 --- a/src/pages/library/[slug].tsx +++ b/src/pages/library/[slug].tsx @@ -218,13 +218,11 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element {
    {item.categories.data.length > 0 && ( -
    +

    {langui.categories}

    -
    +
    {item.categories.data.map((category) => ( - - {category.attributes.short} - + {category.attributes.name} ))}
    diff --git a/src/pages/library/index.tsx b/src/pages/library/index.tsx index ed121d9..37e6008 100644 --- a/src/pages/library/index.tsx +++ b/src/pages/library/index.tsx @@ -17,6 +17,7 @@ import { useEffect, useState } from "react"; import { convertPrice, prettyDate, prettyinlineTitle } from "queries/helpers"; import Switch from "components/Switch"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; +import Chip from "components/Chip"; interface LibraryProps extends AppStaticProps { items: GetLibraryItemsPreviewQuery["libraryItems"]["data"]; @@ -116,9 +117,14 @@ export default function Library(props: LibraryProps): JSX.Element { {name && (

    {name} + {`${items.length} ${ + items.length <= 1 + ? langui.result.toLowerCase() + : langui.results.toLowerCase() + }`}

    )}
    { if (item.attributes.categories.data.length === 0) { - typeGroup.get("No category")?.push(item); + typeGroup.get(langui.no_category)?.push(item); } else { item.attributes.categories.data.map((category) => { typeGroup.get(category.attributes.name)?.push(item); diff --git a/src/pages/wiki/chronology.tsx b/src/pages/wiki/chronology.tsx index 1a58ac2..b006c03 100644 --- a/src/pages/wiki/chronology.tsx +++ b/src/pages/wiki/chronology.tsx @@ -19,14 +19,12 @@ import { useRouter } from "next/router"; import ReactTooltip from "react-tooltip"; import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; -interface DataChronologyProps extends AppStaticProps { +interface ChronologyProps extends AppStaticProps { chronologyItems: GetChronologyItemsQuery["chronologyItems"]["data"]; chronologyEras: GetErasQuery["chronologyEras"]["data"]; } -export default function DataChronology( - props: DataChronologyProps -): JSX.Element { +export default function Chronology(props: ChronologyProps): JSX.Element { useTesting(props); const { chronologyItems, chronologyEras } = props; @@ -133,7 +131,7 @@ export default function DataChronology( } export const getStaticProps: GetStaticProps = async (context) => { - const props: DataChronologyProps = { + const props: ChronologyProps = { ...(await getAppStaticProps(context)), chronologyItems: ( await getChronologyItems({ @@ -148,7 +146,7 @@ export const getStaticProps: GetStaticProps = async (context) => { }; }; -function useTesting(props: DataChronologyProps) { +function useTesting(props: ChronologyProps) { const router = useRouter(); const { chronologyItems, chronologyEras } = props; chronologyEras.map((era) => { diff --git a/src/pages/wiki/index.tsx b/src/pages/wiki/index.tsx index 1b0b1f1..463b482 100644 --- a/src/pages/wiki/index.tsx +++ b/src/pages/wiki/index.tsx @@ -6,7 +6,7 @@ import { AppStaticProps, getAppStaticProps } from "queries/getAppStaticProps"; interface WikiProps extends AppStaticProps {} -export default function Hubs(props: WikiProps): JSX.Element { +export default function Wiki(props: WikiProps): JSX.Element { const { langui } = props; const subPanel = ( diff --git a/src/queries/helpers.ts b/src/queries/helpers.ts index 6e30470..bbf5786 100644 --- a/src/queries/helpers.ts +++ b/src/queries/helpers.ts @@ -256,3 +256,20 @@ export function sortContent( return 0; }); } + +export function slugify(str: string): string { + return str + .replace(/[ÀÁÂÃÄÅàáâãäåæÆ]/g, "a") + .replace(/[çÇ]/g, "c") + .replace(/[ðÐ]/g, "d") + .replace(/[ÈÉÊËéèêë]/g, "e") + .replace(/[ÏïÎîÍíÌì]/g, "i") + .replace(/[Ññ]/g, "n") + .replace(/[øØœŒÕõÔôÓóÒò]/g, "o") + .replace(/[ÜüÛûÚúÙù]/g, "u") + .replace(/[ŸÿÝý]/g, "y") + .replace(/[^a-z0-9- ]/gi, "") + .trim() + .replace(/ /gi, "-") + .toLowerCase(); +} diff --git a/src/tailwind.css b/src/tailwind.css index e1aa100..a17a243 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -24,6 +24,10 @@ @apply bg-dark text-light; } + mark { + @apply bg-mid px-2 + } + /* SCROLLBARS STYLING */ * { @@ -42,45 +46,82 @@ @apply bg-dark rounded-full border-[3px] border-solid border-light; } - /* CHANGE PROSE DEFAULTS */ + /* CHANGE FORMATTED DEFAULTS */ - .prose, - .prose p, - .prose h1, - .prose h2, - .prose h3, - .prose h4, - .prose h5, - .prose h6, - .prose a, - .prose strong { - @apply text-black; + .formatted h1, + .formatted h2, + .formatted h3, + .formatted h4, + .formatted h5, + .formatted h6 { + @apply text-center; } - .prose a { - @apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark; + .formatted h1 { + @apply text-4xl my-16; } - .prose footer { + .formatted h1 + h2 { + @apply -mt-10; + } + + .formatted h2 { + @apply text-3xl my-12; + } + + .formatted h2 + h3 { + @apply -mt-8; + } + + .formatted h3 { + @apply text-2xl my-8; + } + + .formatted h3 + h4 { + @apply -mt-6; + } + + .formatted h4 { + @apply text-xl my-6; + } + + .formatted h5 { + @apply text-lg my-4; + } + + .formatted p, + .formatted strong { + @apply my-2 text-justify; + } + + .formatted footer { @apply border-t-[3px] border-dotted pt-6; } - .prose footer > div { + .formatted footer > div { @apply my-2 px-6 py-4 rounded-xl; } - .prose footer > div:target { + .formatted footer > div:target { @apply bg-mid shadow-inner-sm shadow-shade; } - .prose li::marker { + .formatted li::marker { @apply text-dark; } - .prose blockquote { + .formatted blockquote { @apply border-l-dark; } + .formatted ul { + @apply list-disc pl-4; + } + + .formatted ol { + @apply list-decimal pl-4; + } + /* INPUT */ input { diff --git a/tailwind.config.js b/tailwind.config.js index 4a84db7..0f9f6b4 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -72,7 +72,6 @@ module.exports = { }, }, plugins: [ - require("@tailwindcss/typography"), plugin(function ({ addUtilities }) { addUtilities({