more review work

This commit is contained in:
Belle 2024-08-23 22:39:28 +08:00
parent 59dbce2f94
commit 1bd1aac14a
7 changed files with 435 additions and 122 deletions

View file

@ -0,0 +1,17 @@
import { Box, Flex, Text } from 'theme-ui'
/** @jsxImportSource theme-ui */
const Project = ({img, name, projectName, country}) => {
return(
<Box sx={{backgroundColor: '#FFF7E5', borderRadius: '5px', display: 'flex', px: 3, py: 2, my: 2, mr: 3}}>
<Box sx={{backgroundImage: `url('${img}')`, width: '50px', height: '50px', backgroundSize: 'cover', mr: 3}}></Box>
<Box>
<Text sx={{fontWeight: 'bold'}} as="p">{projectName}</Text>
<Text as="p">{name}, {country}</Text>
</Box>
</Box>
)
}
export default Project

View file

@ -45,6 +45,7 @@
"date-fns": "^2.30.0",
"devtools-detect": "^4.0.1",
"form-data": "^4.0.0",
"framer-motion": "^11.3.29",
"fuzzysort": "^2.0.4",
"geopattern": "^1.2.3",
"globby": "^11.0.4",
@ -62,13 +63,14 @@
"openai": "^4.42.0",
"pcb-stackup": "^4.2.8",
"rc-dialog": "^9.5.2",
"react": "^17.0.2",
"react": "^18.3.1",
"react-before-after-slider-component": "^1.1.8",
"react-countdown": "^2.3.6",
"react-datepicker": "^4.24.0",
"react-dom": "^17.0.2",
"react-dom": "^18.3.1",
"react-horizontal-scrolling-menu": "^6.0.2",
"react-konami-code": "^2.3.0",
"react-leaflet": "^4.2.1",
"react-lite-youtube-embed": "^2.4.0",
"react-markdown": "^8",
"react-marquee-slider": "^1.1.5",

View file

@ -0,0 +1,34 @@
import AirtablePlus from 'airtable-plus'
const airtable = new AirtablePlus({
apiKey: process.env.AIRTABLE_API_KEY,
baseID: 'app4kCWulfB02bV8Q',
tableName: 'Users'
})
// Function to get coordinates using OpenCage API
async function getCoordinates(city, country) {
const apiKey = process.env.GEO_API_KEY
const url = `https://api.opencagedata.com/geocode/v1/json?q=${encodeURIComponent(city)},${encodeURIComponent(country)}&key=${apiKey}`
const response = await fetch(url)
const data = await response.json()
if (data.results.length > 0) {
const { lat, lng } = data.results[0].geometry
console.log(lat)
console.log(lng)
return { lat, lng }
} else {
throw new Error('Location not found')
}
}
export default async function handler(req, res) {
const { lat, lng } = await getCoordinates('New York', 'USA')
console.log(lat)
console.log(lng)
return res.status(200).json({ 'lat': lat, 'lng': lng })
}

View file

@ -0,0 +1,41 @@
import AirtablePlus from 'airtable-plus'
const airtable = new AirtablePlus({
apiKey: process.env.AIRTABLE_API_KEY,
baseID: 'app4kCWulfB02bV8Q',
tableName: 'Showcase'
})
async function getProjects() {
try {
const projects = await airtable.read({
filterByFormula: `{ScreenshotLink} != ''`,
fields: [
'Name',
'ScreenshotLink',
'Name (from User)',
'Zach - Country (from User)'
],
maxRecords: 100
})
return projects
} catch (error) {
console.error('Error fetching projects:', error)
return []
}
}
export default async function handler(req, res) {
const projects = await getProjects()
const results = projects.map(p => ({
id: p.id,
title: p.fields['Name'] || '',
imageLink: p.fields['ScreenshotLink'] || '',
user: p.fields['Name (from User)'] || '',
country: p.fields['Zach - Country (from User)'] || ''
}))
return res.status(200).json({ results })
}

View file

@ -5,25 +5,57 @@ const airtable = new AirtablePlus({
baseID: 'app4kCWulfB02bV8Q',
tableName: 'Users'
})
const locations = [
{ city: 'New York', country: 'USA' },
{ city: 'Paris', country: 'France' }
// Add more locations...
]
// Work around a node v20.0.0, v20.1.0, and v20.2.0 bug. The issue was fixed
// in v20.3.0.
// https://github.com/nodejs/node/issues/47822#issuecomment-1564708870
// Safe to remove once support for Node v20 is dropped.
if (
// !process.env.IS_BROWSER && // uncomment this line if you use a bundler that sets env.IS_BROWSER during build time
process.versions &&
// check for `node` in case we want to use this in "exotic" JS envs
process.versions.node &&
process.versions.node.match(/20\.[0-2]\.0/)
) {
require("net").setDefaultAutoSelectFamily(false);
const testData = [
{
id: 'rec1FzO4EkkGpmKrE',
country: ['Czech Republic'],
state: ['Středočeský kraj']
},
{ id: 'rec1FbmaqLe8ymTYt', country: ['United States'], state: ['MA'] },
{ id: 'rec1Dad1HKUHgMnL6', country: ['Australia'], state: ['Victoria'] },
{ id: 'rec1DUg36umkIVqpK', country: ['India'], state: ['Delhi'] },
{ id: 'rec1CmBrkirXIdHwC', country: ['Pakistan'], state: ['Sindh'] },
{ id: 'rec1BnDrIaco309Tw', country: ['United States'], state: ['Texas'] },
{
id: 'rec1B324lcw2GqIsB',
country: ['United States'],
state: ['South Carolina']
}
]
async function getRelevantUsers() {
try {
const users = await airtable.read({
filterByFormula: `{Zach - Country} != ''`
})
console.log(users)
const userLocations = users.map(user => {
return {
id: user.id,
project:
user.fields['Project'][0] || `${user.fields['Total Earned (Hours)']}`,
country: user.fields['Zach - Country'],
state: user.fields['Belle - State']
}
})
console.log(userLocations)
return userLocations
} catch (error) {
console.error('Error fetching users:', error)
return []
}
}
async function updateLocation(userId, lat, lng) {
await airtable.update(userId, {
lat: lat,
long: lng
})
}
// Function to get coordinates using OpenCage API
async function getCoordinates(city, country) {
@ -35,32 +67,23 @@ async function getCoordinates(city, country) {
if (data.results.length > 0) {
const { lat, lng } = data.results[0].geometry
console.log(lat)
console.log(lng)
return { lat, lng }
} else {
throw new Error('Location not found')
}
}
// const getUsers = async function () {
// const records = await airtable.read({
// filterByFormula: `{Total Earned (Hours)} > 3`,
// fields: [
// 'Name',
// 'Description',
// 'Slack Link',
// 'Code Link',
// 'Play Link',
// 'ScreenshotLink',
// 'color',
// 'textColor'
// ]
// })
// return records
// }
export default async function handler(req, res) {
let coordinates = getCoordinates('New York', 'USA')
return res.status(200).json({ coordinates })
// const users = await getRelevantUsers()
// users.map(user => getCoordinates(user.state, user.country))
for (const user of testData) {
const { lat, lng } = await getCoordinates(user.state, user.country)
await updateLocation(user.id, lat.toString(), lng.toString())
}
return res.status(200).json()
}

View file

@ -3,6 +3,8 @@ import { Button, Heading, Text, Box, Close } from 'theme-ui'
import Icon from '@hackclub/icons'
import { Balancer } from 'react-wrap-balancer'
import Fade from 'react-reveal/Fade'
import Project from '../../components/arcade/review/project'
import { motion } from 'framer-motion'
/** @jsxImportSource theme-ui */
@ -52,70 +54,254 @@ a {
}
`
const Review = () => {
return (
<body className="gaegu">
<div
sx={{
display: 'grid',
gridTemplateColumns: ['1fr', '2fr 1fr', '3fr 1fr']
}}
>
<div sx={{ px: 5, py: 4 }}>
<Fade>
<Text
as="h3"
variant="subtitle"
className="slackey"
sx={{ color: '#FF5C00' }}
>
Hack Club x GitHub
</Text>
</Fade>
<Fade delay={100}>
<img
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
sx={{
width: ['90vw', '60vw', '40vw'],
maxWidth: '400px',
display: 'block',
mt: 3
}}
/>
</Fade>
<Fade delay={200}>
<Balancer>
<Text
as="p"
variant="subtitle"
sx={{ color: '#09AFB4', maxWidth: '400px' }}
>
One Summer. 10,000 students. The ultimate hackathon.
</Text>
</Balancer>
</Fade>
<Fade>
<Button
as="a"
sx={{
backgroundColor: '#FF5C00',
color: '#ebebeb',
textSizeAdjust: '16px',
borderRadius: '10px'
}}
href="/arcade/showcase"
target="_blank"
rel="noopener"
>
See all projects
</Button>
</Fade>
</div>
<div id="projects"></div>
</div>
const testData = [
{
id: 'rec002eCQbUNDp6j6',
title: 'emoji-converter',
imageLink: '',
user: ['Daniel Lialin'],
country: ['Italy']
},
{
id: 'rec09g4vdIBOCh14C',
title: 'Quote-Board',
imageLink:
'https://cloud-c6ul4axwx-hack-club-bot.vercel.app/0instagram_profile_downloader.jpg',
user: ['Clay Nicholson'],
country: ['United States']
},
{
id: 'rec0EGFNQfhkMN41x',
title: 'pyanimeplanet',
imageLink: 'https://cloud-7yvacsny5-hack-club-bot.vercel.app/0image.png',
user: ['VishalRashmika'],
country: ['Sri Lanka']
},
{
id: 'rec0GOC6KT6H9IO47',
title: 'bartoszGPT',
imageLink: 'https://cloud-bra5efhoc-hack-club-bot.vercel.app/0image.png',
user: ['Briyan Dyju'],
country: ['United Arab Emirates']
},
{
id: 'rec0H5KTXjTA1G1OM',
title: 'loopholes',
imageLink: '',
user: ['Ethan Francis'],
country: ['United States']
},
{
id: 'rec0KMBho9pHZDtRq',
title: 'Traffic-Light',
imageLink:
'https://cloud-4j4xbk0el-hack-club-bot.vercel.app/0image__1_.png',
user: ['Felix Gao'],
country: ['Canada']
},
{
id: 'rec0KqA1GDMw3ZfcG',
title: 'Fumo bot',
imageLink:
'https://github.com/user-attachments/assets/98a24347-f4d4-4ae7-8404-aeb08347cfe7',
user: ['Victorio'],
country: ''
},
{
id: 'rec0MCupFjvVCeCWd',
title: 'main',
imageLink: '',
user: ['Hamza Nasher-Alneam'],
country: ['United States']
},
{
id: 'rec0XmkWtdFl3GpCv',
title: 'Python Game Engine',
imageLink: '',
user: ['Akul Saju'],
country: ['United Arab Emirates']
}
]
<style>{styled}</style>
</body>
const projectVariants = {
initial: { x: '100%', opacity: 0, y: '100%' }, // Start off-screen to the right
animate: (index) => ({
x: 0,
opacity: 1,
transition: {
duration: 0.5,
delay: index * 1, // Adjust this factor to control the delay for each project
},
}),
moveUp: {
y: '-1000%', // Move the project upward
transition: {
ease: 'linear',
duration: 30 // Control the speed of the upward movement
}
},
exit: {
opacity: 0, // Fade out or continue sliding up
transition: { duration: 0.5 }
}
}
// const containerVariants = {
// animate: {
// transition: {
// staggerChildren: 1 // Delay each project entering
// }
// }
// }
const Review = () => {
const [map, setMap] = useState(null)
useEffect(() => {
import('react-leaflet').then(
({ MapContainer, TileLayer, Marker, Popup, useMap }) => {
setMap({ MapContainer, TileLayer, Marker, Popup })
}
)
}, [])
if (!map) {
// Return null or a loader while the map components are being loaded
return <div>Loading...</div>
}
const { MapContainer, TileLayer, Marker, Popup } = map
return (
<>
<body className="gaegu">
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""
/>
<div
sx={{
display: 'grid',
gridTemplateColumns: ['1fr', '2fr 1fr', '3fr 1fr']
}}
>
<div sx={{ px: 5, py: 4 }}>
<Fade>
<Text
as="h3"
variant="subtitle"
className="slackey"
sx={{ color: '#FF5C00' }}
>
Hack Club x GitHub
</Text>
</Fade>
<Fade delay={100}>
<img
src="https://cloud-677i45opw-hack-club-bot.vercel.app/0arcade_1.png"
sx={{
width: ['90vw', '60vw', '40vw'],
maxWidth: '400px',
display: 'block',
mt: 3
}}
/>
</Fade>
<Fade delay={200}>
<Balancer>
<Text
as="p"
variant="subtitle"
sx={{ color: '#09AFB4', mb: 3 }}
>
One Summer. 10,000 students. The ultimate hackathon.
</Text>
</Balancer>
</Fade>
<MapContainer
center={[51.505, -0.09]}
zoom={2}
scrollWheelZoom={false}
sx={{ height: '400px', borderRadius: '10px' }}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={[51.505, -0.09]}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
<Fade>
<Button
as="a"
sx={{
backgroundColor: '#FF5C00',
color: '#ebebeb',
textSizeAdjust: '16px',
borderRadius: '10px',
mt: 3
}}
href="/arcade/showcase"
target="_blank"
rel="noopener"
>
See all projects
</Button>
</Fade>
</div>
<div id="projects">
<motion.div
initial="initial"
animate="animate"
exit="exit"
// variants={containerVariants}
sx={{ height: '100vh' }}
>
{testData.map((p, index) => (
<motion.div
key={p.id}
custom={index}
variants={projectVariants}
initial="initial"
animate="animate"
whileInView="moveUp"
exit="exit"
sx={{ position: 'relative', width: '100%' }} // Ensure projects stack vertically
>
<Project
name={p.user[0]}
projectName={p.title}
country={p.country[0]}
img={p.imageLink}
/>
</motion.div>
))}
</motion.div>
{/* {testData.map(p => (
<Project
name={p.user[0]}
projectName={p.title}
country={p.country[0]}
img={p.imageLink}
/>
))} */}
</div>
</div>
<style>{styled}</style>
</body>
<script
src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""
></script>
</>
)
}

View file

@ -1780,6 +1780,11 @@
classnames "^2.3.2"
rc-util "^5.24.4"
"@react-leaflet/core@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@react-leaflet/core/-/core-2.1.0.tgz#383acd31259d7c9ae8fb1b02d5e18fe613c2a13d"
integrity sha512-Qk7Pfu8BSarKGqILj4x7bCSZ1pjuAPZ+qmRwH5S7mDS91VSbVVsJSrW4qA+GPrro8t69gFYVMWb1Zc4yFmPiVg==
"@remix-run/router@1.19.1":
version "1.19.1"
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.19.1.tgz#984771bfd1de2715f42394c87fb716c1349e014f"
@ -4329,6 +4334,13 @@ formdata-node@^4.3.2:
node-domexception "1.0.0"
web-streams-polyfill "4.0.0-beta.3"
framer-motion@^11.3.29:
version "11.3.29"
resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.3.29.tgz#5ec10a350b89789d43ea7d9c6bde45b28470f196"
integrity sha512-uyDuUOeOElJEA3kbkbyoTNEf75Jih1EUg0ouLKYMlGDdt/LaJPmO+FyOGAGxM2HwKhHcAoKFNveR5A8peb7yhw==
dependencies:
tslib "^2.4.0"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@ -7475,14 +7487,13 @@ react-datepicker@^4.24.0:
react-onclickoutside "^6.13.0"
react-popper "^2.3.0"
react-dom@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
react-dom@^18.3.1:
version "18.3.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4"
integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
scheduler "^0.20.2"
scheduler "^0.23.2"
react-fast-compare@^3.0.1, react-fast-compare@^3.2.0:
version "3.2.2"
@ -7513,6 +7524,13 @@ react-konami-code@^2.3.0:
dependencies:
prop-types "^15.8.1"
react-leaflet@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/react-leaflet/-/react-leaflet-4.2.1.tgz#c300e9eccaf15cb40757552e181200aa10b94780"
integrity sha512-p9chkvhcKrWn/H/1FFeVSqLdReGwn2qmiobOQGO3BifX+/vV/39qhY8dGqbdcPh1e6jxh/QHriLXr7a4eLFK4Q==
dependencies:
"@react-leaflet/core" "^2.1.0"
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"
@ -7680,15 +7698,7 @@ react-wrap-balancer@^1.1.0:
resolved "https://registry.yarnpkg.com/react-wrap-balancer/-/react-wrap-balancer-1.1.1.tgz#527bf61dcd668c0349601ed2b5a1f0f1cde10ee7"
integrity sha512-AB+l7FPRWl6uZ28VcJ8skkwLn2+UC62bjiw8tQUrZPlEWDVnR9MG0lghyn7EyxuJSsFEpht4G+yh2WikEqQ/5Q==
react@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
react@^18.2.0:
react@^18.2.0, react@^18.3.1:
version "18.3.1"
resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891"
integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==
@ -8179,13 +8189,12 @@ safe-regex-test@^1.0.3:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
scheduler@^0.20.2:
version "0.20.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
scheduler@^0.23.2:
version "0.23.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3"
integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
scroll-into-view-if-needed@^3.1.0:
version "3.1.0"
@ -8441,6 +8450,7 @@ string-hash@1.1.3:
integrity sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
name string-width-cjs
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==