Add styling improvements to showcase form

This commit is contained in:
Max Wofford 2024-08-19 16:51:58 -04:00
parent e2f5359fab
commit 099e98d2e8
8 changed files with 90 additions and 107 deletions

View file

@ -1,26 +1,14 @@
import { Input, Label, Text, Flex, Box, Grid } from 'theme-ui' import { Input, Label, Text, Box, Grid } from 'theme-ui'
import ProjectView from './project-view' import ProjectView from './project-view'
import useForm from '../../../lib/use-form' import useForm from '../../../lib/use-form'
import Submit from '../../submit' import Submit from '../../submit'
import { useState } from 'react'
import Icon from '@hackclub/icons' import Icon from '@hackclub/icons'
// import FileInput from '../../../pages/api/arcade/showcase/projects/[projectID]/file-input'
/** @jsxImportSource theme-ui */ /** @jsxImportSource theme-ui */
const ProjectEditForm = ({ project }) => { const ProjectEditForm = ({ project }) => {
// const [previewProject, setPreviewProject] = useState(project)
const [screenshot, setScreenshot] = useState(project.screenshot)
const [newScreenshot, setNewScreenshot] = useState('')
const [video, setVideo] = useState(project.video)
const [newVideo, setNewVideo] = useState('')
function publishedChanges(e) {
console.log('published changes', e)
}
const { status, formProps, useField, data } = useForm( const { status, formProps, useField, data } = useForm(
`/api/arcade/showcase/projects/${project.id}/edit/`, `/api/arcade/showcase/projects/${project.id}/edit/`,
publishedChanges, null,
{ {
method: 'PATCH', method: 'PATCH',
initData: { ...project, recordId: project.id }, initData: { ...project, recordId: project.id },
@ -29,38 +17,6 @@ const ProjectEditForm = ({ project }) => {
} }
) )
const updateScreenshot = newMedia => {
if (screenshot.some(item => item === newMedia)) {
alert('This media already exists and cannot be added.')
return
}
setScreenshot(screenshot => [...screenshot, newMedia])
}
const deleteScreenshot = deletedMedia => {
setScreenshot(screenshot.filter(item => !item.includes(deletedMedia)))
}
const updateNewScreenshot = e => {
setNewScreenshot(e.target.value)
}
const updateVideo = newMedia => {
if (video.some(item => item === newMedia)) {
alert('This media already exists and cannot be added.')
return
}
setVideo(video => [...video, newMedia])
}
const deleteVideo = deletedMedia => {
setVideo(video.filter(item => !item.includes(deletedMedia)))
}
const updateNewVideo = e => {
setNewVideo(e.target.value)
}
const previewProject = { const previewProject = {
...data ...data
} }
@ -160,11 +116,11 @@ const ProjectEditForm = ({ project }) => {
</Label> </Label>
<Label> <Label>
<Text>Screenshot link</Text> <Text>Screenshot link (required)</Text>
<Text variant="caption"> <Text variant="caption">
Demo your work! No hosted link? Try{' '} Demo your work! Post an image in{' '}
<a href="https://hackclub.slack.com/archives/C016DEDUL87" target="_blank">#cdn</a>{' '} <a href="https://hackclub.slack.com/archives/C016DEDUL87" target="_blank">#cdn</a>{' '}
or <a href="https://tmpfiles.org/?upload" target="_blank">tmpfiles</a> on Slack and paste the link here.
</Text> </Text>
<Input <Input
{...useField('screenshot')} {...useField('screenshot')}
@ -173,11 +129,9 @@ const ProjectEditForm = ({ project }) => {
/> />
</Label> </Label>
<Label> <Label>
<Text>Video link</Text> <Text>Video demo (optional)</Text>
<Text variant="caption"> <Text variant="caption">
Add a link to your demo video! Need a host? Try{' '} Short video demoing your project. YouTube link. Suggested for hardware projects.
<a href="https://hackclub.slack.com/archives/C016DEDUL87" target="_blank">#cdn</a>{' '}
or <a href="https://tmpfiles.org/?upload" target="_blank">tmpfiles</a>
</Text> </Text>
<Input <Input
{...useField('video')} {...useField('video')}
@ -191,8 +145,6 @@ const ProjectEditForm = ({ project }) => {
<Input <Input
{...useField('color')} {...useField('color')}
type="color" type="color"
// value={color}
// onChange={handleColorChange}
sx={{ sx={{
width: '150px', width: '150px',
height: '50px', height: '50px',
@ -240,7 +192,6 @@ const ProjectEditForm = ({ project }) => {
</form> </form>
<Box <Box
sx={{ sx={{
// backgroundColor: color,
border: '2px dashed #09AFB4', border: '2px dashed #09AFB4',
borderRadius: '5px' borderRadius: '5px'
}} }}

View file

@ -4,6 +4,7 @@ import randomNotFoundImg from './random-not-found-img'
import { Button, Text } from 'theme-ui' import { Button, Text } from 'theme-ui'
import Icon from '@hackclub/icons' import Icon from '@hackclub/icons'
import ReadmeRenderer from './readme-renderer' import ReadmeRenderer from './readme-renderer'
import YoutubeRenderer from './youtube-renderer'
/** @jsxImportSource theme-ui */ /** @jsxImportSource theme-ui */
function darkenColor(hex, factor) { function darkenColor(hex, factor) {
@ -66,23 +67,21 @@ const ProjectView = ({
setInvertedColor(invertColor(textColor)) setInvertedColor(invertColor(textColor))
}, [color]) }, [color])
function convertToRawUrl(githubUrl) { // function convertToRawUrl(githubUrl) {
if (!githubUrl.includes('github.com')) { // if (!githubUrl.includes('github.com')) {
// throw new Error('Invalid GitHub URL') // // throw new Error('Invalid GitHub URL')
return '' // return ''
} // }
return githubUrl // return githubUrl
.replace('github.com', 'raw.githubusercontent.com') // .replace('github.com', 'raw.githubusercontent.com')
.replace('/blob/', '/') // .replace('/blob/', '/')
} // }
const [markdown, setMarkdown] = useState('') const [markdown, setMarkdown] = useState('')
useEffect(() => { useEffect(() => {
console.log(readMeLink)
const fetchMarkdown = async () => { const fetchMarkdown = async () => {
// const rawReadMeLink = convertToRawUrl(readMeLink)
if (readMeLink) { if (readMeLink) {
try { try {
const res = await fetch(readMeLink) const res = await fetch(readMeLink)
@ -114,6 +113,43 @@ const ProjectView = ({
> >
<h1 className="slackey">{title}</h1> <h1 className="slackey">{title}</h1>
<h3>By {user}</h3> <h3>By {user}</h3>
<div
className={styles.buttonGroup}
sx={{ width: '90%', margin: 'auto', pt: 2, pb: 2 }}
>
{playLink && (
<Button
as="a"
sx={{
backgroundColor: '#FF5C00',
color: '#ebebeb',
textSizeAdjust: '16px',
borderRadius: '10px'
}}
href={playLink}
target="_blank"
rel="noopener"
>
Play Now
</Button>
)}
<Button
as="a"
sx={{
backgroundColor: '#09AFB4',
color: '#ebebeb',
textSizeAdjust: '16px',
borderRadius: '10px'
}}
href={codeLink}
target="_blank"
rel="noopener"
>
{codeHost}
</Button>
</div>
<Text <Text
as="a" as="a"
href="/arcade/showcase/my" href="/arcade/showcase/my"
@ -176,7 +212,8 @@ const ProjectView = ({
/> />
</div> </div>
)} )}
{ video != '' && ( <YoutubeRenderer youtubeLink={video} />
{/* { video != '' && (
<div <div
sx={{ sx={{
display: 'flex', display: 'flex',
@ -189,7 +226,7 @@ const ProjectView = ({
Your browser does not support the video tag. Your browser does not support the video tag.
</video> </video>
</div> </div>
)} )} */}
</div> </div>
<p <p
@ -200,42 +237,6 @@ const ProjectView = ({
</p> </p>
</div> </div>
<div
className={styles.buttonGroup}
sx={{ width: '90%', margin: 'auto', pt: 1, pb: 5 }}
>
{playLink && (
<Button
as="a"
sx={{
backgroundColor: '#FF5C00',
color: '#ebebeb',
textSizeAdjust: '16px',
borderRadius: '10px'
}}
href={playLink}
target="_blank"
rel="noopener"
>
Play Now
</Button>
)}
<Button
as="a"
sx={{
backgroundColor: '#09AFB4',
color: '#ebebeb',
textSizeAdjust: '16px',
borderRadius: '10px'
}}
href={codeLink}
target="_blank"
rel="noopener"
>
{codeHost}
</Button>
</div>
</div> </div>
) )
} }

View file

@ -4,7 +4,11 @@ import style from './readme-renderer.module.css'
const ReadmeRenderer = ({ markdown }) => { const ReadmeRenderer = ({ markdown }) => {
return ( return (
<ReactMarkdown className={style.reactMarkDown} remarkPlugins={[remarkGfm]}> <ReactMarkdown
className={style.reactMarkDown}
remarkPlugins={[remarkGfm]}
linkTarget={'_blank'}
>
{markdown} {markdown}
</ReactMarkdown> </ReactMarkdown>
) )

View file

@ -1,3 +1,6 @@
.reactMarkDown {
text-align: left;
}
.reactMarkDown img { .reactMarkDown img {
max-width: 100%; max-width: 100%;
} }

View file

@ -0,0 +1,18 @@
import LiteYouTubeEmbed from 'react-lite-youtube-embed';
import 'react-lite-youtube-embed/dist/LiteYouTubeEmbed.css'
const YoutubeRenderer = ({ youtubeLink }) => {
if (!youtubeLink) return null
const youtubeID = youtubeLink.split('v=')[1]
if (!youtubeID) return <p>Invalid YouTube link: "{youtubeLink}"</p>
return (
<LiteYouTubeEmbed
id={youtubeID}
adNetwork={false}
noCookie={true}
/>
)
}
export default YoutubeRenderer

View file

@ -68,6 +68,7 @@
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-horizontal-scrolling-menu": "^6.0.2", "react-horizontal-scrolling-menu": "^6.0.2",
"react-konami-code": "^2.3.0", "react-konami-code": "^2.3.0",
"react-lite-youtube-embed": "^2.4.0",
"react-markdown": "^8", "react-markdown": "^8",
"react-marquee-slider": "^1.1.5", "react-marquee-slider": "^1.1.5",
"react-masonry-css": "^1.0.16", "react-masonry-css": "^1.0.16",

View file

@ -19,7 +19,7 @@ export default async function handler(req, res) {
updatedFields['Code Link'] = body.codeLink updatedFields['Code Link'] = body.codeLink
updatedFields['Play Link'] = body.playLink updatedFields['Play Link'] = body.playLink
updatedFields['Screenshot'] = [body.screenshot].map(i => ({ url: i })) updatedFields['Screenshot'] = [body.screenshot].map(i => ({ url: i }))
updatedFields['Video'] = [body.video].map(i => ({ url: i })) // updatedFields['Video'] = [body.video].map(i => ({ url: i }))
updatedFields['color'] = body.color updatedFields['color'] = body.color
updatedFields['textColor'] = body.textColor updatedFields['textColor'] = body.textColor
updatedFields['ScreenshotLink'] = body.screenshot updatedFields['ScreenshotLink'] = body.screenshot

View file

@ -7478,6 +7478,11 @@ react-konami-code@^2.3.0:
dependencies: dependencies:
prop-types "^15.8.1" prop-types "^15.8.1"
react-lite-youtube-embed@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/react-lite-youtube-embed/-/react-lite-youtube-embed-2.4.0.tgz#1f56a12be1061d50431444d52d836bd09a1283a2"
integrity sha512-Xo6cM1zPlROvvM97JkqQIoXstlQDaC4+DawmM7BB7Hh1cXrkBHEGq1iJlQxBTUWAUklmpcC7ph7qg7CztXtABQ==
react-markdown@^8: react-markdown@^8:
version "8.0.7" version "8.0.7"
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.7.tgz#c8dbd1b9ba5f1c5e7e5f2a44de465a3caafdf89b" resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.7.tgz#c8dbd1b9ba5f1c5e7e5f2a44de465a3caafdf89b"