1
0
Fork 0

use single source of truth for navigation

This commit is contained in:
Enoch Riese 2022-05-31 15:31:29 -04:00
parent 777b40c414
commit eedcae7740
4 changed files with 32 additions and 37 deletions

View file

@ -20,7 +20,7 @@ const PatternPicker = ({ app }) => {
<span>{t('designs')}</span> <span>{t('designs')}</span>
</div> </div>
<ul tabIndex="0" className="p-2 shadow menu dropdown-content bg-base-100 rounded-box w-52 overflow-y-scroll navdrop"> <ul tabIndex="0" className="p-2 shadow menu dropdown-content bg-base-100 rounded-box w-52 overflow-y-scroll navdrop">
{Object.keys(app.patterns).map(section => ( {Object.keys(app.navigation).map(section => (
<React.Fragment key={section}> <React.Fragment key={section}>
<li className={` <li className={`
capitalize font-bold text-base-content text-center capitalize font-bold text-base-content text-center
@ -28,17 +28,18 @@ const PatternPicker = ({ app }) => {
`}> `}>
{t(app.navigation[section].__title)} {t(app.navigation[section].__title)}
</li> </li>
{app.patterns[section].map(pattern => ( {Object.keys(app.navigation[section]).filter((p)=>!p.startsWith('__')).map(pattern => {
return (
<li key={pattern}> <li key={pattern}>
<Link href={formatVersionUri(version, pattern)}> <Link href={app.navigation[section][pattern].__slug}>
<button className="btn btn-ghost"> <button className="btn btn-ghost">
<span className="text-base-content"> <span className="text-base-content">
{pattern} {app.navigation[section][pattern].__title}
</span> </span>
</button> </button>
</Link> </Link>
</li> </li>
))} )})}
</React.Fragment> </React.Fragment>
))} ))}
</ul> </ul>

View file

@ -6,6 +6,7 @@ import patterns from 'shared/config/designs.json'
// Locale and translation // Locale and translation
import { useTranslation } from 'next-i18next' import { useTranslation } from 'next-i18next'
import { capitalize } from 'shared/utils' import { capitalize } from 'shared/utils'
import { formatVersionUri } from '../components/version-picker.js'
import useVersion from 'site/hooks/useVersion.js' import useVersion from 'site/hooks/useVersion.js'
// Initial navigation // Initial navigation
@ -42,7 +43,7 @@ const initialNavigation = (t, version) => {
__title: capitalize(design), __title: capitalize(design),
__order: design, __order: design,
__linktitle: capitalize(design), __linktitle: capitalize(design),
__slug: `v/${version}/${design}` __slug: formatVersionUri(version,design)
} }
} }
} }

View file

@ -20,17 +20,17 @@ const links = (section, list, version) => list.map(design => (
</li> </li>
)) ))
const icons = { export const default_icons = {
accessories: (className='') => <TutorialIcon className={className}/>, accessories: (className='') => <TutorialIcon className={className}/>,
blocks: (className='') => <BoxIcon className={className}/>, blocks: (className='') => <BoxIcon className={className}/>,
garments: (className='') => <DesignIcon className={className}/>, garments: (className='') => <DesignIcon className={className}/>,
utilities: (className='') => <CogIcon className={className}/>, utilities: (className='') => <CogIcon className={className}/>,
} }
const Section = ({ section, version, patterns }) => { const Section = ({ section, version, patterns, icons }) => {
const { t } = useTranslation(['patterns']) const { t } = useTranslation(['patterns'])
return patterns.map(design => ( return patterns.map(design => (
<Link href={formatVersionUri(version, design)}> <Link href={design.__slug} key={design.__order}>
<a className={` <a className={`
text-secondary border rounded-lg text-secondary border rounded-lg
flex flex-col gap-1 px-4 py-2 grow justify-between text-2xl flex flex-col gap-1 px-4 py-2 grow justify-between text-2xl
@ -43,17 +43,17 @@ const Section = ({ section, version, patterns }) => {
`}> `}>
<div className="flex flex-row items-center justify-items-start w-full"> <div className="flex flex-row items-center justify-items-start w-full">
<span className="text-2xl md:text-3xl lg:text-4xl xl:text-4xl 2xl:text-5xl font-bold grow capitalize"> <span className="text-2xl md:text-3xl lg:text-4xl xl:text-4xl 2xl:text-5xl font-bold grow capitalize">
{t(`patterns:${design}.t`)} {design.__title}
</span> </span>
{icons[section]("w-12 h-12 md:h-20 md:w-20 xl:w-32 xl:h-32 shrink-0")} {icons[section] && icons[section]("w-12 h-12 md:h-20 md:w-20 xl:w-32 xl:h-32 shrink-0")}
</div> </div>
<span className="text-xl md:text-2xl xl:text-3xl pb-2 xl:pb-4 2xl:text-4xl">{t(`patterns:${design}.d`)}</span> <span className="text-xl md:text-2xl xl:text-3xl pb-2 xl:pb-4 2xl:text-4xl">{t(`patterns:${design.__order}.d`)}</span>
</a> </a>
</Link> </Link>
)) ))
} }
const PatternListPageTemplate = ({ section=false, version=false }) => { const PatternListPageTemplate = ({ section=false, version=false, icons=default_icons }) => {
const app = useApp() const app = useApp()
const { t } = useTranslation(['app']) const { t } = useTranslation(['app'])
@ -61,6 +61,8 @@ const PatternListPageTemplate = ({ section=false, version=false }) => {
? app.navigation[section].__title ? app.navigation[section].__title
: t('designs') : t('designs')
const sectionPatterns = section ? Object.values(app.navigation[section]).filter((o)=> typeof o == 'object') : [];
return ( return (
<Page app={app} title={`FreeSewing Lab: ${formatVersionTitle(version)}`} layout={Layout}> <Page app={app} title={`FreeSewing Lab: ${formatVersionTitle(version)}`} layout={Layout}>
<Head> <Head>
@ -78,18 +80,18 @@ const PatternListPageTemplate = ({ section=false, version=false }) => {
</Head> </Head>
<div className="max-w-7xl m-auto py-20 md:py-36 min-h-screen"> <div className="max-w-7xl m-auto py-20 md:py-36 min-h-screen">
<section className="px-8"> <section className="px-8">
<PageTitle app={app} slug={'/'+section} title={title} /> <PageTitle app={app} slug={section ? app.navigation[section].__slug : '/' } title={title} />
{section { section
? ( ? (
<div className="flex flex-row flex-wrap gap-4 items-center justify-center my-8"> <div className="flex flex-row flex-wrap gap-4 items-center justify-center my-8">
<Section section={section} version={version} patterns={app.patterns[section]} /> <Section section={section} version={version} patterns={sectionPatterns} icons={icons} />
</div> </div>
) )
: Object.keys(app.patterns).map(section => ( : Object.keys(app.patterns).map(section => (
<div key={section} className="mb-12"> <div key={section} className="mb-12">
<h2 className="pb-0">{app.navigation[section].__title}</h2> <h2 className="pb-0">{app.navigation[section].__title}</h2>
<div className="flex flex-row flex-wrap gap-4 items-center justify-center my-8"> <div className="flex flex-row flex-wrap gap-4 items-center justify-center my-8">
<Section {...{section, version}} patterns={app.patterns[section]} /> <Section {...{section, version, icons}} patterns={sectionPatterns} />
</div> </div>
</div> </div>
)) ))

View file

@ -8,12 +8,9 @@ import DocsIcon from 'shared/components/icons/docs.js'
import DesignIcon from 'shared/components/icons/design.js' import DesignIcon from 'shared/components/icons/design.js'
import BoxIcon from 'shared/components/icons/box.js' import BoxIcon from 'shared/components/icons/box.js'
import CogIcon from 'shared/components/icons/cog.js' import CogIcon from 'shared/components/icons/cog.js'
import UserIcon from 'shared/components/icons/user.js'
import CommunityIcon from 'shared/components/icons/community.js'
import ShowcaseIcon from 'shared/components/icons/camera.js'
// Don't show children for blog and showcase posts // Don't show children for blog and showcase posts
const keepClosed = ['blog', 'showcase' ] const keepClosed = ['blog', 'showcase', ]
// TODO: For now we force tailwind to pickup these styles // TODO: For now we force tailwind to pickup these styles
// At some point this should 'just work' though, but let's not worry about it now // At some point this should 'just work' though, but let's not worry about it now
@ -24,19 +21,14 @@ const force = [
// List of icons matched to top-level slug // List of icons matched to top-level slug
const icons = { const icons = {
accessories: (className='') => <TutorialIcon className={className}/>,
account: (className='') => <UserIcon className={className}/>,
blocks: (className='') => <BoxIcon className={className}/>,
blog: (className='') => <RssIcon className={className}/>, blog: (className='') => <RssIcon className={className}/>,
community: (className='') => <CommunityIcon className={className}/>, tutorials: (className='') => <TutorialIcon className={className}/>,
designs: (className='') => <DesignIcon className={className}/>,
docs: (className='') => <DocsIcon className={className}/>,
garments: (className='') => <DesignIcon className={className}/>,
guides: (className='') => <GuideIcon className={className}/>, guides: (className='') => <GuideIcon className={className}/>,
howtos: (className='') => <HelpIcon className={className}/>, howtos: (className='') => <HelpIcon className={className}/>,
reference: (className='') => <DocsIcon className={className}/>, reference: (className='') => <DocsIcon className={className}/>,
showcase: (className='') => <ShowcaseIcon className={className}/>, accessories: (className='') => <TutorialIcon className={className}/>,
tutorials: (className='') => <TutorialIcon className={className}/>, blocks: (className='') => <BoxIcon className={className}/>,
garments: (className='') => <DesignIcon className={className}/>,
utilities: (className='') => <CogIcon className={className}/>, utilities: (className='') => <CogIcon className={className}/>,
} }
@ -94,7 +86,7 @@ const SubLevel = ({ nodes={}, active }) => (
hover:cursor-row-resize hover:cursor-row-resize
items-center items-center
`}> `}>
<Link href={`/${child.__slug}`}> <Link href={`${child.__slug}`}>
<a title={child.__title} className={` <a title={child.__title} className={`
grow pl-2 border-l-2 grow pl-2 border-l-2
${linkClasses} ${linkClasses}
@ -127,7 +119,7 @@ const SubLevel = ({ nodes={}, active }) => (
</li> </li>
) : ( ) : (
<li className='pl-2 flex flex-row items-center' key={child.__slug}> <li className='pl-2 flex flex-row items-center' key={child.__slug}>
<Link href={`/${child.__slug}`} title={child.__title}> <Link href={`${child.__slug}`} title={child.__title}>
<a className={` <a className={`
pl-2 border-l-2 pl-2 border-l-2
grow grow
@ -172,7 +164,7 @@ const TopLevel = ({ icon, title, nav, current, slug, hasChildren=false, active }
items-center items-center
`}> `}>
<span className="text-secondary">{icon}</span> <span className="text-secondary">{icon}</span>
<Link href={`/${slug}`}> <Link href={`${slug}`}>
<a className={` <a className={`
grow ${linkClasses} hover:cursor-pointer grow ${linkClasses} hover:cursor-pointer
${slug === active ${slug === active
@ -215,16 +207,15 @@ export const Icons = ({
liClasses='', liClasses='',
linkClasses=`grow text-lg lg:text-xl py-1 text-base-content sm:text-base-content linkClasses=`grow text-lg lg:text-xl py-1 text-base-content sm:text-base-content
hover:text-secondary sm:hover:text-secondary hover:cursor-pointer hover:text-secondary sm:hover:text-secondary hover:cursor-pointer
flex flex-col items-center`, flex flex-col items-center`
linkStyle={}
}) => { }) => {
if (!app.navigation) return null if (!app.navigation) return null
const output = [] const output = []
for (const page of order(app.navigation)) { for (const page of order(app.navigation)) {
output.push( output.push(
<li key={page.__slug} className={liClasses}> <li key={page.__slug} className={liClasses}>
<Link href={`/${page.__slug}`}> <Link href={`${page.__slug}`}>
<a className={linkClasses} title={page.__title} style={linkStyle}> <a className={linkClasses} title={page.__title}>
{icons[page.__slug] {icons[page.__slug]
? icons[page.__slug]('w-14 h-14') ? icons[page.__slug]('w-14 h-14')
: <HelpIcon /> : <HelpIcon />