feat(dev): Ported dev site to named exports
This commit is contained in:
parent
595417a23b
commit
db789180b6
22 changed files with 287 additions and 315 deletions
|
@ -1,172 +0,0 @@
|
|||
import Logo from 'shared/components/logos/freesewing.js'
|
||||
import OsiLogo from 'shared/components/logos/osi.js'
|
||||
import CreativeCommonsLogo from 'shared/components/logos/cc.js'
|
||||
import CcByLogo from 'shared/components/logos/cc-by.js'
|
||||
import Ribbon from 'shared/components/ribbon.js'
|
||||
import Link from 'next/link'
|
||||
import { WordMark } from 'shared/components/wordmark.js'
|
||||
|
||||
import HelpIcon from 'shared/components/icons/help.js'
|
||||
import DiscordIcon from 'shared/components/icons/discord.js'
|
||||
import FacebookIcon from 'shared/components/icons/facebook.js'
|
||||
import GithubIcon from 'shared/components/icons/github.js'
|
||||
import InstagramIcon from 'shared/components/icons/instagram.js'
|
||||
import RedditIcon from 'shared/components/icons/reddit.js'
|
||||
import TwitterIcon from 'shared/components/icons/twitter.js'
|
||||
|
||||
// Classes
|
||||
const link = 'text-secondary font-bold hover:pointer hover:underline px-1'
|
||||
const accent = 'text-accent font-bold text-lg px-1 block sm:inline'
|
||||
const freesewing = 'px-1 text-lg font-bold block sm:inline'
|
||||
|
||||
// Keep these translations in the component because they're only used here
|
||||
const translations = {
|
||||
cc: (
|
||||
<span>
|
||||
Content on FreeSewing.org is available under{' '}
|
||||
<a className={link} href="https://creativecommons.org/licenses/by/4.0/">
|
||||
a Creative Commons license
|
||||
</a>
|
||||
</span>
|
||||
),
|
||||
mit: (
|
||||
<span>
|
||||
The FreeSewing source code is{' '}
|
||||
<a href="https://github.com/freesewing/freesewing" className={link}>
|
||||
available on Github
|
||||
</a>{' '}
|
||||
under{' '}
|
||||
<a href="https://opensource.org/licenses/MIT" className={link}>
|
||||
the MIT license
|
||||
</a>
|
||||
</span>
|
||||
),
|
||||
sponsors: (
|
||||
<>
|
||||
<span className={freesewing}>FreeSewing</span> is sponsored by these{' '}
|
||||
<span className={accent}>awesome companies</span>
|
||||
</>
|
||||
),
|
||||
}
|
||||
|
||||
const icon = { className: 'w-8 lg:w-12 h-8 lg:h-12' }
|
||||
const social = {
|
||||
Discord: {
|
||||
icon: <DiscordIcon {...icon} />,
|
||||
href: 'https://discord.freesewing.org/',
|
||||
},
|
||||
Instagram: {
|
||||
icon: <InstagramIcon {...icon} />,
|
||||
href: 'https://instagram.com/freesewing_org',
|
||||
},
|
||||
Facebook: {
|
||||
icon: <FacebookIcon {...icon} />,
|
||||
href: 'https://www.facebook.com/groups/627769821272714/',
|
||||
},
|
||||
Github: {
|
||||
icon: <GithubIcon {...icon} />,
|
||||
href: 'https://github.com/freesewing',
|
||||
},
|
||||
Reddit: {
|
||||
icon: <RedditIcon {...icon} />,
|
||||
href: 'https://www.reddit.com/r/freesewing/',
|
||||
},
|
||||
Twitter: {
|
||||
icon: <TwitterIcon {...icon} />,
|
||||
href: 'https://twitter.com/freesewing_org',
|
||||
},
|
||||
}
|
||||
|
||||
const Footer = ({ app }) => {
|
||||
return (
|
||||
<footer className="bg-neutral">
|
||||
<Ribbon loading={app.loading} theme={app.theme} />
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 py-12 2xl:py-20 text-neutral-content px-4">
|
||||
{/* First col - CC & MIT */}
|
||||
<div className="mb-20 order-1 mt-20 2xl:mt-0 2xl:mb-0">
|
||||
<div className="max-w-md m-auto">
|
||||
<div>
|
||||
<CreativeCommonsLogo className="w-64 m-auto" />
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 justify-center items-center mt-8">
|
||||
<CcByLogo className="w-8 lg:w-12" />
|
||||
<p className="text-neutral-content text-right basis-4/5 lg:basis-3/4 leading-5">
|
||||
{translations.cc}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 justify-center items-center mt-4">
|
||||
<OsiLogo className="w-8 lg:w-12" />
|
||||
<p className="text-neutral-content text-right basis-4/5 lg:basis-3/4 leading-5">
|
||||
{translations.mit}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Second col - Social & Sponsors */}
|
||||
<div className="lg:col-span-2 -order-2 2xl:order-2 px-4 lg:px-0">
|
||||
{/* Social icons */}
|
||||
<div className="w-full sm:w-auto flex flex-row flex-wrap gap-4 lg:gap-8 items-center justify-center">
|
||||
<Link href="/contact" className="hover:text-secondary hover:-mt-2 transition-all" title="Contact information">
|
||||
<HelpIcon {...icon} />
|
||||
</Link>
|
||||
{Object.keys(social).map((item) => (
|
||||
<Link key={item} href={social[item].href} className="hover:text-secondary hover:-mt-2 transition-all" title={item}>
|
||||
{social[item].icon}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
{/* Sponsors */}
|
||||
<div className="border rounded-xl p-8 border-dashed border-base-100/25 mt-20">
|
||||
<p className="text-center text-neutral-content leading-5">
|
||||
{translations.sponsors}
|
||||
<br />
|
||||
</p>
|
||||
<div className="py-4 flex flex-row gap-8 flex-wrap 2xl:flex-nowrap justify-around text-neutral-content">
|
||||
<a title="Search powered by Algolia" href="https://www.algolia.com/">
|
||||
<img
|
||||
src="/brands/algolia.svg"
|
||||
className="h-12 aspect-auto"
|
||||
alt="Search powered by Algolia"
|
||||
/>
|
||||
</a>
|
||||
<a title="Error handling by Bugsnag" href="https://www.bugsnag.com/">
|
||||
<img src="/brands/bugsnag.svg" className="h-12" alt="Error handling by bugsnag" />
|
||||
</a>
|
||||
<a title="Translation powered by Crowdin" href="https://www.crowdin.com/">
|
||||
<img
|
||||
src="/brands/crowdin.svg"
|
||||
alt="Translation powered by Crowdin"
|
||||
className="h-12"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
title="Builds & hosting by Vercel"
|
||||
href="https://www.vercel.com/?utm_source=freesewing&utm_campaign=oss"
|
||||
>
|
||||
<img src="/brands/vercel.svg" alt="Builds & Hosting by Vercel" className="h-12" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Col 3 - Logo & Slogan */}
|
||||
<div className="w-full 4xl:w-auto xl:max-w-md mb-8 text-center order-3 mt-0 lg:mt-20 2xl:mt-0 2xl:mb-0">
|
||||
<div className="max-w-md m-auto">
|
||||
<Logo stroke="none" size={164} className="w-40 lg:w-64 m-auto m-auto" />
|
||||
<h5 className="lg:text-3xl mt-4">
|
||||
<WordMark />
|
||||
</h5>
|
||||
<p className="bold text-neutral-content text-normal lg:text-xl leading-5">
|
||||
Come for the sewing patterns
|
||||
<br />
|
||||
Stay for the community
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer
|
178
sites/dev/components/footer.mjs
Normal file
178
sites/dev/components/footer.mjs
Normal file
|
@ -0,0 +1,178 @@
|
|||
import Link from 'next/link'
|
||||
import { FreeSewingLogo } from 'shared/components/logos/freesewing.mjs'
|
||||
import { OsiLogo } from 'shared/components/logos/osi.mjs'
|
||||
import { CCLogo } from 'shared/components/logos/cc.mjs'
|
||||
import { CCByLogo } from 'shared/components/logos/cc-by.mjs'
|
||||
import { Ribbon } from 'shared/components/ribbon.mjs'
|
||||
import { WordMark } from 'shared/components/wordmark.mjs'
|
||||
import {
|
||||
HelpIcon,
|
||||
DiscordIcon,
|
||||
FacebookIcon,
|
||||
GithubIcon,
|
||||
InstagramIcon,
|
||||
RedditIcon,
|
||||
TwitterIcon,
|
||||
} from 'shared/components/icons.mjs'
|
||||
|
||||
// Classes
|
||||
const link = 'text-secondary font-bold hover:pointer hover:underline px-1'
|
||||
const accent = 'text-accent font-bold text-lg px-1 block sm:inline'
|
||||
const freesewing = 'px-1 text-lg font-bold block sm:inline'
|
||||
|
||||
// Keep these translations in the component because they're only used here
|
||||
const translations = {
|
||||
cc: (
|
||||
<span>
|
||||
Content on FreeSewing.org is available under{' '}
|
||||
<a className={link} href="https://creativecommons.org/licenses/by/4.0/">
|
||||
a Creative Commons license
|
||||
</a>
|
||||
</span>
|
||||
),
|
||||
mit: (
|
||||
<span>
|
||||
The FreeSewing source code is{' '}
|
||||
<a href="https://github.com/freesewing/freesewing" className={link}>
|
||||
available on Github
|
||||
</a>{' '}
|
||||
under{' '}
|
||||
<a href="https://opensource.org/licenses/MIT" className={link}>
|
||||
the MIT license
|
||||
</a>
|
||||
</span>
|
||||
),
|
||||
sponsors: (
|
||||
<>
|
||||
<span className={freesewing}>FreeSewing</span> is sponsored by these{' '}
|
||||
<span className={accent}>awesome companies</span>
|
||||
</>
|
||||
),
|
||||
}
|
||||
|
||||
const icon = { className: 'w-8 lg:w-12 h-8 lg:h-12' }
|
||||
const social = {
|
||||
Discord: {
|
||||
icon: <DiscordIcon {...icon} />,
|
||||
href: 'https://discord.freesewing.org/',
|
||||
},
|
||||
Instagram: {
|
||||
icon: <InstagramIcon {...icon} />,
|
||||
href: 'https://instagram.com/freesewing_org',
|
||||
},
|
||||
Facebook: {
|
||||
icon: <FacebookIcon {...icon} />,
|
||||
href: 'https://www.facebook.com/groups/627769821272714/',
|
||||
},
|
||||
Github: {
|
||||
icon: <GithubIcon {...icon} />,
|
||||
href: 'https://github.com/freesewing',
|
||||
},
|
||||
Reddit: {
|
||||
icon: <RedditIcon {...icon} />,
|
||||
href: 'https://www.reddit.com/r/freesewing/',
|
||||
},
|
||||
Twitter: {
|
||||
icon: <TwitterIcon {...icon} />,
|
||||
href: 'https://twitter.com/freesewing_org',
|
||||
},
|
||||
}
|
||||
|
||||
export const Footer = ({ app }) => (
|
||||
<footer className="bg-neutral">
|
||||
<Ribbon loading={app.loading} theme={app.theme} />
|
||||
<div className="grid grid-cols-1 lg:grid-cols-4 py-12 2xl:py-20 text-neutral-content px-4">
|
||||
{/* First col - CC & MIT */}
|
||||
<div className="mb-20 order-1 mt-20 2xl:mt-0 2xl:mb-0">
|
||||
<div className="max-w-md m-auto">
|
||||
<div>
|
||||
<CCLogo className="w-64 m-auto" />
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 justify-center items-center mt-8">
|
||||
<CCByLogo className="w-8 lg:w-12" />
|
||||
<p className="text-neutral-content text-right basis-4/5 lg:basis-3/4 leading-5">
|
||||
{translations.cc}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-row gap-2 justify-center items-center mt-4">
|
||||
<OsiLogo className="w-8 lg:w-12" />
|
||||
<p className="text-neutral-content text-right basis-4/5 lg:basis-3/4 leading-5">
|
||||
{translations.mit}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Second col - Social & Sponsors */}
|
||||
<div className="lg:col-span-2 -order-2 2xl:order-2 px-4 lg:px-0">
|
||||
{/* Social icons */}
|
||||
<div className="w-full sm:w-auto flex flex-row flex-wrap gap-4 lg:gap-8 items-center justify-center">
|
||||
<Link
|
||||
href="/contact"
|
||||
className="hover:text-secondary hover:-mt-2 transition-all"
|
||||
title="Contact information"
|
||||
>
|
||||
<HelpIcon {...icon} />
|
||||
</Link>
|
||||
{Object.keys(social).map((item) => (
|
||||
<Link
|
||||
key={item}
|
||||
href={social[item].href}
|
||||
className="hover:text-secondary hover:-mt-2 transition-all"
|
||||
title={item}
|
||||
>
|
||||
{social[item].icon}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
{/* Sponsors */}
|
||||
<div className="border rounded-xl p-8 border-dashed border-base-100/25 mt-20">
|
||||
<p className="text-center text-neutral-content leading-5">
|
||||
{translations.sponsors}
|
||||
<br />
|
||||
</p>
|
||||
<div className="py-4 flex flex-row gap-8 flex-wrap 2xl:flex-nowrap justify-around text-neutral-content">
|
||||
<a title="Search powered by Algolia" href="https://www.algolia.com/">
|
||||
<img
|
||||
src="/brands/algolia.svg"
|
||||
className="h-12 aspect-auto"
|
||||
alt="Search powered by Algolia"
|
||||
/>
|
||||
</a>
|
||||
<a title="Error handling by Bugsnag" href="https://www.bugsnag.com/">
|
||||
<img src="/brands/bugsnag.svg" className="h-12" alt="Error handling by bugsnag" />
|
||||
</a>
|
||||
<a title="Translation powered by Crowdin" href="https://www.crowdin.com/">
|
||||
<img
|
||||
src="/brands/crowdin.svg"
|
||||
alt="Translation powered by Crowdin"
|
||||
className="h-12"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
title="Builds & hosting by Vercel"
|
||||
href="https://www.vercel.com/?utm_source=freesewing&utm_campaign=oss"
|
||||
>
|
||||
<img src="/brands/vercel.svg" alt="Builds & Hosting by Vercel" className="h-12" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Col 3 - Logo & Slogan */}
|
||||
<div className="w-full 4xl:w-auto xl:max-w-md mb-8 text-center order-3 mt-0 lg:mt-20 2xl:mt-0 2xl:mb-0">
|
||||
<div className="max-w-md m-auto">
|
||||
<FreeSewingLogo stroke="none" size={164} className="w-40 lg:w-64 m-auto m-auto" />
|
||||
<h5 className="lg:text-3xl mt-4">
|
||||
<WordMark />
|
||||
</h5>
|
||||
<p className="bold text-neutral-content text-normal lg:text-xl leading-5">
|
||||
Come for the sewing patterns
|
||||
<br />
|
||||
Stay for the community
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
|
@ -1,12 +1,12 @@
|
|||
// Hooks
|
||||
import { useState, useEffect } from 'react'
|
||||
import ThemePicker from 'shared/components/theme-picker.js'
|
||||
import CloseIcon from 'shared/components/icons/close.js'
|
||||
import MenuIcon from 'shared/components/icons/menu.js'
|
||||
import SearchIcon from 'shared/components/icons/search.js'
|
||||
import Ribbon from 'shared/components/ribbon.js'
|
||||
import { WordMark } from 'shared/components/wordmark.js'
|
||||
// Components
|
||||
import { ThemePicker } from 'shared/components/theme-picker/index.mjs'
|
||||
import { CloseIcon, MenuIcon, SearchIcon } from 'shared/components/icons.mjs'
|
||||
import { Ribbon } from 'shared/components/ribbon.mjs'
|
||||
import { WordMark } from 'shared/components/wordmark.mjs'
|
||||
|
||||
const Header = ({ app, setSearch }) => {
|
||||
export const Header = ({ app, setSearch }) => {
|
||||
const [prevScrollPos, setPrevScrollPos] = useState(0)
|
||||
const [show, setShow] = useState(true)
|
||||
|
||||
|
@ -88,5 +88,3 @@ const Header = ({ app, setSearch }) => {
|
|||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
|
@ -1,6 +1,6 @@
|
|||
import Popout from 'shared/components/popout.js'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
|
||||
const HelpUs = ({ slug = '/' }) => (
|
||||
export const HelpUs = ({ slug = '/' }) => (
|
||||
<details className="mt-4">
|
||||
<summary>Click here to learn how you can help us improve this page</summary>
|
||||
<Popout tip className="max-w-prose">
|
||||
|
@ -16,5 +16,3 @@ const HelpUs = ({ slug = '/' }) => (
|
|||
</Popout>
|
||||
</details>
|
||||
)
|
||||
|
||||
export default HelpUs
|
|
@ -1,16 +0,0 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import Aside from 'shared/components/navigation/aside'
|
||||
|
||||
const DefaultLayout = ({ app, children = [] }) => {
|
||||
const router = useRouter()
|
||||
const slug = router.asPath.slice(1)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Aside app={app} slug={slug} mobileOnly />
|
||||
{children}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default DefaultLayout
|
14
sites/dev/components/layouts/bare.mjs
Normal file
14
sites/dev/components/layouts/bare.mjs
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import { AsideNavigation } from 'shared/components/navigation/aside.mjs'
|
||||
|
||||
export const BareLayout = ({ app, children = [] }) => {
|
||||
const router = useRouter()
|
||||
const slug = router.asPath.slice(1)
|
||||
|
||||
return (
|
||||
<>
|
||||
<AsideNavigation app={app} slug={slug} mobileOnly />
|
||||
{children}
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -1,25 +1,28 @@
|
|||
// Hooks
|
||||
import { useRouter } from 'next/router'
|
||||
// Shared components
|
||||
import Aside from 'site/components/navigation/aside.js'
|
||||
import ThemePicker from 'shared/components/theme-picker.js'
|
||||
import Breadcrumbs from 'shared/components/breadcrumbs.js'
|
||||
import { getCrumbs } from 'shared/utils'
|
||||
import HomeIcon from 'shared/components/icons/home.js'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { AsideNavigation } from 'site/components/navigation/aside.mjs'
|
||||
import { ThemePicker } from 'shared/components/theme-picker/index.mjs'
|
||||
import { Breadcrumbs } from 'shared/components/breadcrumbs.mjs'
|
||||
import { getCrumbs } from 'shared/utils.mjs'
|
||||
import { HomeIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
const DefaultLayout = ({ app, title = false, crumbs = false, children = [] }) => {
|
||||
export const DocsLayout = ({ app, title = false, crumbs = false, children = [] }) => {
|
||||
const router = useRouter()
|
||||
const slug = router.asPath.slice(1)
|
||||
const breadcrumbs = crumbs ? crumbs : getCrumbs(app, slug, title)
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-4 m-auto justify-center place-items-stretch">
|
||||
<Aside
|
||||
<AsideNavigation
|
||||
app={app}
|
||||
slug={slug}
|
||||
before={[
|
||||
<div className="flex flex-row items-center justify-between border-b mb-4" key="home-key">
|
||||
<Link href="/"><HomeIcon /></Link>
|
||||
<Link href="/">
|
||||
<HomeIcon />
|
||||
</Link>
|
||||
<ThemePicker app={app} />
|
||||
</div>,
|
||||
]}
|
||||
|
@ -36,5 +39,3 @@ const DefaultLayout = ({ app, title = false, crumbs = false, children = [] }) =>
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DefaultLayout
|
|
@ -1,6 +1,6 @@
|
|||
import { MainSections, ActiveSection } from './primary'
|
||||
import { MainSections, ActiveSection } from './primary.mjs'
|
||||
|
||||
const Aside = ({ app, slug, mobileOnly = false, before = [], after = [] }) => (
|
||||
export const AsideNavigation = ({ app, slug, mobileOnly = false, before = [], after = [] }) => (
|
||||
<aside
|
||||
className={`
|
||||
fixed top-0 right-0 h-screen w-screen
|
||||
|
@ -24,5 +24,3 @@ const Aside = ({ app, slug, mobileOnly = false, before = [], after = [] }) => (
|
|||
</div>
|
||||
</aside>
|
||||
)
|
||||
|
||||
export default Aside
|
|
@ -1,9 +1,6 @@
|
|||
import Link from 'next/link'
|
||||
import orderBy from 'lodash.orderby'
|
||||
import TutorialIcon from 'shared/components/icons/tutorial.js'
|
||||
import GuideIcon from 'shared/components/icons/guide.js'
|
||||
import HelpIcon from 'shared/components/icons/help.js'
|
||||
import DocsIcon from 'shared/components/icons/docs.js'
|
||||
import { TutorialIcon, GuideIcon, HelpIcon, DocsIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
// List of icons matched to top-level slug
|
||||
const icons = {
|
||||
|
@ -246,5 +243,3 @@ export const ActiveSection = ({ app, active }) => (
|
|||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
//export default PrimaryMenu
|
|
@ -1,17 +1,19 @@
|
|||
// Hooks
|
||||
import { useState, useRef } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
|
||||
import algoliasearch from 'algoliasearch/lite'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
// Dependencies
|
||||
import algoliasearch from 'algoliasearch/lite'
|
||||
import {
|
||||
InstantSearch,
|
||||
connectHits,
|
||||
connectHighlight,
|
||||
connectSearchBox,
|
||||
} from 'react-instantsearch-dom'
|
||||
import CloseIcon from 'shared/components/icons/close.js'
|
||||
import config from 'site/algolia.config.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { CloseIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
const searchClient = algoliasearch(config.algolia.app, config.algolia.key)
|
||||
|
||||
|
@ -186,7 +188,7 @@ const SearchBox = (props) => {
|
|||
|
||||
const CustomSearchBox = connectSearchBox(SearchBox)
|
||||
|
||||
const Search = (props) => {
|
||||
export const Search = (props) => {
|
||||
const [active, setActive] = useState(0)
|
||||
useHotkeys('esc', () => props.setSearch(false))
|
||||
useHotkeys('up', () => {
|
||||
|
@ -212,5 +214,3 @@ const Search = (props) => {
|
|||
</InstantSearch>
|
||||
)
|
||||
}
|
||||
|
||||
export default Search
|
|
@ -1,10 +1,10 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import Head from 'next/head'
|
||||
import Header from 'site/components/header'
|
||||
import Footer from 'site/components/footer'
|
||||
import Search from 'site/components/search'
|
||||
import { Header } from 'site/components/header.mjs'
|
||||
import { Footer } from 'site/components/footer.mjs'
|
||||
import { Search } from 'site/components/search.mjs'
|
||||
|
||||
const LayoutWrapper = ({ app, children = [], search, setSearch, noSearch = false }) => {
|
||||
export const LayoutWrapper = ({ app, children = [], search, setSearch, noSearch = false }) => {
|
||||
const startNavigation = () => {
|
||||
app.startLoading()
|
||||
// Force close of menu on mobile if it is open
|
||||
|
@ -50,5 +50,3 @@ const LayoutWrapper = ({ app, children = [], search, setSearch, noSearch = false
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LayoutWrapper
|
|
@ -1,21 +1,21 @@
|
|||
// Hooks
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useSwipeable } from 'react-swipeable'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
// Components
|
||||
import Head from 'next/head'
|
||||
// Layouts components
|
||||
import LayoutWrapper from 'site/components/wrappers/layout'
|
||||
import Docs from 'site/components/layouts/docs'
|
||||
// Modal
|
||||
import Modal from 'shared/components/modal'
|
||||
import Loader from 'shared/components/loader'
|
||||
import { LayoutWrapper } from 'site/components/wrappers/layout.mjs'
|
||||
import { DocsLayout } from 'site/components/layouts/docs.mjs'
|
||||
import { Modal } from 'shared/components/modal.mjs'
|
||||
import { Loader } from 'shared/components/loader.mjs'
|
||||
|
||||
/* This component should wrap all page content */
|
||||
const PageWrapper = ({
|
||||
export const PageWrapper = ({
|
||||
title = 'FIXME: No title set',
|
||||
noSearch = false,
|
||||
app = false,
|
||||
layout = Docs,
|
||||
layout = DocsLayout,
|
||||
crumbs = false,
|
||||
children = [],
|
||||
}) => {
|
||||
|
@ -69,5 +69,3 @@ const PageWrapper = ({
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PageWrapper
|
|
@ -6,13 +6,13 @@ import useTheme from 'shared/hooks/useTheme'
|
|||
// Prebuild navigation
|
||||
import prebuildNavigation from 'site/prebuild/navigation.js'
|
||||
|
||||
function useApp(full = true) {
|
||||
export const useApp = (full = true) => {
|
||||
// No translation for freesewing.dev
|
||||
const language = 'en'
|
||||
|
||||
// Persistent state
|
||||
const [account, setAccount] = useLocalStorage('account', { username: false })
|
||||
const [theme, setTheme] = useTheme();
|
||||
const [theme, setTheme] = useTheme()
|
||||
|
||||
// React State
|
||||
const [primaryMenu, setPrimaryMenu] = useState(false)
|
||||
|
@ -29,9 +29,7 @@ function useApp(full = true) {
|
|||
*/
|
||||
const updateNavigation = (path, content) => {
|
||||
if (typeof path === 'string') {
|
||||
path = (path.slice(0,1) === '/')
|
||||
? path.slice(1).split('/')
|
||||
: path.split('/')
|
||||
path = path.slice(0, 1) === '/' ? path.slice(1).split('/') : path.split('/')
|
||||
}
|
||||
setNavigation(set(navigation, path, content))
|
||||
}
|
||||
|
@ -56,7 +54,10 @@ function useApp(full = true) {
|
|||
setPrimaryMenu,
|
||||
setSlug,
|
||||
setTheme,
|
||||
startLoading: () => { setLoading(true); setPrimaryMenu(false) }, // Always close menu when navigating
|
||||
startLoading: () => {
|
||||
setLoading(true)
|
||||
setPrimaryMenu(false)
|
||||
}, // Always close menu when navigating
|
||||
stopLoading: () => setLoading(false),
|
||||
updateNavigation,
|
||||
|
||||
|
@ -64,10 +65,7 @@ function useApp(full = true) {
|
|||
togglePrimaryMenu,
|
||||
|
||||
// Dummy translation method
|
||||
t: s => s,
|
||||
t: (s) => s,
|
||||
i18n: false,
|
||||
}
|
||||
}
|
||||
|
||||
export default useApp
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
const jargon = {
|
||||
cjs: "<b>CJS</b> stands for CommonJS, it is the JavaScript module format popularized by NodeJS, but now increasingly phased out in favor of <b>ESM</b>",
|
||||
esm: "<b>ESM</b> stands for EcmaScript Module, it is the standardized module syntax in JavaScript",
|
||||
export const jargon = {
|
||||
cjs: '<b>CJS</b> stands for CommonJS, it is the JavaScript module format popularized by NodeJS, but now increasingly phased out in favor of <b>ESM</b>',
|
||||
esm: '<b>ESM</b> stands for EcmaScript Module, it is the standardized module syntax in JavaScript',
|
||||
}
|
||||
|
||||
export default jargon
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
// Components
|
||||
import Head from 'next/head'
|
||||
import Robot from 'shared/components/robot'
|
||||
import Popout from 'shared/components/popout'
|
||||
import PageLink from 'shared/components/page-link'
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { Robot } from 'shared/components/robot/index.mjs'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
import { PageLink } from 'shared/components/page-link.mjs'
|
||||
|
||||
const Page404 = () => {
|
||||
const app = useApp()
|
||||
const title = '404: Page not found'
|
||||
|
||||
return (
|
||||
<Page app={app} title={title} layout={Layout}>
|
||||
<PageWrapper app={app} title={title} layout={BareLayout}>
|
||||
<Head>
|
||||
<meta property="og:type" content="article" key="type" />
|
||||
<meta
|
||||
|
@ -47,7 +49,7 @@ const Page404 = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,13 +1,16 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
// Dependencies
|
||||
import mdxMeta from 'site/prebuild/mdx.en.js'
|
||||
import mdxLoader from 'shared/mdx/loader'
|
||||
import MdxWrapper from 'shared/components/wrappers/mdx'
|
||||
import TocWrapper from 'shared/components/wrappers/toc'
|
||||
import Head from 'next/head'
|
||||
import HelpUs from 'site/components/help-us.js'
|
||||
import { mdxLoader } from 'shared/mdx/loader.mjs'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import jargon from 'site/jargon.mjs'
|
||||
// Components
|
||||
import Head from 'next/head'
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
||||
import { TocWrapper } from 'shared/components/wrappers/toc.mjs'
|
||||
import { HelpUs } from 'site/components/help-us.mjs'
|
||||
import { jargon } from 'site/jargon.mjs'
|
||||
|
||||
const MdxPage = (props) => {
|
||||
// This hook is used for shared code and global state
|
||||
|
@ -23,7 +26,7 @@ const MdxPage = (props) => {
|
|||
* active state
|
||||
*/
|
||||
return (
|
||||
<Page app={app} {...props.page}>
|
||||
<PageWrapper app={app} {...props.page}>
|
||||
<Head>
|
||||
<meta property="og:type" content="article" key="type" />
|
||||
<meta property="og:description" content={props.intro} key="type" />
|
||||
|
@ -51,7 +54,7 @@ const MdxPage = (props) => {
|
|||
<HelpUs mdx slug={`/${props.page.slug}`} />
|
||||
</div>
|
||||
</div>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/* This is the recommended way to load a font */
|
||||
import Document, { Html, Head, Main, NextScript } from 'next/document'
|
||||
|
||||
class FsDocument extends Document {
|
||||
render() {
|
||||
return (
|
||||
<Html>
|
||||
<Head>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Indie+Flower&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</Head>
|
||||
<body>
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default FsDocument
|
|
@ -1,20 +1,23 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import Head from 'next/head'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import { Icons } from 'shared/components/navigation/primary'
|
||||
import Highlight from 'shared/components/mdx/highlight'
|
||||
import Popout from 'shared/components/popout'
|
||||
import WebLink from 'shared/components/web-link'
|
||||
import PageLink from 'shared/components/page-link'
|
||||
// Components
|
||||
import Head from 'next/head'
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { Icons } from 'shared/components/navigation/primary.mjs'
|
||||
import { Highlight } from 'shared/components/mdx/highlight.mjs'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
import { WebLink } from 'shared/components/web-link.mjs'
|
||||
import { PageLink } from 'shared/components/page-link.mjs'
|
||||
|
||||
const title = 'Welcome to FreeSewing.dev'
|
||||
|
||||
const HomePage = () => {
|
||||
const app = useApp()
|
||||
return (
|
||||
<Page app={app} title={title} layout={Layout}>
|
||||
<PageWrapper app={app} title={title} layout={BareLayout}>
|
||||
<Head>
|
||||
<meta property="og:type" content="article" key="type" />
|
||||
<meta
|
||||
|
@ -214,7 +217,7 @@ const HomePage = () => {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import { Fragment } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { FreeSewingIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
|
@ -10,7 +11,7 @@ export const Breadcrumbs = ({ crumbs = [], title }) =>
|
|||
</Link>
|
||||
</li>
|
||||
{crumbs.map((crumb) => (
|
||||
<React.Fragment key={crumb[1] + crumb[0]}>
|
||||
<Fragment key={crumb[1] + crumb[0]}>
|
||||
<li className="text-base-content px-2">»</li>
|
||||
<li>
|
||||
{crumb[1] ? (
|
||||
|
@ -25,7 +26,7 @@ export const Breadcrumbs = ({ crumbs = [], title }) =>
|
|||
<span className="text-base-content">{crumb[0]}</span>
|
||||
)}
|
||||
</li>
|
||||
</React.Fragment>
|
||||
</Fragment>
|
||||
))}
|
||||
</ul>
|
||||
) : null
|
||||
|
|
|
@ -155,7 +155,7 @@ export const GithubIcon = (props) => (
|
|||
</IconWrapper>
|
||||
)
|
||||
|
||||
export const GuidesIcon = (props) => (
|
||||
export const GuideIcon = (props) => (
|
||||
<IconWrapper {...props}>
|
||||
<path d="M21 3L3 10.53v.98l6.84 2.65L12.48 21h.98L21 3z" />
|
||||
</IconWrapper>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue