feat(org): Handle author claims for posts
This commit is contained in:
parent
46f884de69
commit
9610d7d11b
3 changed files with 180 additions and 24 deletions
|
@ -1,3 +1,7 @@
|
|||
import { useContext, useState } from 'react'
|
||||
import { ModalContext } from 'shared/context/modal-context.mjs'
|
||||
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
||||
import { cloudflareImageUrl, nsMerge } from 'shared/utils.mjs'
|
||||
import { makers } from 'site/prebuild/makers.mjs'
|
||||
// Components
|
||||
|
@ -6,6 +10,7 @@ import { Lightbox } from 'shared/components/lightbox.mjs'
|
|||
import { ImageWrapper } from 'shared/components/wrappers/img.mjs'
|
||||
import { TimeAgo, ns as timeagoNs } from 'shared/components/timeago/index.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { Link } from 'shared/components/link.mjs'
|
||||
import {
|
||||
BaseLayout,
|
||||
BaseLayoutLeft,
|
||||
|
@ -23,8 +28,12 @@ import { Toc, ns as tocNs } from 'shared/components/mdx/toc.mjs'
|
|||
import { PrevNext } from 'shared/components/prev-next.mjs'
|
||||
import { Tag } from 'shared/components/tag.mjs'
|
||||
import { UserProfile } from 'shared/components/user-profile.mjs'
|
||||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||
import { MarkdownInput } from 'shared/components/inputs.mjs'
|
||||
import { userCard } from 'shared/components/support/support.mjs'
|
||||
|
||||
export const ns = nsMerge(navNs, tocNs, timeagoNs, 'docs')
|
||||
export const ns = nsMerge(navNs, tocNs, timeagoNs, 'docs', 'account')
|
||||
|
||||
const PostMeta = ({ frontmatter, t }) => (
|
||||
<div className="flex flex-row justify-between text-sm mb-1 mt-2">
|
||||
|
@ -70,41 +79,187 @@ export const PostImage = ({ imgId, frontmatter }) => (
|
|||
</figure>
|
||||
)
|
||||
|
||||
const createIssue = async ({ account, setLoadingStatus, title, body, backend, setModal }) => {
|
||||
setLoadingStatus([true, 'account:oneMomentPlease'])
|
||||
const issueData = {
|
||||
title,
|
||||
body: account ? `${body}\n\n${userCard(account.id || false)}` : body,
|
||||
labels: ['%3A%2B1%3A+good+first+issue'],
|
||||
}
|
||||
const result = await backend.createIssue(issueData)
|
||||
if (result.success) {
|
||||
setLoadingStatus([true, 'account:nailedIt', true, true])
|
||||
setModal(
|
||||
<ModalWrapper flex="col" justify="top lg:justify-center" slideFrom="right" keepOpenOnClick>
|
||||
<div className="max-w-prose mdx">
|
||||
<h2>Issue created</h2>
|
||||
<p>Thank you for helping out.</p>
|
||||
<p>
|
||||
We <a href={result.data.issue.html_url}>created a new issue for this</a>.
|
||||
<br />
|
||||
If you would like to help out even more, the issue describes what file to change and
|
||||
what change needs to be made.
|
||||
</p>
|
||||
<p>
|
||||
You can do this via the GitHub website, so it is a great way to make a first
|
||||
contribution if you are new to open source.
|
||||
</p>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
)
|
||||
} else setLoadingStatus([true, 'backendError', true, false])
|
||||
}
|
||||
|
||||
export const PostContent = ({ mdx, dir }) => (
|
||||
<div className="strapi prose lg:prose-lg mb-12 m-auto">
|
||||
<MdxWrapper mdx={mdx} slug={`blog/${dir}`} />
|
||||
</div>
|
||||
)
|
||||
|
||||
const ClaimThisPost = ({ t, type }) => (
|
||||
<div id="maker" className="p-4 border rounded-lg shadow">
|
||||
<h3>Claim this post</h3>
|
||||
<p>
|
||||
This post has not (yet) been associated with a FreeSewing account. Please help us assign
|
||||
proper credit:
|
||||
const ClaimAuthor = ({ t, type }) => (
|
||||
<div className="max-w-prose">
|
||||
<h2>{t(`docs:i${type === 'blog' ? 'Wrote' : 'Made'}This`)}</h2>
|
||||
<p>Great, but it looks like you are not currently logged in.</p>
|
||||
<p>Please log in and then claim this post so we know what account to associate it with.</p>
|
||||
<p className="text-center">
|
||||
<Link href="/signin" className="btn btn-primary">
|
||||
Sign In
|
||||
</Link>
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<button className="btn btn-primary btn-outline">I know who wrote this</button>
|
||||
<button className="btn btn-primary">I wrote this</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
const Maker = ({ id, type, t }) =>
|
||||
const issueData = ({ type, dir, account, body = false }) => ({
|
||||
title: body
|
||||
? `An author suggestion was submitted for the ${type} post ${dir}`
|
||||
: `The ${type} post ${dir} was claimed as their own by user ${account.id}`,
|
||||
body: `This issue is about who should get credit for [this ${type} post](https://freesewing.org/${type}/${dir}).
|
||||
|
||||
According to [user ${account.username}](https://freesewing.org.users/user?id=${account.id}) with ID ${account.id},
|
||||
${body ? 'who wrote:\n\n---\n\n' + body + '\n\n---\n\n' : 'who claimed it as their own'}.
|
||||
|
||||
To reflect this on the site, update [this markdown file](https://github.com/freesewing/freesewing/blob/develop/markdown/org/${type}/${dir}/en.md) so that the frontmatter includes this:
|
||||
|
||||
\`\`\`md
|
||||
author: ${body ? 'the FreeSewing user ID' : account.id}
|
||||
\`\`\`
|
||||
|
||||
Anyone can do this, so if you're looking to contribute, this is a great way to get started.`,
|
||||
})
|
||||
|
||||
const SuggestAuthor = ({ t, type, setLoadingStatus, backend, dir, setModal }) => {
|
||||
const { account } = useAccount()
|
||||
const [body, setBody] = useState('')
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>{t(`docs:iKnowWho${type === 'blog' ? 'Wrote' : 'Made'}This`)}</h2>
|
||||
<p>Awesome. Please let us know below who it was by providing either:</p>
|
||||
<ul className="list list-inside list-disc ml-4">
|
||||
<li>
|
||||
Their FreeSewing <b>user id</b> (best)
|
||||
</li>
|
||||
<li>
|
||||
Their FreeSewing <b>username</b> (good)
|
||||
</li>
|
||||
<li>Other info that allows us to figure out who it is</li>
|
||||
</ul>
|
||||
<MarkdownInput
|
||||
id="support-body"
|
||||
label={t('support:description')}
|
||||
update={setBody}
|
||||
current={body}
|
||||
valid={(val) => val.length > 10}
|
||||
/>
|
||||
<p>When you are done, click the button below to submit.</p>
|
||||
<p className="text-center">
|
||||
<button
|
||||
className="btn btn-primary w-full"
|
||||
onClick={() =>
|
||||
createIssue({
|
||||
account,
|
||||
backend,
|
||||
setLoadingStatus,
|
||||
setModal,
|
||||
...issueData({ type, dir, account, body }),
|
||||
})
|
||||
}
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const ClaimThisPost = ({ t, type, dir }) => {
|
||||
const { setModal } = useContext(ModalContext)
|
||||
const { account } = useAccount()
|
||||
const backend = useBackend()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
||||
return (
|
||||
<div id="maker" className="p-4 border rounded-lg shadow">
|
||||
<h3>Claim this post</h3>
|
||||
<p>
|
||||
This post has not (yet) been associated with a FreeSewing account. Please help us assign
|
||||
proper credit:
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<button
|
||||
className="btn btn-primary btn-outline"
|
||||
onClick={() =>
|
||||
setModal(
|
||||
<ModalWrapper
|
||||
flex="col"
|
||||
justify="top lg:justify-center"
|
||||
slideFrom="right"
|
||||
keepOpenOnClick
|
||||
>
|
||||
<SuggestAuthor
|
||||
{...{ t, type, setLoadingStatus, dir, account, backend, setModal }}
|
||||
/>
|
||||
</ModalWrapper>
|
||||
)
|
||||
}
|
||||
>
|
||||
{t(`docs:iKnowWho${type === 'blog' ? 'Wrote' : 'Made'}This`)}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={
|
||||
account.id
|
||||
? () =>
|
||||
createIssue({
|
||||
account,
|
||||
backend,
|
||||
setLoadingStatus,
|
||||
setModal,
|
||||
...issueData({ type, dir, account }),
|
||||
})
|
||||
: () =>
|
||||
setModal(
|
||||
<ModalWrapper flex="col" justify="top lg:justify-center" slideFrom="right">
|
||||
<ClaimAuthor {...{ t, type, setLoadingStatus, dir, backend, setModal }} />
|
||||
</ModalWrapper>
|
||||
)
|
||||
}
|
||||
>
|
||||
{t(`docs:i${type === 'blog' ? 'Wrote' : 'Made'}This`)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Maker = ({ id, type, t, dir }) =>
|
||||
makers[id] ? (
|
||||
<div id="maker" className="p-4 border rounded-lg shadow">
|
||||
<h5
|
||||
dangerouslySetInnerHTML={{
|
||||
__html:
|
||||
t(type === 'blog' ? 'docs:xWroteThis' : 'docs:xMadeThis', { x: makers[id].username }) +
|
||||
':',
|
||||
}}
|
||||
className="text-center"
|
||||
/>
|
||||
<h5 className="text-center">{t(`docs:${type === 'blog' ? 'writtenBy' : 'madeBy'}`)}</h5>
|
||||
<UserProfile user={makers[id]} />
|
||||
</div>
|
||||
) : (
|
||||
<ClaimThisPost t={t} type={type} />
|
||||
<ClaimThisPost t={t} type={type} dir={dir} />
|
||||
)
|
||||
|
||||
/** layout for a page that displays a blog, showcase or newsletter */
|
||||
|
@ -138,6 +293,7 @@ export const PostLayout = ({ mdx, frontmatter, type, dir }) => {
|
|||
id={type === 'blog' ? frontmatter.author : frontmatter.maker}
|
||||
type={type}
|
||||
t={t}
|
||||
dir={dir}
|
||||
/>
|
||||
<PrevNext />
|
||||
</article>
|
||||
|
|
|
@ -47,7 +47,7 @@ const types = [
|
|||
'other',
|
||||
]
|
||||
|
||||
const userCard = (id) =>
|
||||
export const userCard = (id) =>
|
||||
`[](https://next.freesewing.org/users/${id})`
|
||||
|
||||
const templates = {
|
||||
|
|
|
@ -23,8 +23,8 @@ credits: Credits
|
|||
contentsBy: Contents by
|
||||
translators: Translators
|
||||
title: Title
|
||||
xMadeThis: "<strong>{x}</strong> made this"
|
||||
xWroteThis: "<strong>{x}</strong> wrote this"
|
||||
writtenBy: Written by
|
||||
madeBy: Made by
|
||||
by: By
|
||||
claimThisPost: Claim this post
|
||||
iKnowWhoMadeThis: I know who made this
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue