chore(org): Move github components out of shared
This commit is contained in:
parent
50b6747584
commit
3da46fb672
7 changed files with 137 additions and 88 deletions
|
@ -1,5 +1,5 @@
|
||||||
// Dependencies
|
// Dependencies
|
||||||
import { nsMerge, capitalize, cloudflareImageUrl } from 'shared/utils.mjs'
|
import { nsMerge, capitalize, cloudflareImageUrl, yyyymmdd } from 'shared/utils.mjs'
|
||||||
// Hooks
|
// Hooks
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||||
|
@ -21,6 +21,7 @@ import {
|
||||||
import { Collapse } from 'shared/components/collapse.mjs'
|
import { Collapse } from 'shared/components/collapse.mjs'
|
||||||
import { Tab } from 'shared/components/account/bio.mjs'
|
import { Tab } from 'shared/components/account/bio.mjs'
|
||||||
import { CodeBox } from 'shared/components/code-box.mjs'
|
import { CodeBox } from 'shared/components/code-box.mjs'
|
||||||
|
import { PostArticle } from 'site/components/mdx/posts/article.mjs'
|
||||||
|
|
||||||
export const ns = nsMerge('account', authNs)
|
export const ns = nsMerge('account', authNs)
|
||||||
|
|
||||||
|
@ -165,45 +166,33 @@ export const CreateShowcasePost = ({ noTitle = false }) => {
|
||||||
{img ? (
|
{img ? (
|
||||||
<>
|
<>
|
||||||
<Tip>Here you can add any images you want to include in the post body.</Tip>
|
<Tip>Here you can add any images you want to include in the post body.</Tip>
|
||||||
{Object.keys(extraImages).map((key) => (
|
{Object.keys(extraImages).map((key) => {
|
||||||
<>
|
const markup =
|
||||||
<ImageInput
|
' +
|
||||||
setImg={(img) => setExtraImg(key, img)}
|
' "The image caption/title goes here")'
|
||||||
type="showcase"
|
return (
|
||||||
subId={key}
|
<>
|
||||||
img={extraImages[key]}
|
<ImageInput
|
||||||
slug={slug}
|
key={key}
|
||||||
/>
|
setImg={(img) => setExtraImg(key, img)}
|
||||||
</>
|
type="showcase"
|
||||||
))}
|
subId={key}
|
||||||
|
img={extraImages[key]}
|
||||||
|
slug={slug}
|
||||||
|
/>
|
||||||
|
{extraImages[key] && (
|
||||||
|
<>
|
||||||
|
<p>To include this image in your post, use this markdown snippet:</p>
|
||||||
|
<CodeBox code={markup} title="MarkDown" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})}
|
||||||
<button className="btn btn-secondary mt-2" onClick={addImage}>
|
<button className="btn btn-secondary mt-2" onClick={addImage}>
|
||||||
Add Image
|
Add Image
|
||||||
</button>
|
</button>
|
||||||
{Object.keys(extraImages).length > 0 && (
|
|
||||||
<>
|
|
||||||
<h5>Using extra images in your post</h5>
|
|
||||||
<p>To include these images, use this markup:</p>
|
|
||||||
<CodeBox>
|
|
||||||
{Object.keys(extraImages)
|
|
||||||
.map((key) => `[Image caption here][img${key}]`)
|
|
||||||
.join('\n\n')}
|
|
||||||
</CodeBox>
|
|
||||||
<p>Then, at at the bottom of your post, make sure to include this:</p>
|
|
||||||
<CodeBox>
|
|
||||||
{Object.keys(extraImages)
|
|
||||||
.map(
|
|
||||||
(key) =>
|
|
||||||
`[img${key}]: ${cloudflareImageUrl({
|
|
||||||
id: extraImages[key],
|
|
||||||
variant: 'main',
|
|
||||||
})}`
|
|
||||||
)
|
|
||||||
.join('\n')}
|
|
||||||
</CodeBox>
|
|
||||||
<pre></pre>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Popout note compact>
|
<Popout note compact>
|
||||||
|
@ -223,7 +212,20 @@ export const CreateShowcasePost = ({ noTitle = false }) => {
|
||||||
</Item>
|
</Item>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<p>Post preview here</p>
|
<>
|
||||||
|
<h1>{title}</h1>
|
||||||
|
<PostArticle
|
||||||
|
frontmatter={{
|
||||||
|
title,
|
||||||
|
maker: account.username,
|
||||||
|
date: yyyymmdd(),
|
||||||
|
caption,
|
||||||
|
intro,
|
||||||
|
}}
|
||||||
|
imgId={img}
|
||||||
|
body={body}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</AuthWrapper>
|
</AuthWrapper>
|
|
@ -6,55 +6,84 @@ import { TimeAgo } from 'shared/components/mdx/meta.mjs'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
||||||
import { cloudflareImageUrl } from 'shared/utils.mjs'
|
import { cloudflareImageUrl } from 'shared/utils.mjs'
|
||||||
|
import Markdown from 'react-markdown'
|
||||||
|
|
||||||
export const ns = ['common', 'posts']
|
export const ns = ['common', 'posts']
|
||||||
|
|
||||||
export const PostArticle = ({ frontmatter, MDX, imgId }) => {
|
export const PostArticle = (props) => {
|
||||||
const { t } = useTranslation('common')
|
const { t } = useTranslation('common')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className="mb-12 px-8 max-w-7xl">
|
<PostWrapper>
|
||||||
<div className="flex flex-row justify-between text-sm mb-1 mt-2">
|
<PostMeta frontmatter={props.frontmatter} t={t} />
|
||||||
<div>
|
<PostImage imgId={props.imgId} frontmatter={props.frontmatter} />
|
||||||
<TimeAgo date={frontmatter.date} t={t} /> [{frontmatter.date}]
|
<PostContent {...props} />
|
||||||
</div>
|
<PostAuthor frontmatter={props.frontmatter} />
|
||||||
<div>
|
</PostWrapper>
|
||||||
{frontmatter.designs?.map((design) => (
|
|
||||||
<PageLink
|
|
||||||
href={`/showcase/designs/${design}`}
|
|
||||||
txt={design}
|
|
||||||
key={design}
|
|
||||||
className="px-2 capitalize"
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
By{' '}
|
|
||||||
<a href="#maker" className="text-secondary hover:text-secondary-focus">
|
|
||||||
{frontmatter.author || frontmatter.maker || 'FIXME: No displayname'}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<figure>
|
|
||||||
<Lightbox>
|
|
||||||
<ImageWrapper>
|
|
||||||
<img
|
|
||||||
src={cloudflareImageUrl({ id: imgId })}
|
|
||||||
alt={frontmatter.caption}
|
|
||||||
className="shadow m-auto"
|
|
||||||
/>
|
|
||||||
</ImageWrapper>
|
|
||||||
<figcaption
|
|
||||||
className="text-center mb-8 prose m-auto"
|
|
||||||
dangerouslySetInnerHTML={{ __html: frontmatter.caption }}
|
|
||||||
/>
|
|
||||||
</Lightbox>
|
|
||||||
</figure>
|
|
||||||
<div className="strapi prose lg:prose-lg mb-12 m-auto">
|
|
||||||
<MdxWrapper>{MDX}</MdxWrapper>
|
|
||||||
</div>
|
|
||||||
<div className="max-w-prose text-lg lg:text-xl">
|
|
||||||
<Author author={frontmatter.author || frontmatter.maker} />
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PostWrapper = ({ children }) => <article className="mb-12 px-8 max-w-7xl">{children}</article>
|
||||||
|
|
||||||
|
const PostMeta = ({ frontmatter, t }) => (
|
||||||
|
<div className="flex flex-row justify-between text-sm mb-1 mt-2">
|
||||||
|
<div>
|
||||||
|
<TimeAgo date={frontmatter.date} t={t} /> [{frontmatter.date}]
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{frontmatter.designs?.map((design) => (
|
||||||
|
<PageLink
|
||||||
|
href={`/showcase/designs/${design}`}
|
||||||
|
txt={design}
|
||||||
|
key={design}
|
||||||
|
className="px-2 capitalize"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
By{' '}
|
||||||
|
<a href="#maker" className="text-secondary hover:text-secondary-focus">
|
||||||
|
{frontmatter.author || frontmatter.maker || 'FIXME: No displayname'}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
const PostImage = ({ imgId, frontmatter }) => (
|
||||||
|
<figure>
|
||||||
|
<Lightbox>
|
||||||
|
<ImageWrapper>
|
||||||
|
<img
|
||||||
|
src={cloudflareImageUrl({ id: imgId })}
|
||||||
|
alt={frontmatter.caption}
|
||||||
|
className="shadow m-auto"
|
||||||
|
/>
|
||||||
|
</ImageWrapper>
|
||||||
|
<figcaption
|
||||||
|
className="text-center mb-8 prose m-auto"
|
||||||
|
dangerouslySetInnerHTML={{ __html: frontmatter.caption }}
|
||||||
|
/>
|
||||||
|
</Lightbox>
|
||||||
|
</figure>
|
||||||
|
)
|
||||||
|
|
||||||
|
const PostAuthor = ({ frontmatter }) => (
|
||||||
|
<div className="max-w-prose text-lg lg:text-xl">
|
||||||
|
<Author author={frontmatter.author || frontmatter.maker} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
const PostContent = (props) =>
|
||||||
|
props.MDX ? <PostMDXContent {...props} /> : <PostPreviewContent {...props} />
|
||||||
|
|
||||||
|
const PostMDXContent = ({ MDX }) => (
|
||||||
|
<div className="strapi prose lg:prose-lg mb-12 m-auto">
|
||||||
|
<MdxWrapper>{MDX}</MdxWrapper>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
const PostPreviewContent = ({ body }) => (
|
||||||
|
<div className="strapi prose lg:prose-lg mb-12 m-auto">
|
||||||
|
<Markdown>{body}</Markdown>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { useTranslation } from 'next-i18next'
|
||||||
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||||
import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs'
|
import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs'
|
||||||
import { ns as apikeysNs } from 'shared/components/account/apikeys.mjs'
|
import { ns as apikeysNs } from 'shared/components/account/apikeys.mjs'
|
||||||
import { CreateShowcasePost } from 'shared/components/github/create-showcase.mjs'
|
import { CreateShowcasePost } from 'site/components/github/create-showcase.mjs'
|
||||||
|
|
||||||
// Translation namespaces used on this page
|
// Translation namespaces used on this page
|
||||||
const namespaces = [...new Set([...apikeysNs, ...authNs, ...pageNs])]
|
const namespaces = [...new Set([...apikeysNs, ...authNs, ...pageNs])]
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
export const CodeBox = ({ children }) => (
|
import { CopyIcon } from 'shared/components/icons.mjs'
|
||||||
|
import { CopyToClipboard } from 'shared/components/copy-to-clipboard.mjs'
|
||||||
|
|
||||||
|
export const CodeBox = ({ code, title }) => (
|
||||||
<div className="hljs my-4">
|
<div className="hljs my-4">
|
||||||
|
<div
|
||||||
|
className={`
|
||||||
|
flex flex-row justify-between items-center
|
||||||
|
text-xs font-medium text-success-content
|
||||||
|
mt-1 border-b border-neutral-content border-opacity-25
|
||||||
|
px-4 py-1 mb-2 lg:text-sm
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<span>{title}</span>
|
||||||
|
<CopyToClipboard text={code} />
|
||||||
|
</div>
|
||||||
<pre className="language-md hljs text-base lg:text-lg whitespace-break-spaces overflow-scroll pr-4">
|
<pre className="language-md hljs text-base lg:text-lg whitespace-break-spaces overflow-scroll pr-4">
|
||||||
{children}
|
{code}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import ReactDOMServer from 'react-dom/server'
|
import ReactDOMServer from 'react-dom/server'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { CopyIcon } from 'shared/components/icons.mjs'
|
import { CopyIcon, OkIcon } from 'shared/components/icons.mjs'
|
||||||
import { CopyToClipboard as Copy } from 'react-copy-to-clipboard'
|
import { CopyToClipboard as Copy } from 'react-copy-to-clipboard'
|
||||||
|
|
||||||
const strip = (html) =>
|
const strip = (html) =>
|
||||||
|
@ -22,7 +22,11 @@ export const CopyToClipboard = ({ content }) => {
|
||||||
return (
|
return (
|
||||||
<Copy text={text} onCopy={() => handleCopied(setCopied)}>
|
<Copy text={text} onCopy={() => handleCopied(setCopied)}>
|
||||||
<button className={copied ? 'text-success' : ''}>
|
<button className={copied ? 'text-success' : ''}>
|
||||||
<CopyIcon className="w-5 h-5" />
|
{copied ? (
|
||||||
|
<OkIcon className="w-5 h-5 text-success-content bg-success rounded-full p-1" stroke={4} />
|
||||||
|
) : (
|
||||||
|
<CopyIcon className="w-5 h-5 text-inherit" />
|
||||||
|
)}
|
||||||
</button>
|
</button>
|
||||||
</Copy>
|
</Copy>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue