images + videos

This commit is contained in:
Belle 2024-08-18 18:19:17 +08:00
parent 595a256bf5
commit 21c9449075
5 changed files with 217 additions and 37 deletions

View file

@ -5,12 +5,19 @@ import Submit from '../../submit'
import { useState } from 'react'
import Icon from '@hackclub/icons'
import FileInput from '../../../pages/api/arcade/showcase/projects/[projectID]/file-input'
/** @jsxImportSource theme-ui */
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)
console.log(color)
}
const { status, formProps, useField, data } = useForm(
@ -23,11 +30,37 @@ const ProjectEditForm = ({ project }) => {
}
)
// const [color, setColor] = useState(project.color);
const updateScreenshot = newMedia => {
if (screenshot.some(item => item === newMedia)) {
alert('This media already exists and cannot be added.')
return
}
setScreenshot(screenshot => [...screenshot, newMedia])
}
// const handleColorChange = (e) => {
// setColor(e.target.value);
// };
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)
}
return (
<Box
@ -48,15 +81,15 @@ const ProjectEditForm = ({ project }) => {
display: 'flex',
width: '100%',
mb: 2,
color: '#333',
color: '#333'
}}
>
<Icon glyph="edit" />
Editing {project.title} details
</Text>
<Text
as="a"
href="/arcade/showcase/my"
as="a"
href="/arcade/showcase/my"
sx={{
border: '2px dashed #333',
borderRadius: '5px',
@ -122,7 +155,7 @@ const ProjectEditForm = ({ project }) => {
sx={{ border: '1px dashed', borderColor: '#09AFB4', mb: 2 }}
/>
</Label>
<Label>
{/* <Label>
<Text>Screenshot</Text>
<Input
{...useField('screenshot')}
@ -135,8 +168,135 @@ const ProjectEditForm = ({ project }) => {
{...useField('video')}
sx={{ border: '1px dashed', borderColor: '#09AFB4', mb: 2 }}
/>
</Label> */}
<Input {...useField('authToken')} type="hidden" />
{/* <FileInput /> */}
<Label>
<Text>Add screenshots</Text>
<Flex sx={{ alignItems: 'center', mb: 2 }}>
<Input
type="url"
value={newScreenshot}
onChange={updateNewScreenshot}
sx={{ border: '1px dashed', borderColor: '#09AFB4' }}
/>
<Icon
onClick={() => updateScreenshot(newScreenshot)}
glyph="plus"
sx={{
transitionDuration: '0.3s',
cursor: 'pointer',
height: '37px',
width: '37px',
color: '#09AFB4',
ml: 2,
'&:hover': {
transform: 'scale(1.05)'
}
}}
/>
</Flex>
</Label>
{screenshot.map(image => (
<div
sx={{
display: 'grid',
position: 'relative',
mb: 3,
alignItems: 'center',
wordBreak: 'break-all',
gridTemplateColumns: '8fr 1fr'
}}
>
{image}
<Icon
onClick={() => deleteScreenshot(image)}
glyph="minus"
sx={{
transitionDuration: '0.3s',
height: '30px',
width: '30px',
color: '#DE4E2B',
cursor: 'pointer',
'&:hover': {
transform: 'scale(1.05)'
}
}}
/>
</div>
))}
<Input
{...useField('screenshot')}
value={JSON.stringify(screenshot)}
type="hidden"
/>
<Label>
<Text>Add videos</Text>
<Flex sx={{ alignItems: 'center', mb: 2 }}>
<Input
type="url"
value={newVideo}
onChange={updateNewVideo}
sx={{ border: '1px dashed', borderColor: '#09AFB4' }}
/>
<Icon
onClick={() => updateVideo(newVideo)}
glyph="plus"
sx={{
transitionDuration: '0.3s',
cursor: 'pointer',
height: '37px',
width: '37px',
color: '#09AFB4',
ml: 2,
'&:hover': {
transform: 'scale(1.05)'
}
}}
/>
</Flex>
</Label>
{video.map(image => (
<div
sx={{
display: 'grid',
position: 'relative',
mb: 3,
alignItems: 'center',
wordBreak: 'break-all',
gridTemplateColumns: '8fr 1fr'
}}
>
{image}
<Icon
onClick={() => deleteVideo(image)}
glyph="minus"
sx={{
transitionDuration: '0.3s',
height: '30px',
width: '30px',
color: '#DE4E2B',
cursor: 'pointer',
float: 'right',
'&:hover': {
transform: 'scale(1.05)'
}
}}
/>
</div>
))}
<Input
{...useField('video')}
value={JSON.stringify(video)}
type="hidden"
/>
<Label>
<Text>Background Color</Text>
<Input
@ -146,14 +306,15 @@ const ProjectEditForm = ({ project }) => {
// onChange={handleColorChange}
sx={{
width: '150px',
height: '50px',
padding: '0',
backgroundColor: 'transparent',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
zIndex: 1,
position: 'relative',}}
height: '50px',
padding: '0',
backgroundColor: 'transparent',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
zIndex: 1,
position: 'relative'
}}
/>
</Label>
<Label>
@ -163,19 +324,18 @@ const ProjectEditForm = ({ project }) => {
type="color"
sx={{
width: '150px',
height: '50px',
padding: '0',
backgroundColor: 'transparent',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
zIndex: 1,
position: 'relative',}}
height: '50px',
padding: '0',
backgroundColor: 'transparent',
border: 'none',
borderRadius: '8px',
cursor: 'pointer',
zIndex: 1,
position: 'relative'
}}
/>
</Label>
<Input {...useField('authToken')} type="hidden" />
<FileInput />
<Submit
status={status}
labels={{

View file

@ -45,6 +45,8 @@ const ProjectView = ({
codeLink = '',
color = '',
textColor = '',
screenshot = [],
video = [],
...props
}) => {
const [darkColor, setDarkColor ] = useState("#000000")
@ -110,10 +112,11 @@ const ProjectView = ({
sx={{
display: 'grid',
flexWrap: 'wrap',
gridTemplateColumns: images > 1 ? ['1fr', '1fr 1fr', '1fr 1fr 1fr'] : '1fr'
gridTemplateColumns: images > 1 ? ['1fr', '1fr 1fr', '1fr 1fr 1fr'] : '1fr',
gap: '10px'
}}
>
{imagesList.map((image, index) => (
{screenshot.map((image, index) => (
<div
key={index}
sx={{
@ -129,6 +132,14 @@ const ProjectView = ({
/>
</div>
))}
{video.map((link, index) => (
<div key={index} style={{ marginBottom: '20px' }}>
<video width="600" controls>
<source src={link} type="video/mp4" />
Your browser does not support the video tag.
</video>
</div>
))}
</div>

View file

@ -1,5 +1,6 @@
import AirtablePlus from "airtable-plus";
import { ensureAuthed } from "../../login/test";
import { update } from "lodash";
export default async function handler(req, res) {
const user = await ensureAuthed(req)
@ -22,6 +23,8 @@ export default async function handler(req, res) {
updatedFields['Screenshot'] = body.images
updatedFields['color'] = body.color
updatedFields['textColor'] = body.textColor
updatedFields['ScreenshotLinks'] = body.screenshot
updatedFields['VideoLinks'] = body.video
console.log(body.color)
@ -47,7 +50,10 @@ export default async function handler(req, res) {
user: user.fields['Name'],
githubProf: project.fields['Github Profile'] || '',
color: project.fields['color'] || '',
textColor: project.fields['textColor'] || ''
textColor: project.fields['textColor'] || '',
screenshot: JSON.parse(p.fields['ScreenshotLinks']) || [],
video: JSON.parse(p.fields['VideoLinks']) || [],
}
return res.status(200).json({ project: results })

View file

@ -1,7 +1,6 @@
import AirtablePlus from "airtable-plus";
import { ensureAuthed } from "../../login/test";
import { closestTo } from "date-fns";
import AirtablePlus from 'airtable-plus'
import { ensureAuthed } from '../../login/test'
import { closestTo } from 'date-fns'
export default async function handler(req, res) {
const user = await ensureAuthed(req)
@ -12,7 +11,7 @@ export default async function handler(req, res) {
const airtable = new AirtablePlus({
apiKey: process.env.AIRTABLE_API_KEY,
baseID: 'app4kCWulfB02bV8Q',
tableName: "Showcase"
tableName: 'Showcase'
})
const { projectID } = req.query
@ -34,7 +33,9 @@ export default async function handler(req, res) {
githubProf: p.fields['Github Profile'] || '',
user: user.fields['Name'],
color: p.fields['color'] || '',
textColor: p.fields['textColor'] || ''
textColor: p.fields['textColor'] || '',
screenshot: JSON.parse(p.fields['ScreenshotLinks']) || [],
video: JSON.parse(p.fields['VideoLinks']) || []
}))
return res.status(200).json({ project: results[0] })
}
}

View file

@ -105,6 +105,8 @@ const ProjectShowPage = ({ projectID }) => {
user={project.user}
color={project.color}
textColor={project.textColor}
screenshot={project.screenshot}
video={project.video}
/>
{/* } */}
</div>