diff --git a/components/arcade/showcase/cohort-card.js b/components/arcade/showcase/cohort-card.js index 15643f42..41aef356 100644 --- a/components/arcade/showcase/cohort-card.js +++ b/components/arcade/showcase/cohort-card.js @@ -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' diff --git a/components/arcade/showcase/cohort-card.module.css b/components/arcade/showcase/cohort-card.module.css index 26545cc5..41b6c04d 100644 --- a/components/arcade/showcase/cohort-card.module.css +++ b/components/arcade/showcase/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; diff --git a/pages/api/arcade/showcase/login/test.js b/pages/api/arcade/showcase/login/test.js new file mode 100644 index 00000000..abc342bb --- /dev/null +++ b/pages/api/arcade/showcase/login/test.js @@ -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) + } +} \ No newline at end of file diff --git a/pages/api/arcade/showcase/projects/my.js b/pages/api/arcade/showcase/projects/my.js new file mode 100644 index 00000000..161e9dad --- /dev/null +++ b/pages/api/arcade/showcase/projects/my.js @@ -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 }) +} \ No newline at end of file diff --git a/pages/arcade/showcase/my.js b/pages/arcade/showcase/my.js index b168d1ef..a4082ffa 100644 --- a/pages/arcade/showcase/my.js +++ b/pages/arcade/showcase/my.js @@ -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 }) => ( +
+ {projects.map(project => ( + + ))} +
+) + +const Loading = () => (
Loading...
) + +const Error = (e) => (
There was an error loading your projects: {e}
) + 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 (