1
0
Fork 0

chore: Adapt sites to recent changes

This commit is contained in:
Joost De Cock 2022-06-17 12:02:09 +02:00
parent 147920daeb
commit 43ee0f1790
392 changed files with 1269 additions and 1190 deletions

77
.gitignore vendored
View file

@ -3,10 +3,12 @@
# .env
.env
# Specifics
export
packages/plugin-theme/src/bundle.css.js
packages/plugin-theme/css
# Plugins
plugins/plugin-theme/src/bundle.css.js
plugins/plugin-theme/css
# Components package build artifacts
packages/components/Blockquote
packages/components/Draft
packages/components/DraftConfigurator
@ -27,8 +29,12 @@ packages/components/withGist
packages/components/withLanguage
packages/components/withStorage
packages/components/Workbench
# Code coverage reports
packages/core/coverage
packages/workbench
packages/*/report
# Utils package build artifacts
packages/utils/backend
packages/utils/camelCase
packages/utils/capitalize
@ -54,60 +60,48 @@ packages/utils/tiler
packages/utils/validateEmail
packages/utils/validateTld
packages/*/example/yarn.lock
packages/*/report
# Any NPM or Yarn lock files
designs/*/package-lock.json
designs/*/yarn.lock
packages/*/package-lock.json
packages/*/yarn.lock
packages/strapi/.cache
plugins/*/package-lock.json
plugins/*/yarn.lock
packages/freesewing.dev/public/locales/en/*.json
# NPM lock files for sites (we use yarn)
sites/*/package-lock.json
packages/freesewing.org/public/locales/en/*.json
packages/freesewing.org/public/locales/es/*.json
packages/freesewing.org/public/locales/de/*.json
packages/freesewing.org/public/locales/fr/*.json
packages/freesewing.org/public/locales/nl/*.json
# Strapi cache
sites/strapi/.cache
packages/freesewing.lab/public/locales/en/*.json
packages/freesewing.lab/public/locales/es/*.json
packages/freesewing.lab/public/locales/de/*.json
packages/freesewing.lab/public/locales/fr/*.json
packages/freesewing.lab/public/locales/nl/*.json
# Sites prebuild artifacts
sites/*/public/locales/*/*.json
sites/*/public/feeds/*
packages/freesewing.org/public/feeds/*
packages/freesewing.dev/public/feeds/*
# Lab auto-generated pages
sites/lab/lib
sites/lab/pages
packages/freesewing.lab/lib
packages/freesewing.lab/pages
# dependencies
# Node dependencies
node_modules
# build
# Build folders
dist
build
export
#prebuild
# Prebuild files
prebuild/*.json
# yarn
# Yarn
.yarn
.yarnrc
# NextJS
.next
packages/freesewing.dev/out
packages/freesewing.lab/out
packages/freesewing.org/out
packages/freesewing.dev/public/mdx
packages/freesewing.lab/public/mdx
packages/freesewing.org/public/mdx
packages/freesewing.dev/prebuild
packages/freesewing.lab/prebuild
packages/freesewing.org/prebuild
# Mock registry (verdaccio)
.registry
sites/*/out
sites/*/public/mdx
sites/*/prebuild
# misc
.DS_Store
@ -127,9 +121,6 @@ packages/i18n/sort.sh
scripts/taskrunner.sh
scripts/verdaccio.sh
# Local Netlify folder
.netlify
# Don't ignore the specific Points.dist() docs folder
!markdown/dev/reference/api/point/dist

File diff suppressed because it is too large Load diff

View file

@ -45,3 +45,5 @@ export const degreeMeasurements = ['shoulderSlope']
/* Helper method to determine whether a measurement uses degrees */
export const isDegreeMeasurement = (measie) => degreeMeasurements.indexOf(measie) !== -1

View file

@ -1,12 +1,24 @@
{
"aaron": "A FreeSewing pattern for a A-shirt or tank top",
"albert": "A FreeSewing pattern for an apron",
"bee": "A FreeSewing pattern for a bikini top",
"bella": "A FreeSewing pattern for a womenswear bodice block",
"accessories": {
"benjamin": "A FreeSewing pattern for a bow tie",
"florence": "A FreeSewing pattern for a face mask",
"florent": "A FreeSewing pattern for a flat cap",
"hi": "A FreeSewing pattern for a shark plush toy",
"holmes": "A FreeSewing pattern for a Sherlock Holmes hat",
"hortensia": "A FreeSewing pattern for a handbag",
"trayvon": "A FreeSewing pattern for a tie"
},
"blocks": {
"bella": "A FreeSewing pattern for a womenswear bodice block",
"bent": "A FreeSewing pattern for a menswear body block with a two-part sleeve",
"breanna": "A FreeSewing pattern for a basic body block for womenswear",
"brian": "A FreeSewing pattern for a basic body block for menswear",
"titan": "A FreeSewing pattern for a unisex trouser block"
},
"garments": {
"aaron": "A FreeSewing pattern for a A-shirt or tank top",
"albert": "A FreeSewing pattern for an apron",
"bee": "A FreeSewing pattern for a bikini top",
"bruce": "A FreeSewing pattern for boxer briefs",
"carlita": "A FreeSewing pattern for Sherlock Holmes cosplay; Or just a nice long coat",
"carlton": "A FreeSewing pattern for Sherlock Holmes cosplay; Or just a nice long coat",
@ -14,22 +26,13 @@
"charlie": "A FreeSewing pattern for chino trousers",
"cornelius": "A FreeSewing pattern for cycling breeches, based on the Keystone drafting system",
"diana": "A FreeSewing pattern for a top with a draped neck",
"examples": "A FreeSewing pattern holding examples for our documentation",
"florence": "A FreeSewing pattern for a face mask",
"florent": "A FreeSewing pattern for a flat cap",
"hi": "A FreeSewing pattern for a shark plush toy",
"holmes": "A FreeSewing pattern for a Sherlock Holmes hat",
"hortensia": "A FreeSewing pattern for a handbag",
"huey": "A FreeSewing pattern for a zip-up hoodie",
"hugo": "A FreeSewing pattern for a hooded jumper with raglan sleeves",
"jaeger": "A FreeSewing pattern for a sport coat style jacket",
"legend": "A FreeSewing pattern to document pattern notation",
"lucy": "A FreeSewing pattern for a historical tie-on pocket",
"lunetius": "A FreeSewing pattern for a lacerna, a historical Roman cloak",
"paco": "A FreeSewing pattern for summer pants",
"penelope": "A FreeSewing pattern for a pencil skirt",
"plugintest": "A FreeSewing pattern to test (y)our plugins",
"rendertest": "A FreeSewing pattern to test (y)our render engine our CSS",
"sandy": "A FreeSewing pattern for a circle skirt",
"shin": "A FreeSewing pattern for swim trunks",
"simon": "A FreeSewing pattern for a button down shirt",
@ -39,13 +42,18 @@
"teagan": "A FreeSewing pattern for a T-shirt",
"theo": "A FreeSewing pattern for classic trousers",
"tiberius": "A FreeSewing pattern for a tunica, a historical Roman tunic",
"titan": "A FreeSewing pattern for a unisex trouser block",
"trayvon": "A FreeSewing pattern for a tie",
"tutorial": "A FreeSewing pattern for a baby bib that's used in our tutorial",
"unice": "A FreeSewing pattern for a basic, highly-customizable underwear pattern",
"ursula": "A FreeSewing pattern for a basic, highly-customizable underwear pattern",
"wahid": "A FreeSewing pattern for a classic fitted waistcoat",
"walburga": "A FreeSewing pattern for a wappenrock (tabard/surcoat), a historical European/medieval (ish) garment",
"waralee": "A FreeSewing pattern for wrap pants",
"yuri": "A FreeSewing pattern for a fancy zipless sweater based on the Huey hoodie"
},
"utilities": {
"examples": "A FreeSewing pattern holding examples for our documentation",
"legend": "A FreeSewing pattern to document pattern notation",
"plugintest": "A FreeSewing pattern to test (y)our plugins",
"rendertest": "A FreeSewing pattern to test (y)our render engine our CSS",
"tutorial": "A FreeSewing pattern for a baby bib that's used in our tutorial"
}
}

View file

@ -1,4 +1,4 @@
import designs from './designs.json'
import designsByType from './designs.json'
import packages from './packages.json'
import plugins from './plugins.json'
import sites from './sites.json'
@ -8,8 +8,15 @@ const unpack = (obj, folder) => Object.fromEntries(
Object.keys(obj).map(name => [name, { name, folder, description: obj[name], type: folder.slice(0, -1) } ])
)
const designs = {
...designsByType.accessories,
...designsByType.blocks,
...designsByType.garments,
...designsByType.utilities,
}
// Re-Export imported JSON
export { designs, packages, plugins, sites }
export { designs, designsByType, packages, plugins, sites }
// All software
export const software = {

View file

@ -1,9 +1,9 @@
{
"backend": "FreeSewing backend",
"freesewing.dev": "FreeSewing website with documentation for contributors & developers",
"freesewing.lab": "FreeSewing website to test various patterns",
"freesewing.org": "FreeSewing website",
"freesewing.shared": "Shared code and React components for different websites",
"dev": "FreeSewing website with documentation for contributors & developers",
"lab": "FreeSewing website to test various patterns",
"org": "FreeSewing website",
"shared": "Shared code and React components for different websites",
"strapi": "Freesewing's Strapi instance",
"svgtopdf": "FreeSewing on-demand tiler"
}

View file

@ -4,7 +4,7 @@ import glob from 'glob'
import yaml from 'js-yaml'
import chalk from 'chalk'
import mustache from 'mustache'
import { capitalize } from '../sites/freesewing.shared/utils.mjs'
import { capitalize } from '../sites/shared/utils.mjs'
import conf from '../lerna.json'
const { version } = conf
import {

View file

@ -4,8 +4,6 @@ const config = {
index: 'freesewing.dev',
key: '589c7a7e4d9c95a4f12868581259bf3a', // Search-only API key
},
strapi: 'https://posts.freesewing.org',
monorepo: 'https://github.com/freesewing/freesewing'
}
export default config

View file

@ -0,0 +1,37 @@
import { useRouter } from 'next/router'
import Link from 'next/link'
// Shared components
import Aside from 'shared/components/navigation/aside'
import ThemePicker from 'shared/components/theme-picker'
import Breadcrumbs from 'shared/components/breadcrumbs.js'
import { getCrumbs } from 'shared/utils'
const DefaultLayout = ({ app, title=false, crumbs=false, children=[] }) => {
const router = useRouter()
const slug = router.asPath.slice(1)
const breadcrumbs = crumbs
? crumbs
: getCrumbs(app, slug, title)
return (
<div className="m-auto flex flex-row justify-center">
<Aside app={app} slug={slug} before={<ThemePicker app={app} className="block sm:hidden"/>}/>
<section className="py-28 md:py-36 max-w-7xl px-6 xl:pl-8 2xl:pl-16">
<div>
{title && (
<>
<Breadcrumbs title={title} crumbs={breadcrumbs} />
{title
? <h1>{title}</h1>
: <h1>{app.getTitle(slug)}</h1>
}
</>
)}
{children}
</div>
</section>
</div>
)
}
export default DefaultLayout

View file

@ -5,7 +5,7 @@ import { useRouter } from 'next/router'
import algoliasearch from 'algoliasearch/lite';
import { useHotkeys } from 'react-hotkeys-hook'
import { InstantSearch, connectHits, connectHighlight, connectSearchBox } from 'react-instantsearch-dom'
import config from 'site/freesewing.config.js'
import config from 'site/algolia.config.mjs'
const searchClient = algoliasearch(config.algolia.app, config.algolia.key)

View file

@ -0,0 +1,3 @@
import i18n from '../shared/config/i18n.config.mjs'
export default i18n()

View file

@ -1,4 +1,4 @@
import configBuilder from '../freesewing.shared/config/next.mjs'
import configBuilder from '../shared/config/next.mjs'
import i18nConfig from './next-i18next.config.js'
const config = configBuilder('dev')

View file

@ -3,16 +3,14 @@
"version": "2.21.0-rc.0",
"private": true,
"scripts": {
"dev": "next dev -p 3002",
"dev": "node --experimental-json-modules ./node_modules/.bin/next dev -p 8000",
"develop": "next dev -p 3002",
"prebuild": "SITE=dev node ../freesewing.shared/prebuild/index.mjs",
"prebuild": "SITE=dev node --experimental-json-modules ../shared/prebuild/index.mjs",
"build": "next build",
"export": "yarn prebuild && next build && next export && node scripts/algolia.mjs",
"start": "next start -p 3002",
"lint": "next lint",
"testdeploy": "next build && next export && netlify-cli deploy",
"deploy": "next build && next export && netlify-cli deploy --prod",
"serve": "pm2 start npm --name 'freesewing.dev' -- run start"
"serve": "pm2 start npm --name 'dev' -- run start"
},
"dependencies": {
"@heroicons/react": "^1.0.5",

View file

@ -0,0 +1,107 @@
import Page from 'site/components/wrappers/page.js'
import useApp from 'site/hooks/useApp.js'
import Link from 'next/link'
import TimeAgo from 'react-timeago'
import { strapiHost } from 'shared/config/freesewing.mjs'
import { strapiImage } from 'shared/utils'
import { useTranslation } from 'next-i18next'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
const strapi = "https://posts.freesewing.org"
const textShadow = {
style: {
textShadow: "1px 1px 1px #000000, -1px -1px 1px #000000, 1px -1px 1px #000000, -1px 1px 1px #000000, 2px 2px 1px #000000"
}
}
const Preview = ({ app, post }) => (
<div className="shadow rounded-lg">
<Link href={`/blog/${post.slug}`}>
<a title={post.title} className="hover:underline">
<div className="bg-base-100 w-full aspect-video shadow flex flex-column items-end rounded-lg" style={{
backgroundImage: `url(${strapi}${post.image.sizes.medium.url})`,
backgroundSize: 'cover',
}}>
<div className="grow"></div>
<div className="text-right mb-3 lg:mb-8">
<div className={`
bg-neutral text-neutral-content bg-opacity-40 text-right
px-4 py-1
lg:px-8 lg:py-4
`}>
<h5 className={`
text-neutral-content
text-xl font-bold
md:text-2xl md:font-normal
xl:text-3xl
`} {...textShadow}
>
{post.title}
</h5>
<p className={`
hidden md:block
m-0 p-1 -mt-2
text-neutral-content
leading-normal text-sm font-normal
opacity-70
`}{ ...textShadow}>
<TimeAgo date={post.date} /> by <strong>{post.author}</strong>
</p>
</div>
</div>
</div>
</a>
</Link>
</div>
)
const BlogIndexPage = (props) => {
const app = useApp()
const { t } = useTranslation()
return (
<Page app={app} title={t('blog')} slug='blog'>
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2 max-w-7xl">
{props.posts.map(post => <Preview app={app} post={post} key={post.slug}/>)
}
</div>
</Page>
)
}
export default BlogIndexPage
/*
* getStaticProps() is used to fetch data at build-time.
*
* On this page, it is loading the blog content from strapi.
*
* This, in combination with getStaticPaths() below means this
* page will be used to render/generate all blog content.
*
* To learn more, see: https://nextjs.org/docs/basic-features/data-fetching
*/
export async function getStaticProps({ params, locale }) {
const posts = await fetch(
`${strapiHost}/blogposts?_locale=en&_sort=date:DESC&dev_eq=true`
)
.then(response => response.json())
.then(data => data)
.catch(err => console.log(err))
return {
props: {
posts: posts.map(post => ({
slug: post.slug,
title: post.title,
date: post.date,
author: post.author.displayname,
image: strapiImage(post.image, ['medium']),
})),
...(await serverSideTranslations(locale)),
}
}
}

View file

@ -0,0 +1,5 @@
// Can't seem to make this work as ESM
const config = require('../shared/config/postcss.config.js')
module.exports = config

View file

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 118 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 313 KiB

After

Width:  |  Height:  |  Size: 313 KiB

Before After
Before After

View file

@ -0,0 +1,4 @@
// Can't seem to make this work as ESM
const config = require('../shared/config/tailwind.config.js')
module.exports = config

View file

@ -1,78 +0,0 @@
import React from 'react'
import { useRouter } from 'next/router'
import Link from 'next/link'
// Shared components
import Logo from 'shared/components/logos/freesewing.js'
import Aside from 'shared/components/navigation/aside'
import get from 'lodash.get'
const PageTitle = ({ app, slug, title }) => {
if (title) return <h1>{title}</h1>
if (slug) return <h1>{get(app.navigation, slug.split('/')).__title}</h1>
return <h1>FIXME: This page has no title</h1>
}
const Breadcrumbs = ({ app, slug=false, title }) => {
if (!slug) return null
const crumbs = []
const chunks = slug.split('/')
for (const i in chunks) {
const j = parseInt(i)+parseInt(1)
const page = get(app.navigation, chunks.slice(0,j))
if (page) crumbs.push([page.__linktitle, '/'+chunks.slice(0,j).join('/'), (j < chunks.length)])
}
return (
<ul className="flex flex-row flex-wrap gap-2 font-bold">
<li>
<Link href="/">
<a title="To the homepage" className="text-base-content">
<Logo size={24} fill="currentColor" stroke={false}/>
</a>
</Link>
</li>
{crumbs.map(crumb => (
<React.Fragment key={crumb[1]}>
<li className="text-base-content">&raquo;</li>
<li>
{crumb[2]
? (
<Link href={crumb[1]}>
<a title={crumb[0]} className="text-secondary hover:text-secondary-focus">
{crumb[0]}
</a>
</Link>
)
: <span className="text-base-content">{crumb[0]}</span>
}
</li>
</React.Fragment>
))}
</ul>
)
}
const DefaultLayout = ({ app, title=false, children=[] }) => {
const router = useRouter()
const slug = router.asPath.slice(1)
return (
<div className="m-auto flex flex-row justify-center">
<Aside app={app} slug={slug} />
<section className="py-28 md:py-36">
<div>
{title && (
<div className="px-8 xl:pl-8 2xl:pl-16">
<Breadcrumbs app={app} slug={slug} title={title} />
<PageTitle app={app} slug={slug} title={title} />
</div>
)}
{children}
</div>
</section>
</div>
)
}
export default DefaultLayout

View file

@ -1,115 +0,0 @@
import React from 'react'
import { useState } from 'react'
import { useRouter } from 'next/router'
import Link from 'next/link'
// Shared components
import Logo from 'shared/components/logos/freesewing.js'
import PrimaryNavigation from 'shared/components/navigation/primary'
import get from 'lodash.get'
import Right from 'shared/components/icons/right.js'
import Left from 'shared/components/icons/left.js'
// Site components
import Header from 'site/components/header'
import Footer from 'site/components/footer'
import Search from 'site/components/search'
const PageTitle = ({ app, slug, title }) => {
if (title) return <h1>{title}</h1>
if (slug) return <h1>{get(app.navigation, slug.split('/')).__title}</h1>
return <h1>FIXME: This page has no title</h1>
}
const Breadcrumbs = ({ app, slug=false, title }) => {
if (!slug) return null
const crumbs = []
const chunks = slug.split('/')
for (const i in chunks) {
const j = parseInt(i)+parseInt(1)
const page = get(app.navigation, chunks.slice(0,j))
if (page) crumbs.push([page.__linktitle, '/'+chunks.slice(0,j).join('/'), (j < chunks.length)])
}
return (
<ul className="flex flex-row flex-wrap gap-2 font-bold">
<li>
<Link href="/">
<a title="To the homepage" className="text-base-content">
<Logo size={24} fill="currentColor" stroke={false}/>
</a>
</Link>
</li>
{crumbs.map(crumb => (
<React.Fragment key={crumb[1]}>
<li className="text-base-content">&raquo;</li>
<li>
{crumb[2]
? (
<Link href={crumb[1]}>
<a title={crumb[0]} className="text-secondary hover:text-secondary-focus">
{crumb[0]}
</a>
</Link>
)
: <span className="text-base-content">{crumb[0]}</span>
}
</li>
</React.Fragment>
))}
</ul>
)
}
const LayoutWrapper = ({
app,
title=false,
children=[],
search,
setSearch,
noSearch=false,
workbench=false,
AltMenu=null,
}) => {
const startNavigation = () => {
app.startLoading()
// Force close of menu on mobile if it is open
if (app.primaryNavigation) app.setPrimaryNavigation(false)
// Force close of search modal if it is open
if (search) setSearch(false)
}
const router = useRouter()
router.events?.on('routeChangeStart', startNavigation)
router.events?.on('routeChangeComplete', () => app.stopLoading())
const slug = router.asPath.slice(1)
const [collapsePrimaryNav, setCollapsePrimaryNav] = useState(workbench || false)
const [collapseAltMenu, setCollapseAltMenu] = useState(false)
return (
<div className={`
flex flex-col justify-between
min-h-screen
bg-base-100
`}>
<Header app={app} setSearch={setSearch} />
<main className="grow">{children}</main>
{!noSearch && search && (
<>
<div className={`
fixed w-full max-h-screen bg-base-100 top-0 z-30 pt-0 pb-16 px-8
md:rounded-lg md:top-24
md:max-w-xl md:m-auto md:inset-x-12
md:max-w-2xl
lg:max-w-4xl
`}>
<Search app={app} search={search} setSearch={setSearch}/>
</div>
<div className="fixed top-0 left-0 w-full min-h-screen bg-neutral z-20 bg-opacity-70"></div>
</>
)}
<Footer app={app} />
</div>
)
}
export default LayoutWrapper

View file

@ -1,3 +0,0 @@
import i18n from '../freesewing.shared/config/i18n.config.mjs'
export default i18n()

View file

@ -1,88 +0,0 @@
import Page from 'shared/components/wrappers/page.js'
import useApp from 'site/hooks/useApp.js'
import Link from 'next/link'
import { posts } from 'site/prebuild/strapi.blog.en.js'
import orderBy from 'lodash.orderby'
import TimeAgo from 'react-timeago'
import Head from 'next/head'
import HelpUs from 'site/components/help-us.js'
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
const strapi = "https://posts.freesewing.org"
const Preview = ({ app, post }) => (
<div className="theme-gradient p-1 hover:p-0 hover:mb-1 hover:pointer transition-all">
<Link href={`/blog/${post.slug}`}>
<a title={post.title} className="hover:underline">
<div className="bg-base-100 w-full aspect-video shadow flex flex-column items-end" style={{
backgroundImage: `url(${strapi}${post.img})`,
backgroundSize: 'cover',
}}>
<div className="grow"></div>
<div className="text-right">
<div className={`
bg-neutral text-neutral-content
bg-opacity-80
px-4 text-right
`}>
<h5 className={`
text-neutral-content
text-xl font-normal
md:text-2xl md:font-light
`}>
{post.title}
</h5>
<p className={`
m-0 p-1 -mt-2
text-neutral-content
opacity-50
leading-normal text-sm font-normal
`}>
<TimeAgo date={post.date} /> by {post.author}
</p>
</div>
</div>
</div>
</a>
</Link>
</div>
)
const BlogIndexPage = (props) => {
const app = useApp()
return (
<Page app={app} title='FreeSewing Development Blog' slug='blog'>
<Head>
<meta property="og:title" content="FreeSewing Developers Blog" key="title" />
<meta property="og:type" content="article" key='type' />
<meta property="og:description" content="Content for developers and contributors alike. Strictly no sewing stuff" key='type' />
<meta property="og:article:author" content='Joost De Cock' key='author' />
<meta property="og:image" content="https://canary.backend.freesewing.org/og-img/en/dev/blog" key='image' />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url" content="https://freesewing.dev/blog" key='url' />
<meta property="og:locale" content="en_US" key='locale' />
<meta property="og:site_name" content="freesewing.dev" key='site' />
</Head>
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
{Object.values(orderBy(posts, ['date'], ['desc']))
.map(post => <Preview app={app} post={post} key={post.slug}/>)
}
</div>
<HelpUs slug='/blog' />
</Page>
)
}
export default BlogIndexPage
export async function getStaticProps({ locale }) {
return {
props: {
...(await serverSideTranslations('en')),
}
}
}

View file

@ -1,3 +0,0 @@
import i18n from '../freesewing.shared/config/i18n.config.mjs'
export default i18n()

View file

@ -1,46 +0,0 @@
import path from 'path'
import { readdirSync } from 'fs'
import i18nConfig from './next-i18next.config.js'
const getDirectories = source =>
readdirSync(source, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name)
const pkgs = getDirectories(path.resolve(`../`))
const config = {
experimental: {
externalDir: true,
},
i18n: i18nConfig.i18n,
pageExtensions: [ 'js' ],
webpack: (config, options) => {
// YAML support
config.module.rules.push({
test: /\.ya?ml$/,
type: 'json',
use: 'yaml-loader'
})
// Suppress warnings about importing version from package.json
// We'll deal with it in v3 of FreeSewing
config.ignoreWarnings = [
/only default export is available soon/
]
// Aliases
config.resolve.alias.shared = path.resolve('../freesewing.shared/')
config.resolve.alias.site = path.resolve(`.`)
config.resolve.alias.lib = path.resolve(`./lib`)
config.resolve.alias.pkgs = path.resolve(`../`)
// This forces webpack to load the code from source, rather than compiled bundle
for (const pkg of pkgs) {
config.resolve.alias[`@freesewing/${pkg}$`] = path.resolve(`../${pkg}/src/index.js`)
}
return config
}
}
export default config

View file

@ -1,5 +0,0 @@
// Can't seem to make this work as ESM
const config = require('../freesewing.shared/config/postcss.config.js')
module.exports = config

View file

@ -1 +0,0 @@
../../../freesewing.dev/public/img/splash.jpg

View file

@ -1,4 +0,0 @@
// Can't seem to make this work as ESM
const config = require('../freesewing.shared/config/tailwind.config.js')
module.exports = config

View file

@ -1,5 +0,0 @@
// Can't seem to make this work as ESM
const config = require('../freesewing.shared/config/postcss.config.js')
module.exports = config

View file

@ -1,4 +0,0 @@
// Can't seem to make this work as ESM
const config = require('../freesewing.shared/config/tailwind.config.js')
module.exports = config

View file

@ -1,60 +0,0 @@
{
"accessories": [
"florence",
"florent",
"hi",
"holmes",
"hortensia",
"lucy",
"trayvon"
],
"blocks": [
"bella",
"bent",
"brian",
"titan"
],
"garments": [
"aaron",
"albert",
"bee",
"benjamin",
"breanna",
"bruce",
"carlita",
"carlton",
"cathrin",
"charlie",
"cornelius",
"diana",
"huey",
"hugo",
"jaeger",
"lunetius",
"paco",
"penelope",
"sandy",
"shin",
"simon",
"simone",
"sven",
"tamiko",
"teagan",
"theo",
"tiberius",
"unice",
"ursula",
"wahid",
"walburga",
"waralee",
"yuri"
],
"utilities": [
"examples",
"legend",
"plugintest",
"rendertest",
"tutorial"
]
}

View file

@ -1,5 +0,0 @@
export const strapiHost = 'https://posts.freesewing.org'
export const monorepo = 'https://github.com/freesewing/freesewing'

View file

@ -1,7 +0,0 @@
const pitches = [
'This website does not track you',
"Come in, we're open",
'Made-to-measure sewing patterns',
]
export default pitches

View file

@ -1,11 +1,11 @@
import { useState } from 'react'
// Stores state in local storage
import useLocalStorage from 'shared/hooks/useLocalStorage.js'
// Patterns
import patterns from 'shared/config/designs.json'
// Designs
import { designsByType } from 'config/software/index.mjs'
// Locale and translation
import { useTranslation } from 'next-i18next'
import { capitalize } from 'shared/utils'
import { capitalize } from 'shared/utils.mjs'
import { formatVersionUri } from '../components/version-picker.js'
import useVersion from 'site/hooks/useVersion.js'
import useTheme from 'shared/hooks/useTheme'
@ -14,44 +14,46 @@ import useTheme from 'shared/hooks/useTheme'
const initialNavigation = (t, version) => {
const base = {
accessories: {
__title: t('accessoryPatterns'),
__order: t('accessoryPatterns'),
__linktitle: t('accessoryPatterns'),
__title: t('accessoryDesigns'),
__slug: 'accessories',
},
blocks: {
__title: t('blockPatterns'),
__order: t('blockPatterns'),
__linktitle: t('blockPatterns'),
__title: t('blockDesigns'),
__slug: 'blocks',
},
garments: {
__title: t('garmentPatterns'),
__order: t('garmentPatterns'),
__linktitle: t('garmentPatterns'),
__title: t('garmentDesigns'),
__slug: t('garments'),
},
utilities: {
__title: t('utilityPatterns'),
__order: t('utilityPatterns'),
__linktitle: t('utilityPatterns'),
__title: t('utilityDesigns'),
__slug: 'utilities',
},
}
for (const type in patterns) {
for (const design of patterns[type]) {
for (const type in designsByType) {
for (const design in designsByType[type]) {
base[type][design] = {
__title: capitalize(design),
__order: design,
__linktitle: capitalize(design),
__slug: formatVersionUri(version,design)
}
}
}
for (const key in base) {
base[key].__order = base[key].__title
base[key].__linktitle = base[key].__title
}
return base
}
const designs = {}
for (const type in designsByType) {
designs[type] = []
for (const design in designsByType[type]) {
designs[type].push(design)
}
}
function useApp(full = true) {
// Version
@ -68,7 +70,7 @@ function useApp(full = true) {
const [primaryMenu, setPrimaryMenu] = useState(false)
const [navigation, setNavigation] = useState(initialNavigation(t, version))
const [slug, setSlug] = useState('/')
const [pattern, setPattern] = useState(false)
const [design, setDesign] = useState(false)
const [loading, setLoading] = useState(false)
// State methods
@ -77,12 +79,12 @@ function useApp(full = true) {
return {
// Static vars
site: 'lab',
patterns,
designs,
// State
loading,
navigation,
pattern,
design,
primaryMenu,
slug,
theme,
@ -90,7 +92,7 @@ function useApp(full = true) {
// State setters
setLoading,
setNavigation,
setPattern,
setDesign,
setPrimaryMenu,
setSlug,
setTheme,

View file

@ -0,0 +1,3 @@
import i18n from '../shared/config/i18n.config.mjs'
export default i18n()

59
sites/lab/next.config.mjs Normal file
View file

@ -0,0 +1,59 @@
import path from 'path'
import { readdirSync } from 'fs'
import i18nConfig from './next-i18next.config.js'
import { designs, plugins, packages } from '../../config/software/index.mjs'
const getDirectories = source =>
readdirSync(source, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name)
const pkgs = getDirectories(path.resolve(`../`))
const config = {
experimental: {
externalDir: true,
},
i18n: i18nConfig.i18n,
pageExtensions: [ 'js' ],
webpack: (config, options) => {
// YAML support
config.module.rules.push({
test: /\.ya?ml$/,
type: 'json',
use: 'yaml-loader'
})
// Suppress warnings about importing version from package.json
// We'll deal with it in v3 of FreeSewing
config.ignoreWarnings = [
/only default export is available soon/
]
// Aliases
config.resolve.alias.shared = path.resolve('../shared/')
config.resolve.alias.site = path.resolve('.')
config.resolve.alias.lib = path.resolve('./lib')
config.resolve.alias.config = path.resolve('../../config/')
config.resolve.alias.designs = path.resolve('../../designs/')
config.resolve.alias.plugins = path.resolve('../../plugins/')
config.resolve.alias.pkgs = path.resolve('../../packages/')
// Load designs from source, rather than compiled package
for (const design in designs) {
config.resolve.alias[`@freesewing/${design}$`] = path.resolve(`../../designs/${design}/src/index.js`)
}
// Load plugins from source, rather than compiled package
for (const plugin in plugins) {
config.resolve.alias[`@freesewing/${plugin}$`] = path.resolve(`../../plugins/${plugin}/src/index.js`)
}
// Load these from source, rather than compiled package
for (const pkg of ['core', 'config-helpers', 'i18n', 'models']) {
config.resolve.alias[`@freesewing/${pkg}$`] = path.resolve(`../../packages/${pkg}/src/index.js`)
}
return config
}
}
export default config

View file

@ -3,17 +3,15 @@
"version": "2.21.0-rc.0",
"private": true,
"scripts": {
"dev": "next dev -p 3002",
"develop": "next dev -p 3002",
"prebuild": "cd ../utils && npm run build && cd - && SITE=lab node ../freesewing.shared/prebuild/index.mjs",
"dev": "node --experimental-json-modules ./node_modules/.bin/next dev -p 8000",
"develop": "next dev -p 8000",
"prebuild": "SITE=lab node --experimental-json-modules ../shared/prebuild/index.mjs",
"cibuild": "yarn prebuild && next build",
"build": "next build",
"export": "yarn prebuild && next build && next export",
"start": "next start -p 3002",
"lint": "next lint",
"testdeploy": "next build && next export && netlify-cli deploy",
"deploy": "next build && next export && netlify-cli deploy --prod",
"serve": "pm2 start npm --name 'freesewing.dev' -- run start"
"serve": "pm2 start npm --name 'dev' -- run start"
},
"dependencies": {
"@heroicons/react": "^1.0.5",

View file

@ -4,14 +4,14 @@ import WorkbenchWrapper from 'shared/components/wrappers/workbench.js'
import { useRouter } from 'next/router'
import Layout from 'site/components/layouts/lab'
const WorkbenchPage = ({ pattern }) => {
const WorkbenchPage = ({ design }) => {
const app = useApp()
const router = useRouter()
const { preload, from } = router.query
return (
<Page app={app}>
<WorkbenchWrapper {...{ app, pattern, preload, from }} layout={Layout} />
<WorkbenchWrapper {...{ app, design, preload, from }} layout={Layout} />
</Page>
)
}

Some files were not shown because too many files have changed in this diff Show more