feat(org): Ported components to mjs and named exports
This commit is contained in:
parent
37f7833983
commit
595417a23b
118 changed files with 836 additions and 852 deletions
|
@ -1,10 +1,12 @@
|
|||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import useBackend from 'site/hooks/useBackend.js'
|
||||
import { useBackend } from 'site/hooks/useBackend.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { Icons, welcomeSteps } from '../shared.js'
|
||||
import Popout from 'shared/components/popout.js'
|
||||
import Markdown from 'react-markdown'
|
||||
import { Icons, welcomeSteps } from '../shared.mjs'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
|
||||
export const ns = ['bio']
|
||||
|
||||
|
@ -18,7 +20,7 @@ const Tab = ({ id, activeTab, setActiveTab, t }) => (
|
|||
</button>
|
||||
)
|
||||
|
||||
const UsernameSettings = ({ app, title = false, welcome = false }) => {
|
||||
export const BioSettings = ({ app, title = false, welcome = false }) => {
|
||||
const backend = useBackend(app)
|
||||
const { t } = useTranslation(ns)
|
||||
const [bio, setBio] = useState(app.account.bio)
|
||||
|
@ -91,5 +93,3 @@ const UsernameSettings = ({ app, title = false, welcome = false }) => {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default UsernameSettings
|
|
@ -1,8 +1,10 @@
|
|||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import useBackend from 'site/hooks/useBackend.js'
|
||||
import { useBackend } from 'site/hooks/useBackend.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { Choice, Icons, welcomeSteps } from '../shared.js'
|
||||
import { Choice, Icons, welcomeSteps } from '../shared.mjs'
|
||||
|
||||
export const ns = ['compare']
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import useBackend from 'site/hooks/useBackend.js'
|
||||
import { useBackend } from 'site/hooks/useBackend.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { Choice, Icons, welcomeSteps } from '../shared.js'
|
||||
import { Choice, Icons, welcomeSteps } from '../shared.mjs'
|
||||
|
||||
export const ns = ['control']
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
// Hooks
|
||||
import { useState, useCallback } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import useBackend from 'site/hooks/useBackend.js'
|
||||
import Link from 'next/link'
|
||||
import { Icons, welcomeSteps } from '../shared.js'
|
||||
import { useBackend } from 'site/hooks/useBackend.mjs'
|
||||
import { useDropzone } from 'react-dropzone'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { Icons, welcomeSteps } from '../shared.mjs'
|
||||
|
||||
export const ns = ['img']
|
||||
|
||||
const ImgSettings = ({ app, title = false, welcome = false }) => {
|
||||
export const ImgSettings = ({ app, title = false, welcome = false }) => {
|
||||
const backend = useBackend(app)
|
||||
const { t } = useTranslation(ns)
|
||||
|
||||
|
@ -80,5 +82,3 @@ const ImgSettings = ({ app, title = false, welcome = false }) => {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default ImgSettings
|
|
@ -1,8 +1,10 @@
|
|||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import useBackend from 'site/hooks/useBackend.js'
|
||||
import { useBackend } from 'site/hooks/useBackend.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { Choice, Icons, welcomeSteps } from '../shared.js'
|
||||
import { Choice, Icons, welcomeSteps } from '../shared.mjs'
|
||||
|
||||
export const ns = ['newsletter']
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
import Link from 'next/link'
|
||||
import CogIcon from 'shared/components/icons/cog.js'
|
||||
import ControlIcon from 'shared/components/icons/control.js'
|
||||
import NewsletterIcon from 'shared/components/icons/newsletter.js'
|
||||
import UnitsIcon from 'shared/components/icons/units.js'
|
||||
import CompareIcon from 'shared/components/icons/compare.js'
|
||||
import LabelIcon from 'shared/components/icons/label.js'
|
||||
import BioIcon from 'shared/components/icons/bio.js'
|
||||
import UserIcon from 'shared/components/icons/user.js'
|
||||
import {
|
||||
CogIcon,
|
||||
ControlIcon,
|
||||
NewsletterIcon,
|
||||
UnitsIcon,
|
||||
CompareIcon,
|
||||
LabelIcon,
|
||||
BioIcon,
|
||||
UserIcon,
|
||||
} from 'shared/components/icons.mjs'
|
||||
|
||||
const btnClasses = {
|
||||
dflt:
|
|
@ -1,12 +1,14 @@
|
|||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import useBackend from 'site/hooks/useBackend.js'
|
||||
import { useBackend } from 'site/hooks/useBackend.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { Choice, Icons, welcomeSteps } from '../shared.js'
|
||||
import { Choice, Icons, welcomeSteps } from '../shared.mjs'
|
||||
|
||||
export const ns = ['units']
|
||||
|
||||
const UnitsSettings = ({ app, title = false, welcome = false }) => {
|
||||
export const UnitsSettings = ({ app, title = false, welcome = false }) => {
|
||||
const backend = useBackend(app)
|
||||
const { t } = useTranslation(ns)
|
||||
const [selection, setSelection] = useState(app.account?.imperial === true ? 'imperial' : 'metric')
|
||||
|
@ -25,7 +27,7 @@ const UnitsSettings = ({ app, title = false, welcome = false }) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
{title ? <h1 className="text-4xl">{t('title')}</h1> : null}
|
||||
{title ? <h1 className="text-4xl">{t('title')}</h1> : <h1></h1>}
|
||||
{['metric', 'imperial'].map((val) => (
|
||||
<Choice val={val} t={t} update={update} current={selection} bool key={val}>
|
||||
<span className="block text-lg leading-5">
|
||||
|
@ -61,5 +63,3 @@ const UnitsSettings = ({ app, title = false, welcome = false }) => {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default UnitsSettings
|
|
@ -1,14 +1,15 @@
|
|||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import useBackend from 'site/hooks/useBackend.js'
|
||||
import { useBackend } from 'site/hooks/useBackend.mjs'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { Icons, welcomeSteps } from '../shared.js'
|
||||
import OkIcon from 'shared/components/icons/ok.js'
|
||||
import NoIcon from 'shared/components/icons/no.js'
|
||||
import { Icons, welcomeSteps } from '../shared.mjs'
|
||||
import { OkIcon, NoIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
export const ns = ['username']
|
||||
|
||||
const UsernameSettings = ({ app, title = false, welcome = false }) => {
|
||||
export const UsernameSettings = ({ app, title = false, welcome = false }) => {
|
||||
const backend = useBackend(app)
|
||||
const { t } = useTranslation(ns)
|
||||
const [username, setUsername] = useState(app.account.username)
|
||||
|
@ -85,5 +86,3 @@ const UsernameSettings = ({ app, title = false, welcome = false }) => {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default UsernameSettings
|
|
@ -1,7 +1,7 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { configs } from 'shared/designs/index.js'
|
||||
import DesignIcon from 'shared/components/icons/design.js'
|
||||
import { DesignIcon } from 'shared/components/icons.mjs'
|
||||
import Worm from 'shared/components/worm.js'
|
||||
import { strapiHost } from 'shared/config/freesewing.mjs'
|
||||
import Link from 'next/link'
|
|
@ -1,70 +0,0 @@
|
|||
import Head from 'next/head'
|
||||
|
||||
const rss = (lang, type, title) => ({
|
||||
title,
|
||||
type: "application/rss+xml",
|
||||
href: `/feeds/${type}-${lang}.rss.xml`
|
||||
})
|
||||
const atom = (lang, type, title) => ({
|
||||
title,
|
||||
type: "application/rss+atom",
|
||||
href: `/feeds/${type}-${lang}.atom.xml`
|
||||
})
|
||||
const json = (lang, type, title) => ({
|
||||
title,
|
||||
type: "application/json",
|
||||
href: `/feeds/${type}-${lang}.json`
|
||||
})
|
||||
|
||||
|
||||
const feeds = {
|
||||
en: [
|
||||
atom('en', 'blog', "Atom feed of FreeSewing.org blog posts"),
|
||||
json('en', 'blog', "JSON feed of FreeSewing.org blog posts"),
|
||||
rss( 'en', 'blog', "RSS feed of FreeSewing.org blog posts"),
|
||||
atom('en', 'showcase', "Atom feed of FreeSewing.org showcase posts"),
|
||||
json('en', 'showcase', "JSON feed of FreeSewing.org showcase posts"),
|
||||
rss( 'en', 'showcase', "RSS feed of FreeSewing.org showcase posts"),
|
||||
],
|
||||
de: [
|
||||
atom('de', 'blog', "Atom-Feed von FreeSewing.org-Blogbeiträgen"),
|
||||
json('de', 'blog', "JSON-Feed von FreeSewing.org-Blogbeiträgen"),
|
||||
rss( 'de', 'blog', "RSS-Feed von FreeSewing.org-Blogbeiträgen"),
|
||||
atom('de', 'showcase', "Atom-Feed von FreeSewing.org-Galeriebeiträgen"),
|
||||
json('de', 'showcase', "JSON-Feed von FreeSewing.org-Galeriebeiträgen"),
|
||||
rss( 'de', 'showcase', "RSS-Feed von FreeSewing.org-Galeriebeiträgen"),
|
||||
],
|
||||
es: [
|
||||
atom('es', 'blog', "Fuente Atom de las publicaciones del blog FreeSewing.org"),
|
||||
json('es', 'blog', "Fuente JSON de las publicaciones del blog FreeSewing.org"),
|
||||
rss( 'es', 'blog', "Fuente RSS de las publicaciones del blog FreeSewing.org"),
|
||||
atom('es', 'showcase', "Fuente Atom de publicaciones de exhibición de FreeSewing.org"),
|
||||
json('es', 'showcase', "Fuente JSON de publicaciones de exhibición de FreeSewing.org"),
|
||||
rss( 'es', 'showcase', "Fuente RSS de publicaciones de exhibición de FreeSewing.org"),
|
||||
],
|
||||
fr: [
|
||||
atom('fr', 'blog', "Flux Atom des articles du blog FreeSewing.org"),
|
||||
json('fr', 'blog', "Flux JSON des articles du blog FreeSewing.org"),
|
||||
rss( 'fr', 'blog', "Flux RSS des articles du blog FreeSewing.org"),
|
||||
atom('fr', 'showcase', "Flux Atom des articles du galerie FreeSewing.org"),
|
||||
json('fr', 'showcase', "Flux JSON des articles du galerie FreeSewing.org"),
|
||||
rss( 'fr', 'showcase', "Flux RSS des articles du galerie FreeSewing.org"),
|
||||
],
|
||||
nl: [
|
||||
atom('nl', 'blog', "Atom feed van FreeSewing.org blog posts"),
|
||||
json('nl', 'blog', "JSON feed van FreeSewing.org blog posts"),
|
||||
rss( 'nl', 'blog', "RSS feed van FreeSewing.org blog posts"),
|
||||
atom('nl', 'showcase', "Atom feed van FreeSewing.org voorbeelden"),
|
||||
json('nl', 'showcase', "JSON feed van FreeSewing.org voorbeelden"),
|
||||
rss( 'nl', 'showcase', "RSS feed van FreeSewing.org voorbeelden"),
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
const Feeds = ({ lang='en' }) => (
|
||||
<Head>
|
||||
{feeds[lang].map(feed => <link key={feed.href} {...feed} />)}
|
||||
</Head>
|
||||
)
|
||||
|
||||
export default Feeds
|
68
sites/org/components/feeds.mjs
Normal file
68
sites/org/components/feeds.mjs
Normal file
|
@ -0,0 +1,68 @@
|
|||
import Head from 'next/head'
|
||||
|
||||
const rss = (lang, type, title) => ({
|
||||
title,
|
||||
type: 'application/rss+xml',
|
||||
href: `/feeds/${type}-${lang}.rss.xml`,
|
||||
})
|
||||
const atom = (lang, type, title) => ({
|
||||
title,
|
||||
type: 'application/rss+atom',
|
||||
href: `/feeds/${type}-${lang}.atom.xml`,
|
||||
})
|
||||
const json = (lang, type, title) => ({
|
||||
title,
|
||||
type: 'application/json',
|
||||
href: `/feeds/${type}-${lang}.json`,
|
||||
})
|
||||
|
||||
const feeds = {
|
||||
en: [
|
||||
atom('en', 'blog', 'Atom feed of FreeSewing.org blog posts'),
|
||||
json('en', 'blog', 'JSON feed of FreeSewing.org blog posts'),
|
||||
rss('en', 'blog', 'RSS feed of FreeSewing.org blog posts'),
|
||||
atom('en', 'showcase', 'Atom feed of FreeSewing.org showcase posts'),
|
||||
json('en', 'showcase', 'JSON feed of FreeSewing.org showcase posts'),
|
||||
rss('en', 'showcase', 'RSS feed of FreeSewing.org showcase posts'),
|
||||
],
|
||||
de: [
|
||||
atom('de', 'blog', 'Atom-Feed von FreeSewing.org-Blogbeiträgen'),
|
||||
json('de', 'blog', 'JSON-Feed von FreeSewing.org-Blogbeiträgen'),
|
||||
rss('de', 'blog', 'RSS-Feed von FreeSewing.org-Blogbeiträgen'),
|
||||
atom('de', 'showcase', 'Atom-Feed von FreeSewing.org-Galeriebeiträgen'),
|
||||
json('de', 'showcase', 'JSON-Feed von FreeSewing.org-Galeriebeiträgen'),
|
||||
rss('de', 'showcase', 'RSS-Feed von FreeSewing.org-Galeriebeiträgen'),
|
||||
],
|
||||
es: [
|
||||
atom('es', 'blog', 'Fuente Atom de las publicaciones del blog FreeSewing.org'),
|
||||
json('es', 'blog', 'Fuente JSON de las publicaciones del blog FreeSewing.org'),
|
||||
rss('es', 'blog', 'Fuente RSS de las publicaciones del blog FreeSewing.org'),
|
||||
atom('es', 'showcase', 'Fuente Atom de publicaciones de exhibición de FreeSewing.org'),
|
||||
json('es', 'showcase', 'Fuente JSON de publicaciones de exhibición de FreeSewing.org'),
|
||||
rss('es', 'showcase', 'Fuente RSS de publicaciones de exhibición de FreeSewing.org'),
|
||||
],
|
||||
fr: [
|
||||
atom('fr', 'blog', 'Flux Atom des articles du blog FreeSewing.org'),
|
||||
json('fr', 'blog', 'Flux JSON des articles du blog FreeSewing.org'),
|
||||
rss('fr', 'blog', 'Flux RSS des articles du blog FreeSewing.org'),
|
||||
atom('fr', 'showcase', 'Flux Atom des articles du galerie FreeSewing.org'),
|
||||
json('fr', 'showcase', 'Flux JSON des articles du galerie FreeSewing.org'),
|
||||
rss('fr', 'showcase', 'Flux RSS des articles du galerie FreeSewing.org'),
|
||||
],
|
||||
nl: [
|
||||
atom('nl', 'blog', 'Atom feed van FreeSewing.org blog posts'),
|
||||
json('nl', 'blog', 'JSON feed van FreeSewing.org blog posts'),
|
||||
rss('nl', 'blog', 'RSS feed van FreeSewing.org blog posts'),
|
||||
atom('nl', 'showcase', 'Atom feed van FreeSewing.org voorbeelden'),
|
||||
json('nl', 'showcase', 'JSON feed van FreeSewing.org voorbeelden'),
|
||||
rss('nl', 'showcase', 'RSS feed van FreeSewing.org voorbeelden'),
|
||||
],
|
||||
}
|
||||
|
||||
export const Feeds = ({ lang = 'en' }) => (
|
||||
<Head>
|
||||
{feeds[lang].map((feed) => (
|
||||
<link key={feed.href} {...feed} />
|
||||
))}
|
||||
</Head>
|
||||
)
|
|
@ -1,20 +1,21 @@
|
|||
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 { 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 { useTranslation } from 'next-i18next'
|
||||
import { freeSewingConfig } from 'site/freesewing.config.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'
|
||||
import { freeSewingConfig } from 'site/freesewing.config.mjs'
|
||||
import {
|
||||
HelpIcon,
|
||||
DiscordIcon,
|
||||
FacebookIcon,
|
||||
GithubIcon,
|
||||
InstagramIcon,
|
||||
RedditIcon,
|
||||
TwitterIcon,
|
||||
} from 'shared/components/icons.mjs'
|
||||
|
||||
const icon = { className: 'w-8 lg:w-12 h-8 lg:h-12' }
|
||||
const social = {
|
||||
|
@ -60,10 +61,10 @@ export const Footer = ({ app }) => {
|
|||
<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" />
|
||||
<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" />
|
||||
<CCByLogo className="w-8 lg:w-12" />
|
||||
<p className="text-neutral-content text-right basis-4/5 lg:basis-3/4 leading-5">
|
||||
{t('cc')}
|
||||
</p>
|
||||
|
@ -138,7 +139,7 @@ export const Footer = ({ app }) => {
|
|||
{/* 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" />
|
||||
<FreeSewingLogo stroke="none" size={164} className="w-40 lg:w-64 m-auto m-auto" />
|
||||
<h5 className="lg:text-3xl mt-4">
|
||||
<WordMark />
|
||||
</h5>
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import ThemePicker, { ns as themeNs } from 'shared/components/theme-picker/index.js'
|
||||
import LocalePicker, { ns as localeNs } from 'shared/components/locale-picker/index.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'
|
||||
import { ThemePicker, ns as themeNs } from 'shared/components/theme-picker/index.mjs'
|
||||
import { LocalePicker, ns as localeNs } from 'shared/components/locale-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'
|
||||
|
||||
export const ns = [...new Set([...themeNs, ...localeNs])]
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import Aside from 'shared/components/navigation/aside'
|
||||
import ThemePicker from 'shared/components/theme-picker'
|
||||
|
||||
const DefaultLayout = ({ app, children = [] }) => {
|
||||
const router = useRouter()
|
||||
const slug = router.asPath.slice(1)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Aside app={app} slug={slug} before={<ThemePicker app={app} />} mobileOnly />
|
||||
{children}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default DefaultLayout
|
15
sites/org/components/layouts/bare.mjs
Normal file
15
sites/org/components/layouts/bare.mjs
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import { AsideNavigation } from 'shared/components/navigation/aside.mjs'
|
||||
import { ThemePicker } from 'shared/components/theme-picker/index.mjs'
|
||||
|
||||
export const BareLayout = ({ app, children = [] }) => {
|
||||
const router = useRouter()
|
||||
const slug = router.asPath.slice(1)
|
||||
|
||||
return (
|
||||
<>
|
||||
<AsideNavigation app={app} slug={slug} before={<ThemePicker app={app} />} mobileOnly />
|
||||
{children}
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import Aside from 'site/components/navigation/aside'
|
||||
import { AsideNavigation } from 'site/components/navigation/aside.mjs'
|
||||
|
||||
const DefaultLayout = ({ app, title = false, children = [] }) => {
|
||||
export const DocsLayout = ({ app, title = false, children = [] }) => {
|
||||
const router = useRouter()
|
||||
const slug = router.asPath.slice(1)
|
||||
|
||||
|
@ -18,7 +18,7 @@ const DefaultLayout = ({ app, title = false, children = [] }) => {
|
|||
lg:block
|
||||
`}
|
||||
>
|
||||
<Aside app={app} slug={slug} />
|
||||
<AsideNavigation app={app} slug={slug} />
|
||||
</section>
|
||||
<section className="py-8 lg:py-16 px-6 xl:pl-8 2xl:pl-16">
|
||||
<div>
|
||||
|
@ -29,5 +29,3 @@ const DefaultLayout = ({ app, title = false, children = [] }) => {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DefaultLayout
|
|
@ -2,10 +2,8 @@
|
|||
//import PatternOptions from './pattern-options.js'
|
||||
//import PatternMeasurements from './pattern-measurements.js'
|
||||
|
||||
const components = {
|
||||
export const components = {
|
||||
//PatternDocs,
|
||||
//PatternOptions,
|
||||
//PatternMeasurements,
|
||||
}
|
||||
|
||||
export default components
|
|
@ -3,21 +3,21 @@ import { useTranslation } from 'next-i18next'
|
|||
import orderBy from 'lodash.orderby'
|
||||
import PageLink from 'shared/components/page-link.js'
|
||||
|
||||
const PatternMeasurements = ({ pattern, before=null, after=null }) => {
|
||||
const PatternMeasurements = ({ pattern, before = null, after = null }) => {
|
||||
const { t } = useTranslation(['measurements'])
|
||||
|
||||
const measurements = {}
|
||||
for (const m of configs[pattern].measurements) {
|
||||
measurements[m] = {
|
||||
title: t(`measurements.${m}`),
|
||||
required: true
|
||||
required: true,
|
||||
}
|
||||
}
|
||||
for (const m of configs[pattern].measurements || []) {
|
||||
measurements[m] = {
|
||||
name: m,
|
||||
title: t(`measurements:${m}`),
|
||||
required: false
|
||||
required: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ const PatternMeasurements = ({ pattern, before=null, after=null }) => {
|
|||
<div>
|
||||
{before}
|
||||
<ol className="list-inside ml-8 my-4">
|
||||
{orderBy(measurements, ['title'], ['asc']).map(m => (
|
||||
{orderBy(measurements, ['title'], ['asc']).map((m) => (
|
||||
<li key={m.name}>
|
||||
<PageLink href={'/docs/measurements/' + m.name.toLowerCase()} txt={m.title} />
|
||||
</li>
|
|
@ -49,7 +49,7 @@ const renderOptions = (groups, pattern, t) => {
|
|||
return <ul className="list list-disc list-inside ml-4">{list}</ul>
|
||||
}
|
||||
|
||||
const PatternOptions = ({ pattern, before=null, after=null }) => {
|
||||
const PatternOptions = ({ pattern, before = null, after = null }) => {
|
||||
const { t } = useTranslation([`o_${pattern}`, 'og'])
|
||||
|
||||
return (
|
|
@ -1,6 +1,6 @@
|
|||
import PrimaryNavigation from './primary'
|
||||
import { PrimaryNavigation } 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
|
||||
|
@ -23,5 +23,3 @@ const Aside = ({ app, slug, mobileOnly = false, before = [], after = [] }) => (
|
|||
{after}
|
||||
</aside>
|
||||
)
|
||||
|
||||
export default Aside
|
|
@ -1,8 +1,8 @@
|
|||
import { useState, useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import orderBy from 'lodash.orderby'
|
||||
import FreeSewingIcon from 'shared/components/icons/freesewing.js'
|
||||
import TopLevel from './top-level.js'
|
||||
import { FreeSewingIcon } from 'shared/components/icons.mjs'
|
||||
import { TopLevelNavigation as TopLevel } from './top-level.mjs'
|
||||
|
||||
/* helper method to order nav entries */
|
||||
const order = (obj) => orderBy(obj, ['__order', '__title'], ['asc', 'asc'])
|
||||
|
@ -278,12 +278,10 @@ const Navigation = ({ app, active, className = '' }) => {
|
|||
return <div className={`pb-20 ${className}`}>{output}</div>
|
||||
}
|
||||
|
||||
const PrimaryMenu = ({ app, active, before = [], after = [] }) => (
|
||||
export const PrimaryNavigation = ({ app, active, before = [], after = [] }) => (
|
||||
<nav className="mb-12">
|
||||
{before}
|
||||
<Navigation app={app} active={active} />
|
||||
{after}
|
||||
</nav>
|
||||
)
|
||||
|
||||
export default PrimaryMenu
|
|
@ -1,5 +0,0 @@
|
|||
const TopLevelNavigation = () => {
|
||||
return <p>Top-level menu here</p>
|
||||
}
|
||||
|
||||
export default TopLevelNavigation
|
3
sites/org/components/navigation/top-level.mjs
Normal file
3
sites/org/components/navigation/top-level.mjs
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const TopLevelNavigation = () => {
|
||||
return <p>Top-level menu here</p>
|
||||
}
|
|
@ -10,7 +10,7 @@ import {
|
|||
connectHighlight,
|
||||
connectSearchBox,
|
||||
} from 'react-instantsearch-dom'
|
||||
import { freeSewingConfig } from 'site/freesewing.config.js'
|
||||
import { freeSewingConfig } from 'site/freesewing.config.mjs'
|
||||
|
||||
const searchClient = algoliasearch(freeSewingConfig.algolia.app, freeSewingConfig.algolia.key)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import Link from 'next/link'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Loader from 'shared/components/loader.js'
|
||||
import { Loader } from 'shared/components/loader.mjs'
|
||||
|
||||
export const ns = ['auth']
|
||||
|
||||
|
@ -83,7 +83,7 @@ const ConsentLacking = ({ t }) => (
|
|||
</Wrap>
|
||||
)
|
||||
|
||||
const AuthWrapper = ({ children, app }) => {
|
||||
export const AuthWrapper = ({ children, app }) => {
|
||||
const { t } = useTranslation(ns)
|
||||
if (!app.accountReady) return <Loader />
|
||||
if (!app.token || !app.account?.username) return <AuthRequired t={t} />
|
||||
|
@ -97,5 +97,3 @@ const AuthWrapper = ({ children, app }) => {
|
|||
|
||||
return children
|
||||
}
|
||||
|
||||
export default AuthWrapper
|
|
@ -1,11 +1,20 @@
|
|||
// Hooks
|
||||
import { useRouter } from 'next/router'
|
||||
// Components
|
||||
import { Header, ns as headerNs } from 'site/components/header/index.mjs'
|
||||
import { Footer, ns as footerNs } from 'site/components/footer/index.mjs'
|
||||
import { Search, ns as searchNs } from 'site/components/search'
|
||||
import { Search, ns as searchNs } from 'site/components/search.mjs'
|
||||
|
||||
export const ns = [...new Set([...headerNs, ...footerNs, ...searchNs])]
|
||||
|
||||
const LayoutWrapper = ({ app, children = [], footer, search, setSearch, noSearch = false }) => {
|
||||
export const LayoutWrapper = ({
|
||||
app,
|
||||
children = [],
|
||||
footer,
|
||||
search,
|
||||
setSearch,
|
||||
noSearch = false,
|
||||
}) => {
|
||||
const startNavigation = () => {
|
||||
app.startLoading()
|
||||
// Force close of menu on mobile if it is open
|
||||
|
@ -48,5 +57,3 @@ const LayoutWrapper = ({ app, children = [], footer, search, setSearch, noSearch
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LayoutWrapper
|
|
@ -1,19 +1,20 @@
|
|||
// Hooks
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useSwipeable } from 'react-swipeable'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
// Layouts components
|
||||
import LayoutWrapper from 'site/components/wrappers/layout'
|
||||
import Docs from 'site/components/layouts/docs'
|
||||
// Components
|
||||
import { LayoutWrapper } from 'site/components/wrappers/layout.mjs'
|
||||
import { DocsLayout } from 'site/components/layouts/docs.mjs'
|
||||
// Add feeds
|
||||
import Feeds from 'site/components/feeds.js'
|
||||
import { Feeds } from 'site/components/feeds.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,
|
||||
footer = true,
|
||||
crumbs = false,
|
||||
children = [],
|
||||
|
@ -64,5 +65,3 @@ const PageWrapper = ({
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PageWrapper
|
|
@ -5,7 +5,7 @@ const opacity = {
|
|||
lgbtq: 80,
|
||||
}
|
||||
|
||||
const SusiWrapper = ({ theme, children, error = false }) => (
|
||||
export const SusiWrapper = ({ theme, children, error = false }) => (
|
||||
<section
|
||||
style={{
|
||||
backgroundImage: `url('https://static.freesewing.org/img/splash/${theme || 'light'}.jpg')`,
|
||||
|
@ -25,5 +25,3 @@ const SusiWrapper = ({ theme, children, error = false }) => (
|
|||
</div>
|
||||
</section>
|
||||
)
|
||||
|
||||
export default SusiWrapper
|
|
@ -1,9 +1,7 @@
|
|||
const WelcomeWrapper = ({ children }) => (
|
||||
export const WelcomeWrapper = ({ children }) => (
|
||||
<section className="m-0 p-0 w-full">
|
||||
<div className="flex flex-col items-center justify-start h-screen mt-4 lg:mt-32 max-w-lg m-auto">
|
||||
<div className="w-full text-left">{children}</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
|
||||
export default WelcomeWrapper
|
|
@ -80,7 +80,7 @@ const buildNavigation = (lang, t) => {
|
|||
/*
|
||||
* The actual hook
|
||||
*/
|
||||
function useApp({ bugsnag }) {
|
||||
export function useApp({ bugsnag }) {
|
||||
// Load translation method
|
||||
const locale = useRouter().locale
|
||||
const { t } = useTranslation()
|
||||
|
@ -183,5 +183,3 @@ function useApp({ bugsnag }) {
|
|||
errId,
|
||||
}
|
||||
}
|
||||
|
||||
export default useApp
|
|
@ -9,7 +9,7 @@ const api = axios.create({
|
|||
timeout: 3000,
|
||||
})
|
||||
|
||||
function useBackend(app) {
|
||||
export function useBackend(app) {
|
||||
const auth = {
|
||||
headers: { Authorization: 'Bearer ' + app.token },
|
||||
}
|
||||
|
@ -107,5 +107,3 @@ function useBackend(app) {
|
|||
|
||||
return backend
|
||||
}
|
||||
|
||||
export default useBackend
|
3
sites/org/notes.md
Normal file
3
sites/org/notes.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
to sit
|
||||
bu hao yi se
|
||||
|
|
@ -3,7 +3,7 @@ import { appWithTranslation } from 'next-i18next'
|
|||
import React from 'react'
|
||||
import Bugsnag from '@bugsnag/js'
|
||||
import BugsnagPluginReact from '@bugsnag/plugin-react'
|
||||
import { freeSewingConfig } from 'site/freesewing.config.js'
|
||||
import { freeSewingConfig } from 'site/freesewing.config.mjs'
|
||||
|
||||
Bugsnag.start({
|
||||
apiKey: freeSewingConfig.bugsnag.key,
|
|
@ -1,22 +1,24 @@
|
|||
import { useEffect } from 'react'
|
||||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import useBackend from 'site/hooks/useBackend.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import Link from 'next/link'
|
||||
import { useState } from 'react'
|
||||
import WelcomeWrapper from 'site/components/wrappers/welcome.js'
|
||||
import Spinner from 'shared/components/icons/spinner.js'
|
||||
// Hooks
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useBackend } from 'site/hooks/useBackend.mjs'
|
||||
import { useRouter } from 'next/router'
|
||||
import Popout from 'shared/components/popout.js'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import Link from 'next/link'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { WelcomeWrapper } from 'site/components/wrappers/welcome.mjs'
|
||||
import { Spinner } from 'shared/components/spinner.mjs'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
import { Robot } from 'shared/components/robot/index.mjs'
|
||||
import {
|
||||
GdprProfileDetails,
|
||||
GdprMeasurementsDetails,
|
||||
ns as gdprNs,
|
||||
} from 'site/components/gdpr/details.js'
|
||||
import Robot from 'shared/components/robot/index.js'
|
||||
} from 'site/components/gdpr/details.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const ns = Array.from(new Set([...gdprNs, 'confirm', 'locales', 'themes']))
|
||||
|
@ -110,11 +112,11 @@ const ConfirmSignUpPage = (props) => {
|
|||
// Short-circuit errors
|
||||
if (error)
|
||||
return (
|
||||
<Page app={app} title={t('joinFreeSewing')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('joinFreeSewing')} layout={BareLayout} footer={false}>
|
||||
<WelcomeWrapper theme={app.theme}>
|
||||
<SignupLinkExpired />
|
||||
</WelcomeWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
|
||||
const partA = (
|
||||
|
@ -181,7 +183,7 @@ const ConfirmSignUpPage = (props) => {
|
|||
)
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('joinFreeSewing')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('joinFreeSewing')} layout={BareLayout} footer={false}>
|
||||
<WelcomeWrapper theme={app.theme}>
|
||||
{ready ? (
|
||||
<>
|
||||
|
@ -223,7 +225,7 @@ const ConfirmSignUpPage = (props) => {
|
|||
</Link>
|
||||
</p>
|
||||
</WelcomeWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import mdxLoader from 'shared/mdx/loader'
|
||||
import MdxWrapper from 'shared/components/wrappers/mdx'
|
||||
import TocWrapper from 'shared/components/wrappers/toc'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
// Dependencies
|
||||
import Head from 'next/head'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import components from 'site/components/mdx/index.js'
|
||||
import { mdxLoader } from 'shared/mdx/loader.mjs'
|
||||
import { jargon } from 'site/jargon.mjs'
|
||||
// MDX paths
|
||||
import mdxPaths from 'site/prebuild/mdx.paths.js'
|
||||
import { mdxPaths } from 'site/prebuild/mdx.paths.mjs'
|
||||
// Components
|
||||
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
||||
import { TocWrapper } from 'shared/components/wrappers/toc.mjs'
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { components } from 'site/components/mdx/index.mjs'
|
||||
|
||||
const MdxPage = (props) => {
|
||||
// This hook is used for shared code and global state
|
||||
|
@ -26,7 +28,7 @@ const MdxPage = (props) => {
|
|||
* active state
|
||||
*/
|
||||
return (
|
||||
<Page app={app} {...props.page}>
|
||||
<PageWrapper app={app} {...props.page}>
|
||||
<Head>
|
||||
<meta property="og:title" content={props.page.title} key="title" />
|
||||
<meta property="og:type" content="article" key="type" />
|
||||
|
@ -53,7 +55,7 @@ const MdxPage = (props) => {
|
|||
)}
|
||||
<MdxWrapper mdx={props.mdx} app={app} components={components} />
|
||||
</div>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import mdxLoader from 'shared/mdx/loader'
|
||||
import MdxWrapper from 'shared/components/wrappers/mdx'
|
||||
import ReadMore from 'shared/components/mdx/read-more.js'
|
||||
import { jargon } from 'site/jargon.mjs'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
// Dependencies
|
||||
import Head from 'next/head'
|
||||
import mdxLoader from 'shared/mdx/loader'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
||||
import { ReadMore } from 'shared/components/mdx/read-more.mjs'
|
||||
import { jargon } from 'site/jargon.mjs'
|
||||
|
||||
const DocsPage = ({ title, mdx, bugsnag }) => {
|
||||
const app = useApp({ bugsnag })
|
||||
|
@ -16,14 +19,14 @@ const DocsPage = ({ title, mdx, bugsnag }) => {
|
|||
}
|
||||
|
||||
return (
|
||||
<Page app={app} title={title}>
|
||||
<PageWrapper app={app} title={title}>
|
||||
<Head>
|
||||
<title>{fullTitle}</title>
|
||||
</Head>
|
||||
<div className="w-full">
|
||||
<MdxWrapper mdx={mdx} app={app} components={components} />
|
||||
</div>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import Popout from 'shared/components/popout.js'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
//import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import PageLink from 'shared/components/page-link'
|
||||
import Head from 'next/head'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { PageLink } from 'shared/components/page-link.mjs'
|
||||
|
||||
const HomePage = (props) => {
|
||||
const app = useApp(props)
|
||||
|
@ -14,18 +17,18 @@ const HomePage = (props) => {
|
|||
// const { t } = useTranslation(['homepage', 'ograph'])
|
||||
|
||||
return (
|
||||
<Page app={app} title={title} layout={Layout}>
|
||||
<PageWrapper app={app} title={title} layout={BareLayout}>
|
||||
<Head>
|
||||
<title>{title}</title>
|
||||
</Head>
|
||||
<div>
|
||||
<div className="max-w-xl m-auto my-32 px-6">
|
||||
<Popout fixme>
|
||||
Create homepage. Meanwhile check <PageLink href="/docs" txt="docs" />
|
||||
Create homepage. Meanwhile check <PageLink href="/signup" txt="the signup flow" />
|
||||
</Popout>
|
||||
</div>
|
||||
</div>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,12 +1,15 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import Link from 'next/link'
|
||||
import { useState } from 'react'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import { validateEmail, validateTld } from 'shared/utils.mjs'
|
||||
import SusiWrapper from 'site/components/wrappers/susi.js'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { SusiWrapper } from 'site/components/wrappers/susi.mjs'
|
||||
|
||||
const darkLinkClasses = 'decoration-1 underline text-medium font-medium hover:decoration-2'
|
||||
|
||||
|
@ -29,7 +32,7 @@ const SignInPage = (props) => {
|
|||
const clearUsername = () => app.setUsername(false)
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('welcomeBack')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('welcomeBack')} layout={BareLayout} footer={false}>
|
||||
<SusiWrapper theme={app.theme}>
|
||||
<h1 className="text-neutral-content font-light text-3xl mb-4 pb-0 text-center">
|
||||
{t('welcomeName', { name: app.username || '' })}
|
||||
|
@ -82,7 +85,7 @@ const SignInPage = (props) => {
|
|||
</Link>
|
||||
</p>
|
||||
</SusiWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,15 +1,18 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import useBackend from 'site/hooks/useBackend.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import Link from 'next/link'
|
||||
// Hooks
|
||||
import { useState } from 'react'
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useBackend } from 'site/hooks/useBackend.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import { validateEmail, validateTld } from 'shared/utils.mjs'
|
||||
import SusiWrapper from 'site/components/wrappers/susi.js'
|
||||
import Spinner from 'shared/components/icons/spinner.js'
|
||||
import Robot from 'shared/components/robot/index.js'
|
||||
// Components
|
||||
import Link from 'next/link'
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { SusiWrapper } from 'site/components/wrappers/susi.mjs'
|
||||
import { Spinner } from 'shared/components/spinner.mjs'
|
||||
import { Robot } from 'shared/components/robot/index.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const namespaces = ['signup', 'errors']
|
||||
|
@ -59,7 +62,7 @@ const SignUpPage = (props) => {
|
|||
const loadingClasses = app.loading ? 'opacity-50' : ''
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('joinFreeSewing')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('joinFreeSewing')} layout={BareLayout} footer={false}>
|
||||
<SusiWrapper theme={app.theme} error={result && result !== 'success'}>
|
||||
<h1 className={`text-neutral-content font-light text-3xl mb-0 pb-0 ${loadingClasses}`}>
|
||||
{result ? (
|
||||
|
@ -152,7 +155,7 @@ const SignUpPage = (props) => {
|
|||
</>
|
||||
)}
|
||||
</SusiWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import Popout from 'shared/components/popout.js'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
|
||||
const TypographyPage = (props) => {
|
||||
const app = useApp(props)
|
||||
|
@ -13,7 +15,7 @@ const TypographyPage = (props) => {
|
|||
)
|
||||
|
||||
return (
|
||||
<Page app={{ ...app, navigation: null }} title="Typography">
|
||||
<PageWrapper app={{ ...app, navigation: null }} title="Typography">
|
||||
<div className="text-primary mdx max-w-prose text-base-content max-w-prose text-base">
|
||||
<p>This typography page shows an overview of different elements and how they are styled.</p>
|
||||
<p>It's a good starting point for theme development.</p>
|
||||
|
@ -84,7 +86,7 @@ const TypographyPage = (props) => {
|
|||
)
|
||||
})}
|
||||
</div>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import AuthWrapper, { namespaces as authNs } from 'site/components/wrappers/auth/index.js'
|
||||
import BioSettings, { namespaces as bioNs } from 'site/components/account/bio/index.js'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { AuthWrapper, ns as authNs } from 'site/components/wrappers/auth/index.mjs'
|
||||
import { BioSettings, ns as bioNs } from 'site/components/account/bio/index.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const namespaces = [...bioNs, ...authNs]
|
||||
|
@ -14,13 +17,13 @@ const BioPage = (props) => {
|
|||
const { t } = useTranslation(namespaces)
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('title')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('title')} layout={BareLayout} footer={false}>
|
||||
<AuthWrapper app={app}>
|
||||
<div className="m-auto max-w-lg text-center lg:mt-12 p-8">
|
||||
<BioSettings app={app} title welcome />
|
||||
</div>
|
||||
</AuthWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -29,7 +32,7 @@ export default BioPage
|
|||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
...(await serverSideTranslations(locale, namespaces)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import AuthWrapper, { namespaces as authNs } from 'site/components/wrappers/auth/index.js'
|
||||
import CompareSettings, { namespaces as compareNs } from 'site/components/account/compare/index.js'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { AuthWrapper, ns as authNs } from 'site/components/wrappers/auth/index.mjs'
|
||||
import { CompareSettings, ns as compareNs } from 'site/components/account/compare/index.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const namespaces = [...compareNs, ...authNs]
|
||||
|
@ -14,13 +17,13 @@ const ComparePage = (props) => {
|
|||
const { t } = useTranslation(namespaces)
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('title')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('title')} layout={BareLayout} footer={false}>
|
||||
<AuthWrapper app={app}>
|
||||
<div className="m-auto max-w-lg text-center lg:mt-12 p-8">
|
||||
<CompareSettings app={app} title welcome />
|
||||
</div>
|
||||
</AuthWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -29,7 +32,7 @@ export default ComparePage
|
|||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
...(await serverSideTranslations(locale, namespaces)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import AuthWrapper, { namespaces as authNs } from 'site/components/wrappers/auth/index.js'
|
||||
import ImgSettings, { namespaces as imgNs } from 'site/components/account/img/index.js'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { AuthWrapper, ns as authNs } from 'site/components/wrappers/auth/index.mjs'
|
||||
import { ImgSettings, ns as imgNs } from 'site/components/account/img/index.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const namespaces = [...imgNs, ...authNs]
|
||||
|
@ -14,13 +17,13 @@ const ImgPage = (props) => {
|
|||
const { t } = useTranslation(namespaces)
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('title')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('title')} layout={BareLayout} footer={false}>
|
||||
<AuthWrapper app={app}>
|
||||
<div className="m-auto max-w-lg text-center lg:mt-12 p-8">
|
||||
<ImgSettings app={app} title welcome />
|
||||
</div>
|
||||
</AuthWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -29,7 +32,7 @@ export default ImgPage
|
|||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
...(await serverSideTranslations(locale, namespaces)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import AuthWrapper, { namespaces as authNs } from 'site/components/wrappers/auth/index.js'
|
||||
import ControlSettings, { namespaces as controlNs } from 'site/components/account/control/index.js'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { AuthWrapper, ns as authNs } from 'site/components/wrappers/auth/index.mjs'
|
||||
import { ControlSettings, ns as controlNs } from 'site/components/account/control/index.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const namespaces = [...controlNs, ...authNs]
|
||||
|
@ -14,13 +17,13 @@ const WelcomePage = (props) => {
|
|||
const { t } = useTranslation(namespaces)
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('title')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('title')} layout={BareLayout} footer={false}>
|
||||
<AuthWrapper app={app}>
|
||||
<div className="m-auto max-w-lg text-center lg:mt-12 p-8">
|
||||
<ControlSettings app={app} title welcome />
|
||||
</div>
|
||||
</AuthWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -29,7 +32,7 @@ export default WelcomePage
|
|||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
...(await serverSideTranslations(locale, namespaces)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,12 +1,15 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import AuthWrapper, { namespaces as authNs } from 'site/components/wrappers/auth/index.js'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { AuthWrapper, ns as authNs } from 'site/components/wrappers/auth/index.mjs'
|
||||
import NewsletterSettings, {
|
||||
namespaces as newsletterNs,
|
||||
} from 'site/components/account/newsletter/index.js'
|
||||
ns as newsletterNs,
|
||||
} from 'site/components/account/newsletter/index.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const namespaces = [...newsletterNs, ...authNs]
|
||||
|
@ -16,13 +19,13 @@ const WelcomePage = (props) => {
|
|||
const { t } = useTranslation(namespaces)
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('title')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('title')} layout={BareLayout} footer={false}>
|
||||
<AuthWrapper app={app}>
|
||||
<div className="m-auto max-w-lg text-center lg:mt-12 p-8">
|
||||
<NewsletterSettings app={app} title welcome />
|
||||
</div>
|
||||
</AuthWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -31,7 +34,7 @@ export default WelcomePage
|
|||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
...(await serverSideTranslations(locale, namespaces)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import AuthWrapper, { namespaces as authNs } from 'site/components/wrappers/auth/index.js'
|
||||
import UnitsSettings, { namespaces as unitsNs } from 'site/components/account/units/index.js'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { AuthWrapper, ns as authNs } from 'site/components/wrappers/auth/index.mjs'
|
||||
import { UnitsSettings, ns as unitsNs } from 'site/components/account/units/index.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const namespaces = [...unitsNs, ...authNs]
|
||||
|
@ -14,13 +17,13 @@ const UnitsPage = (props) => {
|
|||
const { t } = useTranslation(namespaces)
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('title')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('title')} layout={BareLayout} footer={false}>
|
||||
<AuthWrapper app={app}>
|
||||
<div className="m-auto max-w-lg text-center lg:mt-12 p-8">
|
||||
<UnitsSettings app={app} title welcome />
|
||||
</div>
|
||||
</AuthWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -29,7 +32,7 @@ export default UnitsPage
|
|||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
...(await serverSideTranslations(locale, namespaces)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,12 +1,13 @@
|
|||
import Page from 'site/components/wrappers/page.js'
|
||||
import useApp from 'site/hooks/useApp.js'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Hooks
|
||||
import { useApp } from 'site/hooks/useApp.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Layout from 'site/components/layouts/bare'
|
||||
import AuthWrapper, { namespaces as authNs } from 'site/components/wrappers/auth/index.js'
|
||||
import UsernameSettings, {
|
||||
namespaces as usernameNs,
|
||||
} from 'site/components/account/username/index.js'
|
||||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Components
|
||||
import { PageWrapper } from 'site/components/wrappers/page.mjs'
|
||||
import { BareLayout } from 'site/components/layouts/bare.mjs'
|
||||
import { AuthWrapper, ns as authNs } from 'site/components/wrappers/auth/index.mjs'
|
||||
import { UsernameSettings, ns as usernameNs } from 'site/components/account/username/index.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
const namespaces = [...usernameNs, ...authNs]
|
||||
|
@ -16,13 +17,13 @@ const UsernamePage = (props) => {
|
|||
const { t } = useTranslation(namespaces)
|
||||
|
||||
return (
|
||||
<Page app={app} title={t('title')} layout={Layout} footer={false}>
|
||||
<PageWrapper app={app} title={t('title')} layout={BareLayout} footer={false}>
|
||||
<AuthWrapper app={app}>
|
||||
<div className="m-auto max-w-lg text-center lg:mt-12 p-8">
|
||||
<UsernameSettings app={app} title welcome />
|
||||
</div>
|
||||
</AuthWrapper>
|
||||
</Page>
|
||||
</PageWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -31,7 +32,7 @@ export default UsernamePage
|
|||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale)),
|
||||
...(await serverSideTranslations(locale, namespaces)),
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
import React from 'react'
|
||||
import Link from 'next/link'
|
||||
import FreeSewingIcon from 'shared/components/icons.mjs'
|
||||
import { FreeSewingIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
const Breadcrumbs = ({ crumbs = [], title }) =>
|
||||
export const Breadcrumbs = ({ crumbs = [], title }) =>
|
||||
crumbs ? (
|
||||
<ul className="flex flex-row flex-wrap gap-2 font-bold">
|
||||
<li>
|
||||
|
@ -30,5 +29,3 @@ const Breadcrumbs = ({ crumbs = [], title }) =>
|
|||
))}
|
||||
</ul>
|
||||
) : null
|
||||
|
||||
export default Breadcrumbs
|
|
@ -1,5 +1,3 @@
|
|||
const Code = ({ children }) => (
|
||||
export const Code = ({ children = null }) => (
|
||||
<code className="text-accent px-1 font-bold">{children}</code>
|
||||
)
|
||||
|
||||
export default Code
|
|
@ -1,7 +1,7 @@
|
|||
import ReactDOMServer from 'react-dom/server'
|
||||
import { useState } from 'react'
|
||||
import { CopyIcon } from 'shared/components/icons.mjs'
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard'
|
||||
import { CopyToClipboard as Copy } from 'react-copy-to-clipboard'
|
||||
|
||||
const strip = (html) =>
|
||||
typeof DOMParser === 'undefined'
|
||||
|
@ -13,19 +13,17 @@ const handleCopied = (setCopied) => {
|
|||
setTimeout(() => setCopied(false), 1000)
|
||||
}
|
||||
|
||||
const CopyToClipboardIcon = ({ content }) => {
|
||||
export const CopyToClipboard = ({ content }) => {
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
const text =
|
||||
typeof content === 'string' ? content : strip(ReactDOMServer.renderToStaticMarkup(content))
|
||||
|
||||
return (
|
||||
<CopyToClipboard text={text} onCopy={() => handleCopied(setCopied)}>
|
||||
<Copy text={text} onCopy={() => handleCopied(setCopied)}>
|
||||
<button className={copied ? 'text-success' : ''}>
|
||||
<CopyIcon className="w-5 h-5" />
|
||||
</button>
|
||||
</CopyToClipboard>
|
||||
</Copy>
|
||||
)
|
||||
}
|
||||
|
||||
export default CopyToClipboardIcon
|
|
@ -1,12 +1,8 @@
|
|||
import PageLink from './page-link'
|
||||
import PageLink from './page-link.mjs'
|
||||
import get from 'lodash.get'
|
||||
import useApp from 'site/hooks/useApp'
|
||||
import useApp from 'site/hooks/useApp.mjs'
|
||||
|
||||
const DocsLink = ({ slug }) => {
|
||||
export const DocsLink = ({ slug }) => {
|
||||
const app = useApp()
|
||||
return <PageLink href={slug} txt={get(app.navigation, [...slug.split('/'), '__title'])} />
|
||||
}
|
||||
|
||||
export default DocsLink
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react'
|
||||
import ResetButtons from './reset-buttons'
|
||||
import { ResetButtons } from './reset-buttons'
|
||||
import { LogGroup } from 'shared/components/workbench/logs'
|
||||
import DefaultErrorView from './view'
|
||||
import { ErrorView as DefaultErrorView } from './view'
|
||||
|
||||
const ErrorView = (props) => {
|
||||
if (props.children) return props.children
|
||||
|
@ -22,7 +22,7 @@ const ErrorView = (props) => {
|
|||
)
|
||||
}
|
||||
|
||||
class ErrorBoundary extends React.Component {
|
||||
export class ErrorBoundary extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { hasError: false }
|
||||
|
@ -65,5 +65,3 @@ class ErrorBoundary extends React.Component {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default ErrorBoundary
|
|
@ -1,10 +0,0 @@
|
|||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
export default function ({resetGist, undoGist}) {
|
||||
const {t} = useTranslation(['app'])
|
||||
|
||||
return (<div className="flex flex-row gap-4 my-4">
|
||||
<button className="btn btn-primary" onClick={undoGist}>{t('undo')}</button>
|
||||
<button className="btn btn-primary" onClick={resetGist}>{t('reset_all')}</button>
|
||||
</div>
|
||||
)}
|
18
sites/shared/components/error/reset-buttons.mjs
Normal file
18
sites/shared/components/error/reset-buttons.mjs
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { useTranslation } from 'next-i18next'
|
||||
|
||||
// FIXME: I feel this should be kept closer to where it's used
|
||||
|
||||
export const ResetButtons = ({ resetGist, undoGist }) => {
|
||||
const { t } = useTranslation(['app'])
|
||||
|
||||
return (
|
||||
<div className="flex flex-row gap-4 my-4">
|
||||
<button className="btn btn-primary" onClick={undoGist}>
|
||||
{t('undo')}
|
||||
</button>
|
||||
<button className="btn btn-primary" onClick={resetGist}>
|
||||
{t('reset_all')}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
import Robot from 'shared/components/robot/index.js'
|
||||
import Popout from 'shared/components/popout.js'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { useState } from 'react'
|
||||
|
||||
const Error = ({ children, inspectChildren}) => {
|
||||
|
||||
const { t } = useTranslation(['errors'])
|
||||
const [share, setShare] = useState(false)
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl m-auto">
|
||||
<Popout warning>
|
||||
<div className="flex flex-row justify-between">
|
||||
<div>
|
||||
<h3>{t('errors:something')}</h3>
|
||||
{children}
|
||||
</div>
|
||||
<Robot pose='fail' />
|
||||
</div>
|
||||
</Popout>
|
||||
<Popout tip>
|
||||
<h3>Would you like to report this problem?</h3>
|
||||
<p>
|
||||
You can help us <strong>make FreeSewing better by reporting this problem</strong>.
|
||||
</p>
|
||||
<p>If you choose to report this:</p>
|
||||
<ul className="list-disc list-inside ml-4 text-xl">
|
||||
<li>
|
||||
We will compile a <strong>crash report</strong> that contains everything needed <strong>to recreate this problem</strong>
|
||||
</li>
|
||||
<li>
|
||||
We will include <strong>personal data</strong> such as your <strong>username</strong>, <strong>
|
||||
email address</strong> and <strong>measurements</strong>
|
||||
</li>
|
||||
<li>
|
||||
We will share this report and the data in it with <a className="text-primary font-bold"
|
||||
href="https://github.com/orgs/freesewing/teams/bughunters">FreeSewing's bughunters team</a> who will investigate the problem on your behalf
|
||||
</li>
|
||||
<li>Your personal data will <strong>not be shared publicly</strong></li>
|
||||
</ul>
|
||||
<div className="form-control">
|
||||
<label className="cursor-pointer flex flex-row gap-4 my-4">
|
||||
<input type="checkbox" checked={share} className="checkbox checkbox-primary" onChange={() => setShare(!share)}/>
|
||||
<span className="label-text text-xl">I agree to the use of my personal data for the purposes outlined above</span>
|
||||
</label>
|
||||
</div>
|
||||
<p>
|
||||
<button disabled={!share} className="btn btn-primary">Report this</button>
|
||||
</p>
|
||||
<p>
|
||||
If you prefer not to share any info, or want to investigate the problem yourself, you can do so:
|
||||
</p>
|
||||
{inspectChildren}
|
||||
</Popout>
|
||||
</div>)
|
||||
}
|
||||
|
||||
export default Error
|
76
sites/shared/components/error/view.mjs
Normal file
76
sites/shared/components/error/view.mjs
Normal file
|
@ -0,0 +1,76 @@
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { useState } from 'react'
|
||||
import { Robot } from 'shared/components/robot/index.mjs'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
|
||||
export const ErrorView = ({ children, inspectChildren }) => {
|
||||
const { t } = useTranslation(['errors'])
|
||||
const [share, setShare] = useState(false)
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl m-auto">
|
||||
<Popout warning>
|
||||
<div className="flex flex-row justify-between">
|
||||
<div>
|
||||
<h3>{t('errors:something')}</h3>
|
||||
{children}
|
||||
</div>
|
||||
<Robot pose="fail" />
|
||||
</div>
|
||||
</Popout>
|
||||
<Popout tip>
|
||||
<h3>Would you like to report this problem?</h3>
|
||||
<p>
|
||||
You can help us <strong>make FreeSewing better by reporting this problem</strong>.
|
||||
</p>
|
||||
<p>If you choose to report this:</p>
|
||||
<ul className="list-disc list-inside ml-4 text-xl">
|
||||
<li>
|
||||
We will compile a <strong>crash report</strong> that contains everything needed{' '}
|
||||
<strong>to recreate this problem</strong>
|
||||
</li>
|
||||
<li>
|
||||
We will include <strong>personal data</strong> such as your <strong>username</strong>,{' '}
|
||||
<strong>email address</strong> and <strong>measurements</strong>
|
||||
</li>
|
||||
<li>
|
||||
We will share this report and the data in it with{' '}
|
||||
<a
|
||||
className="text-primary font-bold"
|
||||
href="https://github.com/orgs/freesewing/teams/bughunters"
|
||||
>
|
||||
FreeSewing's bughunters team
|
||||
</a>{' '}
|
||||
who will investigate the problem on your behalf
|
||||
</li>
|
||||
<li>
|
||||
Your personal data will <strong>not be shared publicly</strong>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="form-control">
|
||||
<label className="cursor-pointer flex flex-row gap-4 my-4">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={share}
|
||||
className="checkbox checkbox-primary"
|
||||
onChange={() => setShare(!share)}
|
||||
/>
|
||||
<span className="label-text text-xl">
|
||||
I agree to the use of my personal data for the purposes outlined above
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<p>
|
||||
<button disabled={!share} className="btn btn-primary">
|
||||
Report this
|
||||
</button>
|
||||
</p>
|
||||
<p>
|
||||
If you prefer not to share any info, or want to investigate the problem yourself, you can
|
||||
do so:
|
||||
</p>
|
||||
{inspectChildren}
|
||||
</Popout>
|
||||
</div>
|
||||
)
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -1,17 +0,0 @@
|
|||
import React from 'react'
|
||||
import Highlight from 'shared/components/mdx/highlight.js'
|
||||
import hljs from 'highlight.js/lib/common'
|
||||
|
||||
const Json = props => {
|
||||
const code = props.js
|
||||
? JSON.stringify(props.js, null, 2)
|
||||
: props.children
|
||||
|
||||
return <Highlight
|
||||
language='json'
|
||||
raw={hljs.highlight(code, { language: 'json' }).value}
|
||||
/>
|
||||
}
|
||||
|
||||
export default Json
|
||||
|
9
sites/shared/components/json.mjs
Normal file
9
sites/shared/components/json.mjs
Normal file
|
@ -0,0 +1,9 @@
|
|||
import React from 'react'
|
||||
import Highlight from 'shared/components/mdx/highlight.mjs'
|
||||
import hljs from 'highlight.js/lib/common'
|
||||
|
||||
export const Json = (props) => {
|
||||
const code = props.js ? JSON.stringify(props.js, null, 2) : props.children
|
||||
|
||||
return <Highlight language="json" raw={hljs.highlight(code, { language: 'json' }).value} />
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
import { useState } from 'react'
|
||||
|
||||
const Lightbox = ({ cancel, children }) => {
|
||||
|
||||
const [ box, setBox ] = useState(false)
|
||||
|
||||
if (box) return (
|
||||
<div className={`
|
||||
fixed top-0 left-0 right-0 w-screen h-screen
|
||||
bg-neutral bg-opacity-90 z-30
|
||||
hover:cursor-zoom-out flex flex-col justify-center
|
||||
`} onClick={() => setBox(false)}>
|
||||
<div className="m-auto text-neutral-content lightbox" style={{
|
||||
maxHeight: "calc(100vh - 6rem)",
|
||||
maxWidth: "calc(100vw - 6rem)",
|
||||
}}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={() => setBox(!box)}
|
||||
className="hover:cursor-zoom-in"
|
||||
>{children}</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Lightbox
|
33
sites/shared/components/lightbox.mjs
Normal file
33
sites/shared/components/lightbox.mjs
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { useState } from 'react'
|
||||
|
||||
export const Lightbox = ({ cancel, children }) => {
|
||||
const [box, setBox] = useState(false)
|
||||
|
||||
if (box)
|
||||
return (
|
||||
<div
|
||||
className={`
|
||||
fixed top-0 left-0 right-0 w-screen h-screen
|
||||
bg-neutral bg-opacity-90 z-30
|
||||
hover:cursor-zoom-out flex flex-col justify-center
|
||||
`}
|
||||
onClick={() => setBox(false)}
|
||||
>
|
||||
<div
|
||||
className="m-auto text-neutral-content lightbox"
|
||||
style={{
|
||||
maxHeight: 'calc(100vh - 6rem)',
|
||||
maxWidth: 'calc(100vw - 6rem)',
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<div onClick={() => setBox(!box)} className="hover:cursor-zoom-in">
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import Spinner from 'shared/components/spinner.js'
|
||||
import { Spinner } from 'shared/components/spinner.mjs'
|
||||
|
||||
const Loader = () => (
|
||||
export const Loader = () => (
|
||||
<div
|
||||
className={`
|
||||
fixed top-0 left-0 right-0 w-screen h-screen
|
||||
|
@ -18,5 +18,3 @@ const Loader = () => (
|
|||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default Loader
|
|
@ -1,13 +1,15 @@
|
|||
// Dependencies
|
||||
import { Fragment } from 'react'
|
||||
import { LocaleIcon, DownIcon } from 'shared/components/icons.mjs'
|
||||
import { useRouter } from 'next/router'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { Popover, Transition } from '@headlessui/react'
|
||||
import Link from 'next/link'
|
||||
// Components
|
||||
import { I18nIcon, DownIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
export const ns = ['locales']
|
||||
|
||||
const LocalePicker = ({ iconOnly = false, bottom = false }) => {
|
||||
export const LocalePicker = ({ iconOnly = false, bottom = false }) => {
|
||||
const { t } = useTranslation(ns)
|
||||
const router = useRouter()
|
||||
|
||||
|
@ -18,7 +20,7 @@ const LocalePicker = ({ iconOnly = false, bottom = false }) => {
|
|||
<Popover.Button
|
||||
className={`h-12 group border-0 inline-flex items-center px-3 text-base text-neural-content hover:bg-neutral-focus`}
|
||||
>
|
||||
<LocaleIcon />
|
||||
<I18nIcon />
|
||||
{!iconOnly && <span className="ml-4 font-medium capitalize">{t(router.locale)}</span>}
|
||||
<DownIcon className={`ml-2 h-5 w-5 ${bottom ? 'rotate-180' : ''}`} aria-hidden="true" />
|
||||
</Popover.Button>
|
||||
|
@ -61,5 +63,3 @@ const LocalePicker = ({ iconOnly = false, bottom = false }) => {
|
|||
</Popover>
|
||||
)
|
||||
}
|
||||
|
||||
export default LocalePicker
|
|
@ -1,7 +0,0 @@
|
|||
const CcByLogo = ({ color='currentColor', className="w-6 h-6" }) => (
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" className={className}>
|
||||
<path d="M 15.979992,0 C 11.547725,0 7.7962273,1.5468447 4.7257722,4.6397397 1.5749793,7.8390824 0,11.625762 0,15.997998 c 0,4.372236 1.5749793,8.13178 4.7257722,11.27823 3.1507936,3.145777 6.9022908,4.71977 11.2542198,4.71977 4.405488,0 8.224496,-1.585888 11.454296,-4.759785 C 30.477964,24.223648 32,20.478011 32,15.997998 32,11.517982 30.452163,7.7326347 27.356259,4.6397397 24.257681,1.546858 20.465819,0 15.979992,0 Z m 0.04001,2.8790794 c 3.631518,0 6.715299,1.2794302 9.251469,3.8394394 2.562949,2.5325614 3.845442,5.6262482 3.845442,9.2794792 0,3.679334 -1.256021,6.733309 -3.765412,9.159434 -2.644631,2.613564 -5.753553,3.91947 -9.331499,3.91947 -3.579291,0 -6.6630856,-1.292667 -9.2514698,-3.879454 -2.5910732,-2.586786 -3.8834564,-5.653341 -3.8834564,-9.19945 0,-3.546782 1.3069629,-6.6398113 3.9234714,-9.2794792 C 9.3179574,4.1584963 12.388488,2.8790794 16.020008,2.8790794 Z m -0.09803,2.7870445 c -1.20598,0.042082 -2.16164,1.0322514 -2.16081,2.2388397 -9.9e-5,1.2364266 1.002285,2.2388084 2.23884,2.2388394 1.236554,-3.1e-5 2.238936,-1.0024128 2.238839,-2.2388394 9.8e-5,-1.2364264 -1.002285,-2.2388088 -2.238839,-2.2388397 -0.02601,-4.528e-4 -0.05202,-4.528e-4 -0.07803,0 z m -3.195198,5.3380011 c -0.5691,0 -1.032387,0.461333 -1.032387,1.032388 v 6.544454 h 1.826685 v 7.748906 h 4.95986 v -7.748906 h 1.824684 v -6.544454 c 0,-0.571042 -0.463288,-1.032389 -1.032389,-1.032388 z" fill={color} stroke="none" />
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default CcByLogo
|
9
sites/shared/components/logos/cc-by.mjs
Normal file
9
sites/shared/components/logos/cc-by.mjs
Normal file
|
@ -0,0 +1,9 @@
|
|||
export const CCByLogo = ({ color = 'currentColor', className = 'w-6 h-6' }) => (
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" className={className}>
|
||||
<path
|
||||
d="M 15.979992,0 C 11.547725,0 7.7962273,1.5468447 4.7257722,4.6397397 1.5749793,7.8390824 0,11.625762 0,15.997998 c 0,4.372236 1.5749793,8.13178 4.7257722,11.27823 3.1507936,3.145777 6.9022908,4.71977 11.2542198,4.71977 4.405488,0 8.224496,-1.585888 11.454296,-4.759785 C 30.477964,24.223648 32,20.478011 32,15.997998 32,11.517982 30.452163,7.7326347 27.356259,4.6397397 24.257681,1.546858 20.465819,0 15.979992,0 Z m 0.04001,2.8790794 c 3.631518,0 6.715299,1.2794302 9.251469,3.8394394 2.562949,2.5325614 3.845442,5.6262482 3.845442,9.2794792 0,3.679334 -1.256021,6.733309 -3.765412,9.159434 -2.644631,2.613564 -5.753553,3.91947 -9.331499,3.91947 -3.579291,0 -6.6630856,-1.292667 -9.2514698,-3.879454 -2.5910732,-2.586786 -3.8834564,-5.653341 -3.8834564,-9.19945 0,-3.546782 1.3069629,-6.6398113 3.9234714,-9.2794792 C 9.3179574,4.1584963 12.388488,2.8790794 16.020008,2.8790794 Z m -0.09803,2.7870445 c -1.20598,0.042082 -2.16164,1.0322514 -2.16081,2.2388397 -9.9e-5,1.2364266 1.002285,2.2388084 2.23884,2.2388394 1.236554,-3.1e-5 2.238936,-1.0024128 2.238839,-2.2388394 9.8e-5,-1.2364264 -1.002285,-2.2388088 -2.238839,-2.2388397 -0.02601,-4.528e-4 -0.05202,-4.528e-4 -0.07803,0 z m -3.195198,5.3380011 c -0.5691,0 -1.032387,0.461333 -1.032387,1.032388 v 6.544454 h 1.826685 v 7.748906 h 4.95986 v -7.748906 h 1.824684 v -6.544454 c 0,-0.571042 -0.463288,-1.032389 -1.032389,-1.032388 z"
|
||||
fill={color}
|
||||
stroke="none"
|
||||
/>
|
||||
</svg>
|
||||
)
|
File diff suppressed because one or more lines are too long
8
sites/shared/components/logos/cc.mjs
Normal file
8
sites/shared/components/logos/cc.mjs
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,36 +0,0 @@
|
|||
import React from 'react'
|
||||
import { logoPath } from 'shared/components/icons/freesewing.js'
|
||||
import colors from 'tailwindcss/colors'
|
||||
|
||||
const strokes = {
|
||||
light: colors.neutral[300],
|
||||
dark: colors.neutral[800],
|
||||
hax0r: colors.lime[700],
|
||||
lgbtq: colors.neutral[500],
|
||||
trans: colors.neutral[500],
|
||||
}
|
||||
let step = 0
|
||||
|
||||
const Logo = ({ className = 'w-20 h-20', theme = 'light', stroke = false }) => {
|
||||
const svgProps = {
|
||||
xmlns: 'http://www.w3.org/2000/svg',
|
||||
viewBox: '1 0 25 25',
|
||||
className: className,
|
||||
}
|
||||
return (
|
||||
<svg {...svgProps}>
|
||||
<defs>
|
||||
<path id="react-logo" d={logoPath} />
|
||||
</defs>
|
||||
<use
|
||||
xlinkHref="#react-logo"
|
||||
fill="none"
|
||||
stroke={stroke || strokes[theme]}
|
||||
strokeWidth="0.5"
|
||||
/>
|
||||
<use xlinkHref="#react-logo" fill="currentColor" stroke="none" />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export default Logo
|
36
sites/shared/components/logos/freesewing.mjs
Normal file
36
sites/shared/components/logos/freesewing.mjs
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,7 +0,0 @@
|
|||
const OsiLogo = ({ color='currentColor', className="w-6 h-6" }) => (
|
||||
<svg viewBox="-0.5 -0.5 33 33" xmlns="http://www.w3.org/2000/svg" className={className}>
|
||||
<path d="m16 15.993m1.9113 4.9789a5.333 5.333 0 1 0-3.8226 0l-3.5923 9.3604a15.359 15.359 0 1 1 11.007 0z" fill="none" stroke={color} strokeWidth="2"/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default OsiLogo
|
10
sites/shared/components/logos/osi.mjs
Normal file
10
sites/shared/components/logos/osi.mjs
Normal file
|
@ -0,0 +1,10 @@
|
|||
export const OsiLogo = ({ color = 'currentColor', className = 'w-6 h-6' }) => (
|
||||
<svg viewBox="-0.5 -0.5 33 33" xmlns="http://www.w3.org/2000/svg" className={className}>
|
||||
<path
|
||||
d="m16 15.993m1.9113 4.9789a5.333 5.333 0 1 0-3.8226 0l-3.5923 9.3604a15.359 15.359 0 1 1 11.007 0z"
|
||||
fill="none"
|
||||
stroke={color}
|
||||
strokeWidth="2"
|
||||
/>
|
||||
</svg>
|
||||
)
|
|
@ -1,5 +1,5 @@
|
|||
import { Tutorial } from '@freesewing/tutorial'
|
||||
import { Examples } from '@freesewing/examples'
|
||||
import { Examples as Pattern } from '@freesewing/examples'
|
||||
import Svg from '../workbench/draft/svg'
|
||||
import Defs from '../workbench/draft/defs'
|
||||
import Stack from '../workbench/draft/stack'
|
||||
|
@ -11,7 +11,7 @@ import Md from 'react-markdown'
|
|||
// head: 320,
|
||||
// },
|
||||
//}
|
||||
const ExamplesComponent = ({ app, part, caption, xray }) => {
|
||||
export const Examples = ({ app, part, caption, xray }) => {
|
||||
// State for gist
|
||||
const { gist, unsetGist, updateGist } = useGist('examples-mdx', app)
|
||||
|
||||
|
@ -21,7 +21,7 @@ const ExamplesComponent = ({ app, part, caption, xray }) => {
|
|||
}
|
||||
|
||||
//const measurements = part.includes('tutorial') ? measurementSets.tutorial : {}
|
||||
const pattern = Examples
|
||||
const pattern = Pattern
|
||||
const draft = new pattern({
|
||||
only: [`examples.${part}`],
|
||||
measurements: {},
|
||||
|
@ -61,5 +61,3 @@ const ExamplesComponent = ({ app, part, caption, xray }) => {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ExamplesComponent
|
|
@ -1,38 +0,0 @@
|
|||
import Popout from 'shared/components/popout'
|
||||
import Lightbox from 'shared/components/lightbox'
|
||||
import ImageWrapper from 'shared/components/wrappers/img.js'
|
||||
|
||||
const Figure = props => {
|
||||
|
||||
const title = props?.title
|
||||
? props.title
|
||||
: props?.alt
|
||||
? props.alt
|
||||
: false
|
||||
|
||||
return (
|
||||
<figure className="block my-4">
|
||||
<Lightbox>
|
||||
<ImageWrapper>
|
||||
<img
|
||||
src={props?.src}
|
||||
alt={props?.alt || ''}
|
||||
title={title || ''}
|
||||
className="m-auto"
|
||||
/>
|
||||
</ImageWrapper>
|
||||
{title
|
||||
? <figcaption className="text-center italic mt-1">{title}</figcaption>
|
||||
: (
|
||||
<Popout fixme>
|
||||
<h5>This image does not have an alt of title specified</h5>
|
||||
<p>Please improve our documentation and fix this.</p>
|
||||
</Popout>
|
||||
)
|
||||
}
|
||||
</Lightbox>
|
||||
</figure>
|
||||
)
|
||||
}
|
||||
|
||||
export default Figure
|
25
sites/shared/components/mdx/figure.mjs
Normal file
25
sites/shared/components/mdx/figure.mjs
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { Popout } from 'shared/components/popout.mjs'
|
||||
import { Lightbox } from 'shared/components/lightbox.mjs'
|
||||
import { ImageWrapper } from 'shared/components/wrappers/img.mjs'
|
||||
|
||||
export const Figure = (props) => {
|
||||
const title = props?.title ? props.title : props?.alt ? props.alt : false
|
||||
|
||||
return (
|
||||
<figure className="block my-4">
|
||||
<Lightbox>
|
||||
<ImageWrapper>
|
||||
<img src={props?.src} alt={props?.alt || ''} title={title || ''} className="m-auto" />
|
||||
</ImageWrapper>
|
||||
{title ? (
|
||||
<figcaption className="text-center italic mt-1">{title}</figcaption>
|
||||
) : (
|
||||
<Popout fixme>
|
||||
<h5>This image does not have an alt of title specified</h5>
|
||||
<p>Please improve our documentation and fix this.</p>
|
||||
</Popout>
|
||||
)}
|
||||
</Lightbox>
|
||||
</figure>
|
||||
)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import CopyToClipboard from 'shared/components/copy-to-clipboard'
|
||||
import StatusCode from './status-code.js'
|
||||
import { CopyToClipboard } from 'shared/components/copy-to-clipboard.mjs'
|
||||
import { HttpStatusCode } from './http.mjs'
|
||||
|
||||
const names = {
|
||||
js: 'Javascript',
|
||||
|
@ -9,7 +9,7 @@ const names = {
|
|||
yaml: 'file.yaml',
|
||||
}
|
||||
|
||||
const Highlight = (props) => {
|
||||
export const Highlight = (props) => {
|
||||
let language = 'txt'
|
||||
let status = false
|
||||
if (props.language) language = props.language
|
||||
|
@ -36,11 +36,9 @@ const Highlight = (props) => {
|
|||
`}
|
||||
>
|
||||
<span>{names[language] ? names[language] : language}</span>
|
||||
{status ? <StatusCode status={status} /> : <CopyToClipboard content={props.children} />}
|
||||
{status ? <HttpStatusCode status={status} /> : <CopyToClipboard content={props.children} />}
|
||||
</div>
|
||||
<pre {...preProps}>{props.children}</pre>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Highlight
|
|
@ -5,7 +5,7 @@ const methodClasses = {
|
|||
delete: 'bg-red-600 text-white',
|
||||
}
|
||||
|
||||
const Method = (props) => {
|
||||
export const HttpMethod = (props) => {
|
||||
let method = false
|
||||
for (const m in methodClasses) {
|
||||
if (!method && props[m]) method = m.toUpperCase()
|
||||
|
@ -22,4 +22,20 @@ const Method = (props) => {
|
|||
)
|
||||
}
|
||||
|
||||
export default Method
|
||||
const statusClasses = {
|
||||
2: 'bg-green-600 text-white',
|
||||
4: 'bg-orange-500 text-white',
|
||||
5: 'bg-red-600 text-white',
|
||||
}
|
||||
|
||||
export const HttpStatusCode = ({ status }) => {
|
||||
return (
|
||||
<div
|
||||
className={`my-1 text-xs inline-flex items-center font-bold leading-sm uppercase px-3 py-1 rounded-full ${
|
||||
statusClasses['' + status.slice(0, 1)]
|
||||
}`}
|
||||
>
|
||||
{status}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,20 +1,19 @@
|
|||
import Popout from '../popout.js'
|
||||
import Highlight from './highlight.js'
|
||||
import YouTube from './youtube.js'
|
||||
import Figure from './figure.js'
|
||||
import ReadMore from './read-more.js'
|
||||
import { Tab, Tabs } from './tabs.js'
|
||||
import Example from './example.js'
|
||||
import Examples from './examples.js'
|
||||
import Method from './http-method.js'
|
||||
import StatusCode from './status-code.js'
|
||||
import { Popout } from 'shared/components/popout.mjs'
|
||||
import { Highlight } from './highlight.mjs'
|
||||
import { YouTube } from './youtube.mjs'
|
||||
import { Figure } from './figure.mjs'
|
||||
import { ReadMore } from './read-more.mjs'
|
||||
import { Tab, Tabs } from './tabs.mjs'
|
||||
import { TabbedExample as Example } from './tabbed-example.mjs'
|
||||
import { Examples } from './examples.mjs'
|
||||
import { HttpMethod, HttpStatusCode } from './http.mjs'
|
||||
|
||||
const Fixme = () => <p>FIXME</p>
|
||||
|
||||
const mdxCustomComponents = (app = false) => ({
|
||||
export const MdxComponents = (app = false) => ({
|
||||
// Custom components
|
||||
Method,
|
||||
StatusCode,
|
||||
Method: HttpMethod,
|
||||
StatusCode: HttpStatusCode,
|
||||
Comment: (props) => <Popout {...props} comment />,
|
||||
Fixme: (props) => <Popout {...props} fixme />,
|
||||
Link: (props) => <Popout {...props} link />,
|
||||
|
@ -38,7 +37,3 @@ const mdxCustomComponents = (app = false) => ({
|
|||
PatternDocs: Fixme,
|
||||
PatternOptions: Fixme,
|
||||
})
|
||||
|
||||
export default mdxCustomComponents
|
||||
|
||||
//<span className="bg-secondary px-2 mx-1 rounded text-primary-content bg-opacity-80">{children}</span>
|
|
@ -74,7 +74,7 @@ const next = (app) => {
|
|||
const renderPrevious = (node) =>
|
||||
node ? (
|
||||
<div className="flex flex-row gap-2 items-center">
|
||||
<LeftIcon className="w-6 h-6" />
|
||||
<LeftIcon className="w-6 h-6 shrink-0" />
|
||||
<Link href={'/' + node.__slug} className="text-secondary break-words">
|
||||
{node.__linktitle}
|
||||
</Link>
|
||||
|
@ -89,13 +89,13 @@ const renderNext = (node) =>
|
|||
<Link href={'/' + node.__slug} className="text-right break-words">
|
||||
{node.__linktitle}
|
||||
</Link>
|
||||
<RightIcon className="w-6 h-6" />
|
||||
<RightIcon className="w-6 h-6 shrink-0" />
|
||||
</div>
|
||||
) : (
|
||||
<span></span>
|
||||
)
|
||||
|
||||
const PrevNext = ({ app }) => {
|
||||
export const PrevNext = ({ app }) => {
|
||||
return (
|
||||
<div className="grid grid-cols-2 gap-4 border-t mt-12 py-2">
|
||||
{renderPrevious(previous(app))}
|
||||
|
@ -103,5 +103,3 @@ const PrevNext = ({ app }) => {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PrevNext
|
|
@ -7,7 +7,7 @@ const order = (obj) => orderBy(obj, ['__order', '__title'], ['asc', 'asc'])
|
|||
const currentChildren = (current) =>
|
||||
Object.values(order(current)).filter((entry) => typeof entry === 'object')
|
||||
|
||||
const ReadMore = (props) => {
|
||||
export const ReadMore = (props) => {
|
||||
// Don't bother if we don't have the navigation tree in app
|
||||
if (!props.app) return null
|
||||
|
||||
|
@ -28,5 +28,3 @@ const ReadMore = (props) => {
|
|||
}
|
||||
return <ul>{list}</ul>
|
||||
}
|
||||
|
||||
export default ReadMore
|
|
@ -1,19 +0,0 @@
|
|||
const statusClasses = {
|
||||
2: 'bg-green-600 text-white',
|
||||
4: 'bg-orange-500 text-white',
|
||||
5: 'bg-red-600 text-white',
|
||||
}
|
||||
|
||||
const StatusCode = ({ status }) => {
|
||||
return (
|
||||
<div
|
||||
className={`my-1 text-xs inline-flex items-center font-bold leading-sm uppercase px-3 py-1 rounded-full ${
|
||||
statusClasses['' + status.slice(0, 1)]
|
||||
}`}
|
||||
>
|
||||
{status}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default StatusCode
|
|
@ -1,4 +1,4 @@
|
|||
import { Tab, Tabs } from './tabs.js'
|
||||
import { Tab, Tabs } from './tabs.mjs'
|
||||
import Md from 'react-markdown'
|
||||
import { pluginBundle } from '@freesewing/plugin-bundle'
|
||||
import { pluginFlip } from '@freesewing/plugin-flip'
|
||||
|
@ -99,7 +99,7 @@ const buildExample = (children, settings = { margin: 5 }, tutorial = false, pape
|
|||
}
|
||||
|
||||
// Wrapper component dealing with the tabs and code view
|
||||
const TabbedExample = ({
|
||||
export const TabbedExample = ({
|
||||
app,
|
||||
children,
|
||||
caption,
|
||||
|
@ -156,5 +156,3 @@ const TabbedExample = ({
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TabbedExample
|
|
@ -19,7 +19,9 @@ export const Tabs = ({ tabs = '', active = 0, children }) => {
|
|||
{tablist.map((title, tabId) => (
|
||||
<button
|
||||
key={tabId}
|
||||
className={`text-xl font-bold capitalize tab tab-bordered grow ${activeTab === tabId ? 'tab-active' : ''}`}
|
||||
className={`text-xl font-bold capitalize tab tab-bordered grow ${
|
||||
activeTab === tabId ? 'tab-active' : ''
|
||||
}`}
|
||||
onClick={() => setActiveTab(tabId)}
|
||||
>
|
||||
{title}
|
|
@ -1,4 +1,4 @@
|
|||
const YouTube = (props) => (
|
||||
export const YouTube = (props) => (
|
||||
<iframe
|
||||
className="w-full aspect-video"
|
||||
src={
|
||||
|
@ -9,6 +9,3 @@ const YouTube = (props) => (
|
|||
frameBorder="0"
|
||||
/>
|
||||
)
|
||||
|
||||
export default YouTube
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
const Modal = ({ cancel, children }) => (
|
||||
<div className={`
|
||||
fixed top-0 left-0 right-0 w-screen h-screen
|
||||
bg-neutral bg-opacity-80 z-30
|
||||
hover:cursor-pointer flex flex-col justify-center
|
||||
`} onClick={cancel}>
|
||||
<div className="m-auto text-neutral-content lightbox" style={{
|
||||
maxHeight: "calc(100vh - 6rem)",
|
||||
maxWidth: "calc(100vw - 6rem)",
|
||||
}}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default Modal
|
20
sites/shared/components/modal.mjs
Normal file
20
sites/shared/components/modal.mjs
Normal file
|
@ -0,0 +1,20 @@
|
|||
export const Modal = ({ cancel, children }) => (
|
||||
<div
|
||||
className={`
|
||||
fixed top-0 left-0 right-0 w-screen h-screen
|
||||
bg-neutral bg-opacity-80 z-30
|
||||
hover:cursor-pointer flex flex-col justify-center
|
||||
`}
|
||||
onClick={cancel}
|
||||
>
|
||||
<div
|
||||
className="m-auto text-neutral-content lightbox"
|
||||
style={{
|
||||
maxHeight: 'calc(100vh - 6rem)',
|
||||
maxWidth: 'calc(100vw - 6rem)',
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
|
@ -1,7 +1,8 @@
|
|||
import PrimaryNavigation from './primary'
|
||||
import { PrimaryNavigation } from './primary.mjs'
|
||||
|
||||
const Aside = ({ app, slug, mobileOnly=false, before=[], after=[]}) => (
|
||||
<aside className={`
|
||||
export const AsideNavigation = ({ app, slug, mobileOnly = false, before = [], after = [] }) => (
|
||||
<aside
|
||||
className={`
|
||||
fixed top-0 right-0 h-screen w-screen
|
||||
overflow-y-auto z-20
|
||||
bg-base-100 text-base-content md:bg-base-50
|
||||
|
@ -16,11 +17,10 @@ const Aside = ({ app, slug, mobileOnly=false, before=[], after=[]}) => (
|
|||
xl:w-lg xl:border-0
|
||||
2xl:pr-8
|
||||
${mobileOnly ? 'block md:hidden' : ''}
|
||||
`}>
|
||||
`}
|
||||
>
|
||||
{before}
|
||||
<PrimaryNavigation app={app} active={slug}/>
|
||||
<PrimaryNavigation app={app} active={slug} />
|
||||
{after}
|
||||
</aside>
|
||||
)
|
||||
|
||||
export default Aside
|
|
@ -12,7 +12,7 @@ import {
|
|||
UserIcon,
|
||||
CommunityIcon,
|
||||
ShowcaseIcon,
|
||||
} from 'shared/components/icons.mjks'
|
||||
} from 'shared/components/icons.mjs'
|
||||
|
||||
// Don't show children for blog and showcase posts
|
||||
const keepClosed = ['blog', 'showcase']
|
||||
|
@ -257,7 +257,7 @@ export const Icons = ({
|
|||
return <ul className={ulClasses}>{output}</ul>
|
||||
}
|
||||
|
||||
const PrimaryMenu = ({ app, active, before = [], after = [] }) => (
|
||||
export const PrimaryNavigation = ({ app, active, before = [], after = [] }) => (
|
||||
<nav className="mb-12">
|
||||
{before}
|
||||
<Icons app={app} ulClasses="hidden md:block lg:hidden flex flex-col items-center" />
|
||||
|
@ -265,5 +265,3 @@ const PrimaryMenu = ({ app, active, before = [], after = [] }) => (
|
|||
{after}
|
||||
</nav>
|
||||
)
|
||||
|
||||
export default PrimaryMenu
|
|
@ -1,6 +1,6 @@
|
|||
import Link from 'next/link'
|
||||
|
||||
const PageLink = ({ href, txt, className = '' }) => (
|
||||
export const PageLink = ({ href, txt, className = '' }) => (
|
||||
<Link
|
||||
href={href}
|
||||
className={`font-medium text-secondary hover:text-secondary-focus hover:underline ${className}`}
|
||||
|
@ -9,5 +9,3 @@ const PageLink = ({ href, txt, className = '' }) => (
|
|||
{txt}
|
||||
</Link>
|
||||
)
|
||||
|
||||
export default PageLink
|
|
@ -2,6 +2,8 @@ import { forwardRef } from 'react'
|
|||
import { Menu } from '@headlessui/react'
|
||||
import Link from 'next/link'
|
||||
|
||||
// FIXME: Is this even used at all?
|
||||
|
||||
/** an accessible dropdown menu for use by picker components */
|
||||
export const Picker = ({ Icon, className, title, ariaLabel, iconOnly = false, children, end }) => {
|
||||
return (
|
|
@ -12,7 +12,7 @@ const colors = {
|
|||
none: '',
|
||||
}
|
||||
|
||||
const Popout = (props) => {
|
||||
export const Popout = (props) => {
|
||||
const [hide, setHide] = useState(false)
|
||||
if (hide) return null
|
||||
|
||||
|
@ -75,5 +75,3 @@ const Popout = (props) => {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Popout
|
|
@ -1,5 +0,0 @@
|
|||
const RawSpan = ({ html='' }) => <span
|
||||
dangerouslySetInnerHTML={{ __html: html }}
|
||||
/>
|
||||
|
||||
export default RawSpan
|
1
sites/shared/components/raw-span.mjs
Normal file
1
sites/shared/components/raw-span.mjs
Normal file
|
@ -0,0 +1 @@
|
|||
export const RawSpan = ({ html = '' }) => <span dangerouslySetInnerHTML={{ __html: html }} />
|
|
@ -1,11 +1,9 @@
|
|||
import themes from 'shared/themes/runtime.js'
|
||||
import { themes } from 'shared/themes/runtime.mjs'
|
||||
|
||||
const Ribbon = ({ loading = false, theme = 'light' }) => (
|
||||
export const Ribbon = ({ loading = false, theme = 'light' }) => (
|
||||
<div
|
||||
className={`flex flex-col justify-between p-0 transition-transform
|
||||
${loading ? 'theme-gradient loading h-1' : 'h-0 -translate-y-1'}
|
||||
`}
|
||||
></div>
|
||||
)
|
||||
|
||||
export default Ribbon
|
|
@ -1,19 +1,20 @@
|
|||
import poses from './poses'
|
||||
import { fail, ohno, shrug, shrug2, yay } from './poses.mjs'
|
||||
|
||||
// pose is one of:
|
||||
// fail,
|
||||
// ohno,
|
||||
// shrug,
|
||||
// shrug2,
|
||||
// yay
|
||||
const poses = {
|
||||
fail,
|
||||
ohno,
|
||||
shrug,
|
||||
shrug2,
|
||||
yay,
|
||||
}
|
||||
|
||||
const Robot = ({
|
||||
export const Robot = ({
|
||||
size = 124,
|
||||
viewBox = '0 0 500 500',
|
||||
className = '',
|
||||
pose = 'yay',
|
||||
color = false,
|
||||
embed = false
|
||||
embed = false,
|
||||
}) => (
|
||||
<svg
|
||||
className={className || ''}
|
||||
|
@ -25,5 +26,3 @@ const Robot = ({
|
|||
<path stroke="none" fill={color ? color : 'currentColor'} d={poses[pose]} />
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default Robot
|
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue