1
0
Fork 0

chore(dev): Changed to prebuild and ReadMore

This commit is contained in:
joostdecock 2023-05-21 09:41:20 +02:00
parent 6604fdaed3
commit 8dff0b8f1b
8 changed files with 160 additions and 101 deletions

View file

@ -16,6 +16,7 @@ import {
DocsIcon, DocsIcon,
WrenchIcon, WrenchIcon,
FreeSewingIcon, FreeSewingIcon,
HeartIcon,
} from 'shared/components/icons.mjs' } from 'shared/components/icons.mjs'
import { Ribbon } from 'shared/components/ribbon.mjs' import { Ribbon } from 'shared/components/ribbon.mjs'
import { ModalThemePicker, ns as themeNs } from 'shared/components/modal/theme-picker.mjs' import { ModalThemePicker, ns as themeNs } from 'shared/components/modal/theme-picker.mjs'
@ -33,6 +34,14 @@ export const ns = ['header', 'sections', ...themeNs]
* for translators * for translators
* how to work as a team * how to work as a team
* about freesewing * about freesewing
*
*
* designers
* contributors
* api
* translation
* infra
* content
* */ * */
const NavIcons = ({ setModal, setSearch }) => { const NavIcons = ({ setModal, setSearch }) => {
@ -45,54 +54,44 @@ const NavIcons = ({ setModal, setSearch }) => {
<MenuIcon className={iconSize} /> <MenuIcon className={iconSize} />
</NavButton> </NavButton>
<NavSpacer /> <NavSpacer />
<NavButton href="/developers" label="Developers" color={colors[1]}> <NavButton href="/api" label="API Docs" color={colors[1]} extraClasses="hidden lg:flex">
<CodeIcon className={iconSize} />
</NavButton>
<NavButton
href="/designers"
label="Designers"
color={colors[2]}
extraClasses="hidden lg:flex"
>
<DesignIcon className={iconSize} />
</NavButton>
<NavButton href="/writers" label="Writers" color={colors[3]} extraClasses="hidden lg:flex">
<DocsIcon className={iconSize} /> <DocsIcon className={iconSize} />
</NavButton> </NavButton>
<NavButton <NavButton href="/design" label="Design" color={colors[2]} extraClasses="hidden lg:flex">
href="/translators" <DesignIcon className={iconSize} />
label="Translators" </NavButton>
color={colors[4]} <NavButton href="/contribute" label="Contribute" color={colors[3]}>
extraClasses="hidden lg:flex" <CodeIcon className={iconSize} />
> </NavButton>
<NavButton href="/i18n" label="Translate" color={colors[4]} extraClasses="hidden lg:flex">
<I18nIcon className={iconSize} /> <I18nIcon className={iconSize} />
</NavButton> </NavButton>
<NavButton <NavButton
href="/infrastructure" href="/infra"
label="Infrastrucure" label="Infrastrucure"
color={colors[5]} color={colors[5]}
extraClasses="hidden lg:flex" extraClasses="hidden lg:flex"
> >
<WrenchIcon className={iconSize} stroke={1.5} /> <WrenchIcon className={iconSize} stroke={1.5} />
</NavButton> </NavButton>
<NavButton href="/teamwork" label="Teamwork" color={colors[6]} extraClasses="hidden lg:flex"> <NavSpacer />
<CommunityIcon className={iconSize} stroke={1.5} /> <NavButton href="/about" label="About" color={colors[6]}>
<FreeSewingIcon className={iconSize} />
</NavButton>
<NavButton href="/support" label="Support" color={colors[7]}>
<HeartIcon className={iconSize} fill />
</NavButton> </NavButton>
<NavSpacer /> <NavSpacer />
<NavButton <NavButton
onClick={() => setModal(<ModalThemePicker />)} onClick={() => setModal(<ModalThemePicker />)}
label={t('header:theme')} label={t('header:theme')}
color={colors[7]} color={colors[8]}
> >
<ThemeIcon className={iconSize} /> <ThemeIcon className={iconSize} />
</NavButton> </NavButton>
<NavButton onClick={() => setSearch(true)} label={t('header:search')} color={colors[8]}> <NavButton onClick={() => setSearch(true)} label={t('header:search')} color={colors[9]}>
<SearchIcon className={iconSize} /> <SearchIcon className={iconSize} />
</NavButton> </NavButton>
<NavSpacer />
<NavButton href="/about" label="About" color={colors[9]}>
<FreeSewingIcon className={iconSize} />
</NavButton>
</> </>
) )
} }

View file

@ -18,40 +18,46 @@ export const ns = ['account', 'sections', 'design', 'tags']
const sitePages = () => { const sitePages = () => {
const pages = { const pages = {
// Top-level pages that are the sections menu // Top-level pages that are the sections menu
developers: { api: {
t: 'For all Developers', t: 'API Documentation',
s: 'developers', s: 'api',
o: 10, o: 10,
}, },
designers: { design: {
t: 'For Pattern Designers & Coders', t: 'Design Sewing Patterns',
s: 'designers', s: 'design',
o: 10,
},
contribute: {
t: 'Contribute to FreeSewing',
s: 'contribute',
o: 20, o: 20,
}, },
writers: { i18n: {
t: 'For Writers', t: 'Help Translate FreeSewing',
s: 'writers', s: 'i18n',
o: 30,
},
translators: {
t: 'For Translators',
s: 'translators',
o: 40, o: 40,
}, },
infrastructure: { infra: {
t: 'FreeSewing Infrastructure', t: 'FreeSewing Infrastructure',
s: 'infrastructure', s: 'infra',
o: 50, o: 50,
}, },
teamwork: {
t: 'Open Source & Teamwork',
s: 'teamwork',
o: 60,
},
about: { about: {
t: 'About FreeSewing', t: 'About FreeSewing',
s: 'about', s: 'about',
o: 99, o: 60,
},
support: {
t: 'Support FreeSewing',
s: 'support',
o: 70,
},
sitemap: {
t: 'Sitemap',
s: 'sitemap',
o: 70,
h: 1,
}, },
} }
return pages return pages
@ -78,7 +84,8 @@ const createSections = (nav) => {
return orderBy(sections, ['o', 't']) return orderBy(sections, ['o', 't'])
} }
export const useNavigation = ({ path, locale = 'en' }) => { export const useNavigation = (params = {}) => {
const { path = [], locale = 'en' } = params
const nav = { ...pbn[locale], ...sitePages() } const nav = { ...pbn[locale], ...sitePages() }
// Hide top-level documentation entries // Hide top-level documentation entries
for (const page of ['tutorials', 'guides', 'howtos', 'reference', 'training']) { for (const page of ['tutorials', 'guides', 'howtos', 'reference', 'training']) {
@ -95,5 +102,6 @@ export const useNavigation = ({ path, locale = 'en' }) => {
slug: path.join('/'), slug: path.join('/'),
nav: path.length > 1 ? get(nav, path[0]) : path.length === 0 ? sections : nav[path[0]], nav: path.length > 1 ? get(nav, path[0]) : path.length === 0 ? sections : nav[path[0]],
title: crumbs.length > 0 ? crumbs.slice(-1)[0].t : '', title: crumbs.length > 0 ? crumbs.slice(-1)[0].t : '',
siteNav: nav,
} }
} }

View file

@ -16,7 +16,8 @@
"scripts": { "scripts": {
"build": "next build", "build": "next build",
"cibuild": "yarn build && node scripts/algolia.mjs", "cibuild": "yarn build && node scripts/algolia.mjs",
"clean": "rimraf prebuild/* && rimraf public/locales/*/* && rimraf public/feeds/*", "clean": "rimraf prebuild/* && rimraf public/locales/*/* && rimraf public/feeds/* && rimraf ../shared/prebuild/data/*",
"predev": "FAST=1 SITE=dev node --experimental-json-modules ../shared/prebuild/index.mjs",
"dev": "next dev -p 8000", "dev": "next dev -p 8000",
"develop": "next dev -p 8000", "develop": "next dev -p 8000",
"i18n": "SITE=dev node ../shared/prebuild/i18n-only.mjs", "i18n": "SITE=dev node ../shared/prebuild/i18n-only.mjs",

View file

@ -28,7 +28,7 @@ const DocsPage = ({ page, slug }) => {
import(`../../../markdown/dev/${slug}/en.md`).then((mod) => { import(`../../../markdown/dev/${slug}/en.md`).then((mod) => {
setFrontmatter(mod.frontmatter) setFrontmatter(mod.frontmatter)
const Component = mod.default const Component = mod.default
setMDX(<Component components={components} />) setMDX(<Component components={components('dev')} />)
}) })
} }
loadMDX() loadMDX()

View file

@ -10,34 +10,44 @@ import { ControlTip } from '../control/tip.mjs'
import { Legend } from './legend.mjs' import { Legend } from './legend.mjs'
import { V3Wip } from '../v3-wip.mjs' import { V3Wip } from '../v3-wip.mjs'
export const components = { export const components = (site = 'org') => {
// Custom components const base = {
Method: HttpMethod, // Custom components
StatusCode: HttpStatusCode, Comment: (props) => <Popout {...props} comment />,
Comment: (props) => <Popout {...props} comment />, Fixme: (props) => <Popout {...props} fixme />,
Fixme: (props) => <Popout {...props} fixme />, Link: (props) => <Popout {...props} link />,
Link: (props) => <Popout {...props} link />, Note: (props) => <Popout {...props} note />,
Note: (props) => <Popout {...props} note />, ReadMore: (props) => <ReadMore {...props} site={site} />,
ReadMore, Related: (props) => <Popout {...props} related />,
Related: (props) => <Popout {...props} related />, Tip: (props) => <Popout {...props} tip />,
Tip: (props) => <Popout {...props} tip />, Warning: (props) => <Popout {...props} warning />,
Warning: (props) => <Popout {...props} warning />, YouTube,
YouTube, pre: (props) => <Highlight {...props} />,
pre: (props) => <Highlight {...props} />, // This Figure component causes hydration errors
// This Figure component causes hydration errors //img: Figure,
//img: Figure, table: (props) => (
table: (props) => ( <table {...props} className="mdx-table table-auto w-full">
<table {...props} className="mdx-table table-auto w-full"> {props.children}
{props.children} </table>
</table> ),
), Tab,
Tab, Tabs,
Tabs, ControlTip,
ControlTip, Example,
Example, }
PatternDocs: V3Wip,
PatternOptions: V3Wip, return site === 'dev'
PatternMeasurements: V3Wip, ? {
Gauge: V3Wip, ...base,
Legend, Method: HttpMethod,
StatusCode: HttpStatusCode,
}
: {
...base,
PatternDocs: V3Wip,
PatternOptions: V3Wip,
PatternMeasurements: V3Wip,
Gauge: V3Wip,
Legend,
}
} }

View file

@ -3,29 +3,67 @@ import orderBy from 'lodash.orderby'
import Link from 'next/link' import Link from 'next/link'
import { useContext } from 'react' import { useContext } from 'react'
import { NavigationContext } from 'shared/context/navigation-context.mjs' import { NavigationContext } from 'shared/context/navigation-context.mjs'
import { useNavigation } from 'site/hooks/use-navigation.mjs'
const baseClasses =
'text-base-content no-underline inline-block hover:text-secondary hover:underline'
const classes = [
`text-3xl font-bold py-2 ${baseClasses} list-disc`,
`text-2xl font-bold py-1 ${baseClasses}`,
`text-xl font-medium ${baseClasses}`,
`text-lg font-medium ${baseClasses}`,
]
const getClasses = (level) => classes[level] || `text-normal font-regular ${baseClasses}`
// Helper method to filter out the real children // Helper method to filter out the real children
const order = (obj) => orderBy(obj, ['o', 't'], ['asc', 'asc']) const order = (obj) => orderBy(obj, ['o', 't'], ['asc', 'asc'])
const currentChildren = (current) => const currentChildren = (current) =>
Object.values(order(current)).filter((entry) => typeof entry === 'object') Object.values(order(current)).filter((entry) => typeof entry === 'object')
export const ReadMore = ({ app, recurse = 0 }) => { const getRoot = {
dev: (slug, nav) => {
if (!slug || slug === 'docs') return nav
if (slug.indexOf('/') === -1) return nav[slug]
return get(nav, slug.split('/'))
},
org: (slug, nav) => {
// Fixme: make this work for org
if (!slug || slug === 'docs') return nav
if (slug.indexOf('/') === -1) return nav[slug]
return get(nav, slug.split('/'))
},
}
export const ReadMore = ({
app,
recurse = 0,
root = false,
site = 'org',
level = 0,
pretty = false,
}) => {
const { nav, slug } = useContext(NavigationContext) const { nav, slug } = useContext(NavigationContext)
const { siteNav } = useNavigation()
// Deal with recurse not being a number // Deal with recurse not being a number
if (recurse) { if (recurse && recurse !== true) {
if (typeof recurse === 'number') recurse-- if (typeof recurse === 'number') recurse--
else recurse = 1 else recurse = 1
} }
const root = slug && slug !== 'docs' ? get(nav, slug.split('/').slice(1)) : nav // Deal with root being passed as true
if (root === true) root = ''
const tree = getRoot[site](root, siteNav)
const list = [] const list = []
for (const page of currentChildren(root)) { for (const page of currentChildren(tree)) {
list.push( list.push(
<li key={page.s}> <li key={page.s}>
<Link href={`/${page.s}`}>{page.t}</Link> <Link href={`/${page.s}`}>
{recurse > 0 ? <ReadMore app={app} slug={page.s} recurse={recurse} /> : null} <span className={getClasses(level)}>{page.t}</span>
</Link>
{recurse ? <ReadMore root={page.s} recurse={recurse} level={level + 1} /> : null}
</li> </li>
) )
} }

View file

@ -17,6 +17,7 @@ import {
I18nIcon, I18nIcon,
WrenchIcon, WrenchIcon,
FreeSewingIcon, FreeSewingIcon,
HeartIcon,
} from 'shared/components/icons.mjs' } from 'shared/components/icons.mjs'
import { Breadcrumbs } from 'shared/components/breadcrumbs.mjs' import { Breadcrumbs } from 'shared/components/breadcrumbs.mjs'
@ -25,13 +26,13 @@ export const ns = ['sections']
// List of icons matched to top-level slug // List of icons matched to top-level slug
export const icons = { export const icons = {
// FreeSewing.dev // FreeSewing.dev
developers: (className = '') => <CodeIcon className={className} />, api: (className = '') => <DocsIcon className={className} />,
designers: (className = '') => <DesignIcon className={className} />, design: (className = '') => <DesignIcon className={className} />,
writers: (className = '') => <DocsIcon className={className} />, contribute: (className = '') => <CodeIcon className={className} />,
translators: (className = '') => <I18nIcon className={className} />, i18n: (className = '') => <I18nIcon className={className} />,
infrastructure: (className = '') => <WrenchIcon className={className} stroke={1.5} />, infra: (className = '') => <WrenchIcon className={className} stroke={1.5} />,
teamwork: (className = '') => <CommunityIcon className={className} stroke={1.5} />,
about: (className = '') => <FreeSewingIcon className={className} stroke={1.5} />, about: (className = '') => <FreeSewingIcon className={className} stroke={1.5} />,
support: (className = '') => <HeartIcon className={className} stroke={1.5} fill />,
// FreeSewing.org // FreeSewing.org
account: (className = '') => <UserIcon className={className} />, account: (className = '') => <UserIcon className={className} />,

View file

@ -10,15 +10,15 @@ import { prebuildDesigns } from './designs.mjs'
import { generateOgImage } from './og/index.mjs' import { generateOgImage } from './og/index.mjs'
const run = async () => { const run = async () => {
const linter = process.env.LINTER ? true : false if (process.env.LINTER) return true
if (linter) return true const FAST = process.env.FAST ? true : false
const SITE = process.env.SITE || 'lab' const SITE = process.env.SITE || 'lab'
prebuildDesigns() if (!FAST) prebuildDesigns()
if (['org', 'dev'].includes(SITE)) { if (['org', 'dev'].includes(SITE)) {
await prebuildGitData(SITE) if (!FAST) await prebuildGitData(SITE)
const docPages = await prebuildDocs(SITE) const docPages = await prebuildDocs(SITE)
prebuildNavigation(docPages, false, SITE) prebuildNavigation(docPages, false, SITE)
if (process.env.GENERATE_OG_IMAGES) { if (!FAST && process.env.GENERATE_OG_IMAGES) {
// Create og image for the home page // Create og image for the home page
await generateOgImage({ await generateOgImage({
lang: 'en', lang: 'en',
@ -42,8 +42,10 @@ const run = async () => {
if (SITE === 'org') await prebuildOrg() if (SITE === 'org') await prebuildOrg()
await prebuildI18n(SITE) await prebuildI18n(SITE)
await prebuildContributors(SITE) if (!FAST) {
await prebuildPatrons(SITE) await prebuildContributors(SITE)
await prebuildPatrons(SITE)
}
console.log() console.log()
} }