mirror of
https://github.com/System-End/site.git
synced 2026-04-19 22:05:11 +00:00
Merge pull request #2 from hackclub/add-project-loading
Add project loading
This commit is contained in:
commit
d5a9cafc75
5 changed files with 135 additions and 7 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { Box, Card, Heading, Text } from 'theme-ui'
|
||||
import { Box, Card, Heading, Link, Text } from 'theme-ui'
|
||||
import styles from './cohort-card.module.css'
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
.card{
|
||||
flex: 1;
|
||||
break-inside: avoid;
|
||||
background-color: rgb(255, 255, 255);
|
||||
background-clip: padding-box;
|
||||
padding: 1.5rem 1.5rem 1rem 1.5rem;
|
||||
cursor: pointer;
|
||||
height: fit-content;
|
||||
position: relative;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
|
|
|
|||
37
pages/api/arcade/showcase/login/test.js
Normal file
37
pages/api/arcade/showcase/login/test.js
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import AirtablePlus from "airtable-plus"
|
||||
|
||||
export const testAuth = async (authToken) => {
|
||||
const airtable = new AirtablePlus({
|
||||
apiKey: process.env.AIRTABLE_API_KEY,
|
||||
baseID: 'app4kCWulfB02bV8Q',
|
||||
tableName: "Users"
|
||||
})
|
||||
|
||||
const safeAuthToken = authToken.replace(/[^a-zA-Z0-9-]/g, '')
|
||||
|
||||
const results = await airtable.read({
|
||||
filterByFormula: `AND(NOT({Auth Token} = BLANK()), {Auth Token} = '${safeAuthToken}')`,
|
||||
maxRecords: 1
|
||||
})
|
||||
|
||||
return results[0]
|
||||
}
|
||||
|
||||
export const ensureAuthed = async (req) => {
|
||||
const authToken = req.headers['authorization']?.replace('Bearer ', '')
|
||||
const user = await testAuth(authToken || '')
|
||||
if (!user) {
|
||||
return { error: "User not found" }
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
export default async function handler(req, res) {
|
||||
// example of how to ensure a request is authenticated
|
||||
const result = await ensureAuthed(req)
|
||||
if (result.error) {
|
||||
return res.status(401).json(result)
|
||||
} else {
|
||||
return res.status(200).json(result)
|
||||
}
|
||||
}
|
||||
32
pages/api/arcade/showcase/projects/my.js
Normal file
32
pages/api/arcade/showcase/projects/my.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import AirtablePlus from "airtable-plus";
|
||||
import { ensureAuthed } from "../login/test";
|
||||
|
||||
export default async function handler(req, res) {
|
||||
const user = await ensureAuthed(req)
|
||||
if (user.error) {
|
||||
return res.status(401).json(user)
|
||||
}
|
||||
|
||||
const airtable = new AirtablePlus({
|
||||
apiKey: process.env.AIRTABLE_API_KEY,
|
||||
baseID: 'app4kCWulfB02bV8Q',
|
||||
tableName: "Showcase"
|
||||
})
|
||||
|
||||
const projects = await airtable.read({
|
||||
filterByFormula: `{User} = '${user.fields['Name']}'`
|
||||
})
|
||||
|
||||
const results = projects.map(p => ({
|
||||
id: p.id,
|
||||
title: p.fields['Name'] || '',
|
||||
desc: p.fields['Description'] || '',
|
||||
slackLink: p.fields['Slack Link'] || '',
|
||||
codeLink: p.fields['Code Link'] || '',
|
||||
slackLink: p.fields['Slack Link'] || '',
|
||||
playLink: p.fields['Play Link'] || '',
|
||||
images: p.fields['Screenshot'].map(i => i.url) || [],
|
||||
githubProf: p.fields['Github Profile'] || ''
|
||||
}))
|
||||
return res.status(200).json({ projects: results })
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react'
|
||||
import { useEffect, useState } from 'react'
|
||||
import CohortCard from '../../../components/arcade/showcase/cohort-card'
|
||||
import ProjectView from '../../../components/arcade/showcase/project-view'
|
||||
import Nav from '../../../components/Nav'
|
||||
|
|
@ -10,7 +10,43 @@ import SlideDown from '../../../components/slide-down'
|
|||
import styles from '../../../components/arcade/showcase/my.module.css'
|
||||
|
||||
|
||||
const ProjectGallery = ({ projects }) => (
|
||||
<div className={styles.gallery}>
|
||||
{projects.map(project => (
|
||||
<CohortCard project={project} key={project.id} />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
const Loading = () => (<div>Loading...</div>)
|
||||
|
||||
const Error = (e) => (<div>There was an error loading your projects: {e}</div>)
|
||||
|
||||
const my = () => {
|
||||
const [projects, setProjects] = useState([])
|
||||
const [status, setStatus] = useState('loading')
|
||||
const [errorMsg, setError] = useState(null)
|
||||
useEffect(async () => {
|
||||
const token = window.localStorage.getItem('arcade.authToken')
|
||||
const response = await fetch('/api/arcade/showcase/projects/my', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
}).catch(e => {
|
||||
console.error(e)
|
||||
setStatus('error')
|
||||
setError(e)
|
||||
})
|
||||
const data = await response.json()
|
||||
if (data.error) {
|
||||
setStatus('error')
|
||||
return
|
||||
} else {
|
||||
setProjects(data.projects)
|
||||
setStatus('success')
|
||||
}
|
||||
}, [])
|
||||
return (
|
||||
<section>
|
||||
<Nav />
|
||||
|
|
@ -35,6 +71,34 @@ const my = () => {
|
|||
zIndex: 1
|
||||
}}
|
||||
>
|
||||
My Ships
|
||||
|
||||
|
||||
|
||||
</Text>
|
||||
<br />
|
||||
<Button
|
||||
as="a"
|
||||
variant="ctaLg"
|
||||
href="https://apply.hackclub.com"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
Add a Project
|
||||
</Button>
|
||||
</Heading>
|
||||
</SlideDown>
|
||||
{
|
||||
status == 'loading' && <Loading />
|
||||
}
|
||||
|
||||
{
|
||||
status == 'error' && <Error error={errorMsg} />
|
||||
}
|
||||
|
||||
{
|
||||
status == 'success' && <ProjectGallery projects={projects} />
|
||||
}
|
||||
<Text
|
||||
as="span"
|
||||
sx={{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue