feat: use builder page as new home

pull/579/head
Amio 2023-01-04 09:31:10 +08:00
rodzic 7571613001
commit f0ebc06449
12 zmienionych plików z 1375 dodań i 850 usunięć

Wyświetl plik

@ -1,17 +1,17 @@
import Link from 'next/link' import Link from 'next/link'
import Image from 'next/image' import Image from 'next/image'
import { Merriweather } from '@next/font/google' // import { Merriweather } from '@next/font/google'
const merriweather = Merriweather({ subsets: ['latin'], weight: ["300", "700"] }) // const merriweather = Merriweather({ subsets: ['latin'], weight: ["300", "700"] })
export default function BadgenTitle ({ host }) { export default function BadgenTitle ({ host }) {
return ( return (
<div className='title-block'> <div className='title-block'>
<div className={`title ${merriweather.className}`}> <div className='title'>
<h1> <h1>
<Image alt='badgen logo' src='/static/badgen-logo.svg' width='42' height='42' /> <Image className='badgen-icon' alt='badgen logo' src='/static/badgen-logo.svg' width='42' height='42' />
Badgen <span className='badgen-name'>Badgen</span>
<StyleSwitch host={host} /> <StyleSwitch host={host} />
</h1> </h1>
<div>Fast badge generating service</div> <div>Fast badge generating service</div>
@ -42,19 +42,18 @@ export default function BadgenTitle ({ host }) {
transition-delay: 100ms; transition-delay: 100ms;
} }
.title h1 { .title h1 {
font: 46px/42px Merriweather, Georgia, serif;
font-weight: 700;
color: #333; color: #333;
height: 52px; height: 52px;
width: 235px; width: 240px;
position: relative; position: relative;
} }
.title h1 img { .title .badgen-name {
height: 42px; font: 50px/46px Merriweather, Georgia, serif;
width: 42px; font-weight: 700;
vertical-align: top; display: inline;
margin-top: -1px; margin-left: 5px;
margin-right: 10px; position: relative;
top: -2px;
} }
.title div { .title div {
font: 20px/32px Merriweather, Georgia, serif; font: 20px/32px Merriweather, Georgia, serif;

Wyświetl plik

@ -18,25 +18,35 @@ export default function BuilderHelper ({ badgeURL, onSelect }: BuilderHelperProp
const matched = examples.filter(eg => eg[0].includes(badgeURL)) const matched = examples.filter(eg => eg[0].includes(badgeURL))
const hints = matched.length === 1 && matched[0][0] === '/' + badgeURL ? null : ( const hints = matched.length === 1 && matched[0][0] === '/' + badgeURL ? null : (
<table> <div className='suggestions'>
<tbody>
{ {
matched.map(eg => ( matched.map(eg => (
<Hint <dl key={eg[0]} onClick={e => onSelect(eg[0].replace(/^\//, ''))}>
key={eg[0]} <dt>{eg[1]}</dt>
info={eg} <dd>{eg[0]}</dd>
onSelect={e => onSelect(eg[0].replace(/^\//, ''))} </dl>
/>
)) ))
} }
</tbody> <style jsx>{`
</table> .suggestions { padding-top: 10px; }
dl {
font-size: 14px;
line-height: 36px;
cursor: default;
white-space: nowrap;
display: flex;
}
dt { font-weight: bold; width: 300px; overflow: visible; text-align: right }
dd { margin-left: 20px; width: 640px; overflow: visible; font-family: menlo, monospace; }
dd:hover { cursor: pointer; text-decoration: underline }
`}</style>
</div>
) )
return ( return (
<div className='helper'> <div className='helper'>
{hints} {hints}
<style>{` <style jsx>{`
.helper { .helper {
height: 50vh; height: 50vh;
width: 100%; width: 100%;
@ -54,32 +64,3 @@ export default function BuilderHelper ({ badgeURL, onSelect }: BuilderHelperProp
</div> </div>
) )
} }
const Hint = ({ info, onSelect }) => (
<tr onClick={onSelect}>
<th>{info[1]}</th>
<td>{info[0]}</td>
<style>{`
tr {
font-size: 15px;
line-height: 36px;
cursor: default;
white-space: nowrap;
padding: 0 1em;
vertical-align: baseline;
}
th {
text-align: right;
padding: 0 1em;
}
td {
font-family: monospace;
}
td:hover {
cursor: pointer;
text-decoration: underline;
}
`}
</style>
</tr>
)

Wyświetl plik

@ -1,4 +1,5 @@
import * as CSS from 'csstype' import * as CSS from 'csstype'
import Link from 'next/link'
export default function BuilderHints ({ focus, badgeURL }) { export default function BuilderHints ({ focus, badgeURL }) {
const visible = !focus && !badgeURL const visible = !focus && !badgeURL
@ -9,31 +10,28 @@ export default function BuilderHints ({ focus, badgeURL }) {
return ( return (
<div className='hints' style={style}> <div className='hints' style={style}>
<Hint left={0} width={50} height={3}> <Hint left={0} width={50} height={3}>
<div style={{ textAlign: 'left', marginBottom: '2em' }}> <Link href='/help#generators'>GENERATER (static or live badge)</Link>
SERVICE_NAME (static badge / live badge)
</div>
</Hint> </Hint>
<Hint left={66} width={70} height={2}>TEXT</Hint> <Hint left={66} width={70} height={2}>TEXT</Hint>
<Hint left={153} width={60} height={2}>TEXT</Hint> <Hint left={153} width={60} height={2}>TEXT</Hint>
<Hint left={230} width={50} height={2}> <Hint left={230} width={50} height={2}>
&nbsp;RGB / <a href='/#colors'>COLOR_NAME</a> (optional) <Link href='/help#colors'>COLOR</Link> (optional)
</Hint> </Hint>
<Hint left={290} width={110} height={1}> <Hint left={290} width={110} height={1}>
<a href='/#options'>OPTIONS (icon, label, etc.)</a> <Link href='/help#options'>OPTIONS (icon, label, etc.)</Link>
</Hint> </Hint>
<style>{` <style jsx>{`
.hints { .hints {
height: 0;
position: relative; position: relative;
overflow: visible; overflow: visible;
width: 100%; width: 100%;
left: -147px; left: -147px;
transition: all 200ms cubic-bezier(0.215, 0.61, 0.355, 1); transition: all 200ms cubic-bezier(0.215, 0.61, 0.355, 1);
} }
a { .hint a {
color: #333; color: #333;
} }
a:hover { .hint a:hover {
border-bottom: 1px dashed #333; border-bottom: 1px dashed #333;
text-decoration: none; text-decoration: none;
} }

Wyświetl plik

@ -1,3 +1,4 @@
/* eslint-disable @next/next/no-img-element */
import Link from 'next/link' import Link from 'next/link'
import Image from 'next/image' import Image from 'next/image'
@ -15,8 +16,6 @@ export default function Footer () {
<em>/</em> <em>/</em>
<Link href='https://flat.badgen.net'>Flat</Link> <Link href='https://flat.badgen.net'>Flat</Link>
<em>/</em> <em>/</em>
<Link href='/builder'>Builder</Link>
<em>/</em>
<Link href='https://github.com/badgen/badgen.net'>GitHub</Link> <Link href='https://github.com/badgen/badgen.net'>GitHub</Link>
<em>/</em> <em>/</em>
<Link href='https://twitter.com/badgen_net'>Twitter</Link> <Link href='https://twitter.com/badgen_net'>Twitter</Link>
@ -33,81 +32,14 @@ export default function Footer () {
</div> </div>
<div className='links'> <div className='links'>
<a title='badgen twitter link' href='https://twitter.com/badgen_net'> <a title='badgen twitter link' href='https://twitter.com/badgen_net'>
<img alt='badgen twitter link' src='https://simpleicons.now.sh/twitter/fff' width='30' height='30' /> <img alt='badgen twitter link' src='https://simpleicons.vercel.app/twitter/fff' width='30' height='30' />
</a> </a>
<a href='https://github.com/badgen/badgen.net'> <a href='https://github.com/badgen/badgen.net'>
<img alt='badgen github link' src='https://simpleicons.now.sh/github/fff' width='30' height='30' /> <img alt='badgen github link' src='https://simpleicons.vercel.app/github/fff' width='30' height='30' />
</a> </a>
</div> </div>
</div> </div>
</div> </div>
<style jsx>{`
footer {
margin-top: 8rem;
background-color: #222;
padding: 2rem 2rem;
color: #777;
}
.footer-content {
margin: 0 auto;
}
footer h3 {
font: 22px/32px Merriweather, Georgia, serif;
letter-spacing: 0.5px;
color: #DDD;
margin-bottom: 1em;
}
footer h3 img {
height: 21px;
opacity: 0.8;
margin-right: 8px;
position: relative;
top: 1px;
}
.sitemap {
line-height: 26px;
}
.sitemap a {
color: #999;
text-transform: uppercase;
letter-spacing: 0.5px;
display: inline;
}
a:hover {
color: #EEE;
text-decoration: underline;
}
.sitemap em {
color: #555;
margin: 0 0.6rem;
}
.bottom {
margin-top: 2rem;
border-top: 1px solid #444;
padding-top: 2rem;
display: grid;
grid-template-columns: 1fr 100px;
}
.bottom a {
color: #999;
display: inline;
}
.links {
text-align: right;
}
.links a {
opacity: 0.7;
display: inline;
}
.links a:hover {
opacity: 1;
}
.links img {
height: 22px;
}
`}
</style>
</footer> </footer>
)} )}

Wyświetl plik

@ -1,12 +1,12 @@
import icons from 'badgen-icons' import icons from 'badgen-icons'
import Image from 'next/image' import Image from 'next/image'
import { Open_Sans } from '@next/font/google' // import { Open_Sans } from '@next/font/google'
const openSans = Open_Sans({ subsets: ['latin'], weight: ['400'] }) // const openSans = Open_Sans({ subsets: ['latin'], weight: ['400'] })
export default function HomeIntro ({ isFlat = false }) { export default function HomeIntro ({ isFlat = false }) {
return ( return (
<div className={`home-intro ${openSans.className}`}> <div className={`home-intro`}>
<pre>{explainCode(isFlat)}</pre> <pre>{explainCode(isFlat)}</pre>
<h3>Options</h3> <h3>Options</h3>
@ -76,7 +76,7 @@ export default function HomeIntro ({ isFlat = false }) {
font-weight: 400; font-weight: 400;
} }
ul { padding-left: 2em; } ul { padding-left: 2em; font-family: "Open Sans", sans-serif }
li { vertical-align: top; font-size: 14px; line-height: 24px; color: #777; margin: 5px 0 } li { vertical-align: top; font-size: 14px; line-height: 24px; color: #777; margin: 5px 0 }
li code { padding: 0.3em 0.5em; display: pre; color: #333; background: #EEF2F8 } li code { padding: 0.3em 0.5em; display: pre; color: #333; background: #EEF2F8 }
li a { display: inline; margin-left: 0.3em; text-decoration: underline } li a { display: inline; margin-left: 0.3em; text-decoration: underline }

Wyświetl plik

@ -4,9 +4,10 @@ const badgeList = require('./public/.meta/badges.json')
const nextConfig = { const nextConfig = {
reactStrictMode: true, reactStrictMode: true,
optimizeFonts: false,
experimental: { experimental: {
appDir: true, appDir: false,
forceSwcTransforms: true, forceSwcTransforms: true,
}, },

1753
package-lock.json wygenerowano

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,6 +1,16 @@
import '../styles/globals.css' import '../styles/globals.css'
import Head from 'next/head'
import type { AppProps } from 'next/app' import type { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) { export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} /> return (
<>
<Head>
<meta name="viewport" content="viewport-fit=cover" />
{/* <meta name='viewport' content='initial-scale=1.0, width=device-width' /> */}
</Head>
<Component {...pageProps} />
</>
)
} }

Wyświetl plik

@ -6,8 +6,8 @@ export default function Document() {
<Html lang="en"> <Html lang="en">
<Head> <Head>
<link rel='icon' type='image/png' href='/static/favicon.png' /> <link rel='icon' type='image/png' href='/static/favicon.png' />
<meta name='viewport' content='initial-scale=1.0, width=device-width' />
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Merriweather:700,300&display=swap' /> <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Merriweather:700,300&display=swap' />
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Inter:700,300&display=swap' />
<Script <Script
src="https://www.googletagmanager.com/gtag/js?id=UA-4646421-14" src="https://www.googletagmanager.com/gtag/js?id=UA-4646421-14"
strategy="afterInteractive" strategy="afterInteractive"

69
pages/help.tsx 100644
Wyświetl plik

@ -0,0 +1,69 @@
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import { useState, useEffect } from 'react'
import BadgenTitle from '../components/badgen-title'
import Intro from '../components/home-intro'
import Footer from '../components/footer'
import examples from '../public/.meta/badges.json'
export default function Index () {
const [host, setHost] = useState('')
useEffect(() => {
const forceHost = new URL(window.location.href).searchParams.get('host')
setHost((forceHost || window.location.origin) + '/')
})
return <>
<Head>
<title>Badgen: fast badge generating service</title>
<meta name="description" content="fast badge generating service" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<BadgenTitle host={host} />
<div className='body-wrapper'>
<Intro />
</div>
<Footer />
<style jsx>{`
.docs {
margin: 0 auto;
padding-bottom: 6em;
}
p {
text-align: center
}
.tab-row {
text-align: center;
}
.tab {
display: inline-block;
border: 1px solid #333;
margin-bottom: 2rem;
}
.tab a {
display: inline-block;
padding: 0 8px;
color: #333;
font: 14px/26px sans-serif;
text-transform: uppercase;
}
.tab a:hover {
cursor: pointer;
}
.live a.live,
.static a.static {
color: #EEE;
background-color: #333;
}
.body-wrapper {
padding-bottom: 6rem;
}
`}
</style>
</> // eslint-disable-line
}

Wyświetl plik

@ -1,88 +1,62 @@
import Head from 'next/head' import React from 'react'
import Image from 'next/image' import Preview from '../components/builder-preview'
import { Inter, Merriweather } from '@next/font/google' import Bar from '../components/builder-bar'
import styles from '../styles/Home.module.css' import Hints from '../components/builder-hints'
import Helper from '../components/builder-helper'
const inter = Inter({ subsets: ['latin'] })
const merriweather = Inter({ subsets: ['latin'] })
// export default function Home() {
// return (
// <>
// <Head>
// <title>Create Next App</title>
// <meta name="description" content="Generated by create next app" />
// <meta name="viewport" content="width=device-width, initial-scale=1" />
// <link rel="icon" href="/favicon.ico" />
// </Head>
// <main className={styles.main}>
// asdf
// </main>
// </>
// )
// }
import { useState, useEffect } from 'react'
import BadgenTitle from '../components/badgen-title'
import Intro from '../components/home-intro'
import Footer from '../components/footer' import Footer from '../components/footer'
import examples from '../public/.meta/badges.json'
export default function Index () { export default class BuilderPage extends React.Component {
const [tab, setTab] = useState('live') state = {
const [host, setHost] = useState('') host: undefined,
const badges = examples[tab] badgeURL: '',
placeholder: '',
focus: false
}
useEffect(() => { handleBlur = () => this.setState({ focus: false })
handleFocus = () => this.setState({ focus: true })
handleChange = badgeURL => this.setState({ badgeURL })
handleSelect = exampleURL => this.setState({ badgeURL: exampleURL })
componentDidMount () {
const forceHost = new URL(window.location.href).searchParams.get('host') const forceHost = new URL(window.location.href).searchParams.get('host')
setHost((forceHost || window.location.origin) + '/') this.setState({
host: (forceHost || window.location.origin) + '/',
badgeURL: window.location.hash.replace(/^#/, ''),
placeholder: 'badge/:subject/:status/:color?icon=github'
}) })
}
return <> render () {
<Head> const { host, placeholder, badgeURL, focus } = this.state
<title>Badgen: fast badge generating service</title>
<meta name="description" content="fast badge generating service" /> return (
<meta name="viewport" content="width=device-width, initial-scale=1" /> <div className='home'>
<link rel="icon" href="/favicon.ico" /> <div className='hero'>
</Head> <Preview host={host} badgeURL={badgeURL} focus={focus} />
<BadgenTitle host={host} /> <Bar
<div className='body-wrapper'> host={host}
<Intro /> badgeURL={badgeURL}
placeholder={placeholder}
onChange={this.handleChange}
onBlur={this.handleBlur}
onFocus={this.handleFocus}
/>
<Hints focus={focus} badgeURL={badgeURL} />
{badgeURL && <Helper host={host} badgeURL={badgeURL} onSelect={this.handleSelect} />}
</div> </div>
<Footer /> <Footer />
<style jsx>{` <style jsx>{`
.docs { .hero {
margin: 0 auto; min-height: 100vh;
padding-bottom: 6em; position: relative;
}
p {
text-align: center
}
.tab-row {
text-align: center;
}
.tab {
display: inline-block;
border: 1px solid #333;
margin-bottom: 2rem;
}
.tab a {
display: inline-block;
padding: 0 8px;
color: #333;
font: 14px/26px sans-serif;
text-transform: uppercase;
}
.tab a:hover {
cursor: pointer;
}
.live a.live,
.static a.static {
color: #EEE;
background-color: #333;
} }
`} `}
</style> </style>
</> // eslint-disable-line </div>
)
}
} }

Wyświetl plik

@ -33,3 +33,69 @@ a {
width: 980px; width: 980px;
margin: 0 auto; margin: 0 auto;
} }
/** ============= Footer ============= */
footer {
background-color: #222;
padding: 2rem 2rem;
color: #777;
}
footer h3 {
font: 22px/32px Merriweather, Georgia, serif;
letter-spacing: 0.5px;
color: #DDD;
margin-bottom: 1em;
}
footer h3 img {
height: 21px;
opacity: 0.8;
margin-right: 8px;
position: relative;
top: 1px;
}
footer .sitemap {
line-height: 26px;
}
footer .sitemap a {
color: #999;
text-transform: uppercase;
letter-spacing: 0.5px;
display: inline;
}
footer a:hover {
color: #EEE;
text-decoration: underline;
}
.sitemap em {
color: #555;
margin: 0 0.6rem;
}
.bottom {
margin-top: 2rem;
border-top: 1px solid #444;
padding-top: 2rem;
display: grid;
grid-template-columns: 1fr 100px;
}
.bottom a {
color: #999;
display: inline;
}
.links {
text-align: right;
}
.links a {
opacity: 0.6;
display: inline;
margin-left: 0.5rem;
}
.links a:hover {
opacity: 1;
}
.links img {
height: 22px;
}
.footer-content {
}