mirror of
https://github.com/System-End/site.git
synced 2026-04-19 20:55:09 +00:00
Add styling improvements to showcase form
This commit is contained in:
parent
e2f5359fab
commit
099e98d2e8
8 changed files with 90 additions and 107 deletions
|
|
@ -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'
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
.reactMarkDown {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
.reactMarkDown img {
|
.reactMarkDown img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
18
components/arcade/showcase/youtube-renderer.js
Normal file
18
components/arcade/showcase/youtube-renderer.js
Normal 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
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue