Skip to content

Commit

Permalink
faq page + mdx infra (#197)
Browse files Browse the repository at this point in the history
#35

- Sets up infra for reading files from the repo
- Adds components for rendering mdx pages
  - `MdxContent`: Root component for rendering the mdx page
- `MdxPageTitle`: For showing the title of the page as well as when it
was last updated
- `MdxAccordion`: For rendering an accordion on the page, used by the
FAQ page
- Adds initial faq page + test content
  • Loading branch information
codemonkey800 authored Dec 1, 2023
1 parent 5199c14 commit 6a7b5e3
Show file tree
Hide file tree
Showing 14 changed files with 670 additions and 108 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.accordion {
h2 {
@apply text-sds-header-xs leading-sds-header-xs font-semibold;
@apply mt-sds-l mb-sds-xxs;
}

h3 {
@apply text-sds-header-xxs leading-sds-header-xxs font-semibold;
@apply mt-sds-m mb-sds-xxxs;
}

p {
@apply mb-sds-m;
}

section {
&:has(> h2) {
@apply text-sds-body-xs leading-sds-body-xs;
}

&:has(> h3) {
@apply text-sds-body-xxs leading-sds-body-xxs;
}
}

ul,
ol {
@apply space-y-sds-xs ml-4;
}

ul {
@apply list-disc;
}

ol {
@apply list-decimal;
}

li ol {
@apply ml-sds-l mt-sds-xs;
}
}
28 changes: 28 additions & 0 deletions frontend/packages/data-portal/app/components/MDX/MdxAccordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {
Accordion,
AccordionDetails,
AccordionHeader,
} from '@czi-sds/components'
import { ReactNode } from 'react'

import styles from './MdxAccodion.module.css'

export function MdxAccordion({
children,
title,
}: {
children: ReactNode
title: string
}) {
return (
<Accordion
className={styles.accordion}
id={`accordion-${title}`}
title={title}
useDivider
>
<AccordionHeader>{title}</AccordionHeader>
<AccordionDetails>{children}</AccordionDetails>
</Accordion>
)
}
24 changes: 24 additions & 0 deletions frontend/packages/data-portal/app/components/MDX/MdxContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { MDXRemote } from 'next-mdx-remote'

import { useMdxFile } from 'app/hooks/useMdxFile'

import { MdxAccordion } from './MdxAccordion'
import { MdxPageTitle } from './MdxPageTitle'

export function MdxContent() {
const { content } = useMdxFile()

return (
<div className="py-sds-xxl px-sds-xl flex flex-auto justify-center">
<div className="w-full max-w-mdx-content">
<MDXRemote
{...content}
components={{
Accordion: MdxAccordion,
PageTitle: MdxPageTitle,
}}
/>
</div>
</div>
)
}
24 changes: 24 additions & 0 deletions frontend/packages/data-portal/app/components/MDX/MdxPageTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import dayjs from 'dayjs'
import { ReactNode } from 'react'

import { useI18n } from 'app/hooks/useI18n'
import { useMdxFile } from 'app/hooks/useMdxFile'

export function MdxPageTitle({ children }: { children: ReactNode }) {
const { t } = useI18n()
const { lastModified } = useMdxFile()

return (
<div className="flex flex-col gap-sds-xs mb-sds-xxl">
<h1 className="text-sds-header-xxl leading-sds-header-xxl font-semibold">
{children}
</h1>

{lastModified && (
<p className="text-sds-body-xxs leading-sds-body-xxs text-sds-gray-600">
{t('lastUpdated')}: {dayjs(lastModified).format('MMMM DD, YYYY')}
</p>
)}
</div>
)
}
1 change: 1 addition & 0 deletions frontend/packages/data-portal/app/components/MDX/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './MdxContent'
9 changes: 9 additions & 0 deletions frontend/packages/data-portal/app/hooks/useMdxFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { MDXRemoteSerializeResult } from 'next-mdx-remote'
import { useTypedLoaderData } from 'remix-typedjson'

export function useMdxFile() {
return useTypedLoaderData<{
content: MDXRemoteSerializeResult
lastModified: Date | null
}>()
}
9 changes: 7 additions & 2 deletions frontend/packages/data-portal/app/routes/faq.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { Demo } from 'app/components/Demo'
import { MdxContent } from 'app/components/MDX'
import { getRepoFileContentResponse } from 'app/utils/repo.server'

export async function loader() {
return getRepoFileContentResponse('website-docs/faq.mdx')
}

export default function FaqPage() {
return <Demo>FAQ Page</Demo>
return <MdxContent />
}
47 changes: 47 additions & 0 deletions frontend/packages/data-portal/app/utils/repo.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { AxiosResponse } from 'axios'
import { serialize } from 'next-mdx-remote/serialize'
import { Octokit } from 'octokit'
import sectionize from 'remark-sectionize'
import { typedjson } from 'remix-typedjson'

import { axios } from 'app/axios'

const octokit = new Octokit()

export interface RepoFile {
content: string
lastModified: Date | null
}

export async function getRepoFileContent(path: string): Promise<RepoFile> {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
const response = (await axios.get(
`https://raw.githubusercontent.com/chanzuckerberg/cryoet-data-portal/main/${path}`,
)) as AxiosResponse

const data = await octokit.rest.repos.listCommits({
owner: 'chanzuckerberg',
repo: 'cryoet-data-portal',
per_page: 1,
})

const date = data.data[0].commit.committer?.date

return {
content: response.data as string,
lastModified: date ? new Date(date) : null,
}
}

export async function getRepoFileContentResponse(path: string) {
const { content, lastModified } = await getRepoFileContent(path)

return typedjson({
lastModified,
content: await serialize(content, {
mdxOptions: {
remarkPlugins: [sectionize],
},
}),
})
}
6 changes: 6 additions & 0 deletions frontend/packages/data-portal/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ declare namespace NodeJS {
readonly SPLIT_IO_SERVER_KEY: string
}
}

declare module 'remark-sectionize' {
const plugin: import('unified').Pluggable
// eslint-disable-next-line import/no-default-export
export default plugin
}
4 changes: 4 additions & 0 deletions frontend/packages/data-portal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"chokidar": "^3.5.3",
"clsx": "^2.0.0",
"compression": "^1.7.4",
"dayjs": "^1.11.10",
"express": "^4.18.2",
"framer-motion": "^10.16.4",
"graphql": "^16.8.1",
Expand All @@ -64,13 +65,16 @@
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"morgan": "^1.10.0",
"next-mdx-remote": "^4.4.1",
"octokit": "^3.1.2",
"pretty-bytes": "^6.1.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^13.5.0",
"react-is": "^18.2.0",
"react-transition-group": "^4.4.5",
"remark-sectionize": "^2.0.0",
"remix-i18next": "^5.4.0",
"remix-typedjson": "^0.2.2",
"source-map-support": "^0.5.21",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"keyPhoto": "key photo",
"lastModified": "Last Modified: {{date}}",
"lastModifiedBlank": "Last Modified",
"lastUpdated": "Last Updated",
"license": "License",
"limitOneValuePerField": "Limit one value per field",
"meetsAll": "Meets all",
Expand Down
1 change: 1 addition & 0 deletions frontend/packages/data-portal/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default {

maxWidth: {
content: '1600px',
'mdx-content': '800px',
},

// overwrite faulty SDS line heights
Expand Down
Loading

0 comments on commit 6a7b5e3

Please sign in to comment.