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
|
||||
import { nsMerge, capitalize, cloudflareImageUrl } from 'shared/utils.mjs'
|
||||
import { nsMerge, capitalize, cloudflareImageUrl, yyyymmdd } from 'shared/utils.mjs'
|
||||
// Hooks
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
|
@ -21,6 +21,7 @@ import {
|
|||
import { Collapse } from 'shared/components/collapse.mjs'
|
||||
import { Tab } from 'shared/components/account/bio.mjs'
|
||||
import { CodeBox } from 'shared/components/code-box.mjs'
|
||||
import { PostArticle } from 'site/components/mdx/posts/article.mjs'
|
||||
|
||||
export const ns = nsMerge('account', authNs)
|
||||
|
||||
|
@ -165,45 +166,33 @@ export const CreateShowcasePost = ({ noTitle = false }) => {
|
|||
{img ? (
|
||||
<>
|
||||
<Tip>Here you can add any images you want to include in the post body.</Tip>
|
||||
{Object.keys(extraImages).map((key) => (
|
||||
<>
|
||||
<ImageInput
|
||||
key={key}
|
||||
setImg={(img) => setExtraImg(key, img)}
|
||||
type="showcase"
|
||||
subId={key}
|
||||
img={extraImages[key]}
|
||||
slug={slug}
|
||||
/>
|
||||
</>
|
||||
))}
|
||||
{Object.keys(extraImages).map((key) => {
|
||||
const markup =
|
||||
' +
|
||||
' "The image caption/title goes here")'
|
||||
return (
|
||||
<>
|
||||
<ImageInput
|
||||
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}>
|
||||
Add Image
|
||||
</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>
|
||||
|
@ -223,7 +212,20 @@ export const CreateShowcasePost = ({ noTitle = false }) => {
|
|||
</Item>
|
||||
</>
|
||||
) : (
|
||||
<p>Post preview here</p>
|
||||
<>
|
||||
<h1>{title}</h1>
|
||||
<PostArticle
|
||||
frontmatter={{
|
||||
title,
|
||||
maker: account.username,
|
||||
date: yyyymmdd(),
|
||||
caption,
|
||||
intro,
|
||||
}}
|
||||
imgId={img}
|
||||
body={body}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</AuthWrapper>
|
|
@ -6,55 +6,84 @@ import { TimeAgo } from 'shared/components/mdx/meta.mjs'
|
|||
import { useTranslation } from 'next-i18next'
|
||||
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
||||
import { cloudflareImageUrl } from 'shared/utils.mjs'
|
||||
import Markdown from 'react-markdown'
|
||||
|
||||
export const ns = ['common', 'posts']
|
||||
|
||||
export const PostArticle = ({ frontmatter, MDX, imgId }) => {
|
||||
export const PostArticle = (props) => {
|
||||
const { t } = useTranslation('common')
|
||||
|
||||
return (
|
||||
<article className="mb-12 px-8 max-w-7xl">
|
||||
<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>
|
||||
<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>
|
||||
<PostWrapper>
|
||||
<PostMeta frontmatter={props.frontmatter} t={t} />
|
||||
<PostImage imgId={props.imgId} frontmatter={props.frontmatter} />
|
||||
<PostContent {...props} />
|
||||
<PostAuthor frontmatter={props.frontmatter} />
|
||||
</PostWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
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 { ns as authNs } from 'shared/components/wrappers/auth/index.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
|
||||
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={`
|
||||
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">
|
||||
{children}
|
||||
{code}
|
||||
</pre>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import ReactDOMServer from 'react-dom/server'
|
||||
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'
|
||||
|
||||
const strip = (html) =>
|
||||
|
@ -22,7 +22,11 @@ export const CopyToClipboard = ({ content }) => {
|
|||
return (
|
||||
<Copy text={text} onCopy={() => handleCopied(setCopied)}>
|
||||
<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>
|
||||
</Copy>
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue