Merge pull request #1201 from aaronw-dev/main

responsive teehee
This commit is contained in:
Max Wofford 2024-05-13 21:09:40 +00:00 committed by GitHub
commit 5b248712b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 692 additions and 253 deletions

View file

@ -17,6 +17,15 @@
"img": "https://cloud-eg2ex8nol-hack-club-bot.vercel.app/0favicon-on-light-removebg-preview.png",
"link": "https://cpu.land"
},
{
"background": "#e5e6da",
"titleColor": "black",
"descriptionColor": "black",
"title": "The Bin",
"description": "A free electronics starter kit for high schoolers, shipped to your door.",
"img": "https://cloud-e3pxf7bt9-hack-club-bot.vercel.app/0ezgif.com-resize.gif",
"link": "https://hackclub.com/bin"
},
{
"background": "#000",
"titleColor": "green",

View file

@ -274,6 +274,18 @@ const nextConfig = {
{
source: '/how-to-organize-a-hackathon/style.css',
destination: 'https://expandables.hackclub.dev/style.css'
},
{
source: '/bin/',
destination: '/bin/index.html'
},
{
source: '/bin/:path*',
destination: '/bin/:path*'
},
{
source: '/bin/selector/',
destination: '/bin/selector/index.html'
}
]
},

View file

@ -1,4 +1,18 @@
import OpenAI from 'openai';
import AirtablePlus from "airtable-plus"
const saveProject = async (parts = [], idea) => {
const airtable = new AirtablePlus({
apiKey: process.env.AIRTABLE_API_KEY,
baseID: 'appKjALSnOoA0EmPk',
tableName: 'Cached Ideas'
})
const cacheName = parts.sort().join(',')
airtable.create({
"Name": cacheName,
"Recommendation": idea
})
}
const sample = (arr) => arr[Math.floor(Math.random() * arr.length)]
@ -47,6 +61,7 @@ export default async function handler(req, res) {
})
const recommendation = await generateProjectIdea(parts)
await saveProject(parts, recommendation)
res.send({ recommendation, parts })
}

View file

@ -1,6 +1,36 @@
import AirtablePlus from "airtable-plus"
const createProject = async (partsList=[]) => {
const findOrCreateProject = async (partsList = []) => {
const airtable = new AirtablePlus({
apiKey: process.env.AIRTABLE_API_KEY,
baseID: 'appKjALSnOoA0EmPk',
tableName: 'Cached Projects'
})
const cacheName = partsList.sort().join(',')
const existingProject = await airtable.read({
filterByFormula: `{Name}="${cacheName}"`,
maxRecords: 1
})
if (existingProject.length > 0) {
return existingProject[0].fields['Share Link']
} else {
const shareLink = await createProject(partsList)
if (shareLink) {
await airtable.create({
"Name": cacheName,
"Share Link": shareLink
})
return shareLink
} else {
return null
}
}
}
const createProject = async (partsList = []) => {
const airtable = new AirtablePlus({
apiKey: process.env.AIRTABLE_API_KEY,
baseID: 'appKjALSnOoA0EmPk',
@ -11,7 +41,7 @@ const createProject = async (partsList=[]) => {
const PADDING = 30;
const MAX_WIDTH = 320; // big question mark on this one
const ROW_HEIGHT = 215; // close enough for jazz, keypad is too big for this but ¯\_(ツ)_/¯
const parts = [
{ "type": "board-pi-pico-w", "id": "pico", "top": 0, "left": 0, "attrs": {} }
]
@ -24,7 +54,7 @@ const createProject = async (partsList=[]) => {
})
return airPart[0].fields['Wokwi Name'].split(',').forEach((name, i) => {
const width = airPart[0].fields['Wokwi X-Offset'];
if((x + width + PADDING) > MAX_WIDTH) {
if ((x + width + PADDING) > MAX_WIDTH) {
x = 0;
y += ROW_HEIGHT;
}
@ -49,20 +79,23 @@ Now that you've thrown some parts into The Bin, it's time to turn that trash int
Wire up your parts and write some code to make them work together.
If you'd like a tutorial, check out this short explainer on making a blinking LED:
If you'd like a tutorial, check out this short explainer on making a blinking
LED:
https://github.com/hackclub/hackclub/pull/1860/files?short_path=0494126
You can get help by chatting with other high schoolers on the Hack Club Slack in the #electronics channel:
You can get help by chatting with other high schoolers on the Hack Club Slack in
the #electronics channel:
👉 https://hackclub.com/slack 👈
Once you're ready build your design IRL, click the "Share" button and submit your design:
https://forms.hackclub.com/t/adnj7zfgTyus
Once you're ready build your design IRL, click the "Share" button and submit
your design:
https://hack.club/bin-submit
`
},
{
name: "sketch.ino",
content: `// Now turn this trash into treasure!
// Want some help? You can chat with us on the Hack Club Slack in the #electronics channel
void setup() {
// put your setup code here, to run once:
Serial1.begin(115200);
@ -107,7 +140,7 @@ export default async function handler(req, res) {
if (req.method === 'POST') {
const { parts } = req.body
const shareLink = await createProject(parts)
const shareLink = await findOrCreateProject(parts)
if (shareLink) {
res.status(200).json({ shareLink })
} else {

View file

@ -12,17 +12,17 @@ import {
} from 'theme-ui'
import Head from 'next/head'
import Meta from '@hackclub/meta'
import Nav from '../components/nav'
import Nav from '../../components/nav'
import { useEffect, useState, useRef } from 'react'
import Footer from '../components/footer'
import Footer from '../../components/footer'
import { keyframes } from '@emotion/react'
import RsvpForm from '../components/bin/rsvp-form'
import RsvpForm from '../../components/bin/rsvp-form'
import { Fade } from 'react-reveal'
import ForceTheme from '../components/force-theme'
import ForceTheme from '../../components/force-theme'
import JSConfetti from 'js-confetti'
import Sparkles from '../components/sparkles'
import Sparkles from '../../components/sparkles'
import Icon from "@hackclub/icons"
import Announcement from '../components/announcement'
import Announcement from '../../components/announcement'
import { TypeAnimation } from 'react-type-animation'
const RsvpCount = () => {

View file

@ -204,9 +204,9 @@ function Page({
gradient="linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.45))"
/>
<Announcement
copy="Hop OnBoard and create your first PCB"
caption="Join 1,000 others to create your first circuit board."
href="https://hackclub.com/onboard/"
copy="Get a free hardware starter kit!"
caption="Join 100s of other high schoolers to create your first electronics project."
href="/bin/"
iconLeft="idea"
/>
<Box

View file

@ -0,0 +1,3 @@
<svg width="41" height="45" viewBox="0 0 41 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.8614 16.1009H0V29.3119H17.8614V45L40.5 23L17.8614 0.5V16.1009Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 195 B

View file

@ -1,4 +1,4 @@
<svg width="94" height="93" viewBox="0 0 94 93" fill="none" xmlns="http://www.w3.org/2000/svg">
<ellipse cx="47" cy="46.5" rx="46.5" ry="47" transform="rotate(90 47 46.5)" fill="#9FEEB5"/>
<path d="M70 39.5932L62.95 32L46.5 47.1864L30.05 32L23 39.5932L46.5 60L70 39.5932Z" fill="#1E1E1E"/>
<?xml version="1.0" encoding="UTF-8"?>
<svg width="47" height="28" fill="none" version="1.1" viewBox="0 0 47 28" xmlns="http://www.w3.org/2000/svg">
<path d="M 47,7.5932 39.95,0 23.5,15.1864 7.05,0 0,7.5932 23.5,28 Z" fill="#fff"/>
</svg>

Before

Width:  |  Height:  |  Size: 297 B

After

Width:  |  Height:  |  Size: 240 B

View file

@ -5,9 +5,9 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The Bin</title>
<link rel="stylesheet" href="../style/common.css">
<link rel="stylesheet" href="./style.css">
<link rel="stylesheet" href="../style/footer.css">
<link rel="stylesheet" href="./style/common.css">
<link rel="stylesheet" href="./landing-new/style.css">
<link rel="stylesheet" href="./style/footer.css">
<link rel="icon" type="image/png" sizes="32x32" href="https://assets.hackclub.com/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="https://assets.hackclub.com/favicons/favicon-16x16.png">
<script src="https://awdev.codes/utils/smoothScroll.js"></script>
@ -15,46 +15,89 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.4/howler.core.min.js"
integrity="sha512-d00Brs/+XQUUaO0Y9Uo8Vw63o7kS6ZcLM2P++17kALrI8oihAfL4pl1jQObeRBgv06j7xG0GHOhudAW0BdrycA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="./script.js"></script>
<script src="./landing-new/script.js"></script>
<script src="./data-loading.js"></script>
<script defer data-domain="hackclub.com" src="https://plausible.io/js/script.js"></script>
<script>
window['_fs_host'] = 'fullstory.com';
window['_fs_script'] = 'edge.fullstory.com/s/fs.js';
window['_fs_org'] = 'ARN0J';
window['_fs_namespace'] = 'FS';
!function(m,n,e,t,l,o,g,y){var s,f,a=function(h){
return!(h in m)||(m.console&&m.console.log&&m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].'),!1)}(e)
;function p(b){var h,d=[];function j(){h&&(d.forEach((function(b){var d;try{d=b[h[0]]&&b[h[0]](h[1])}catch(h){return void(b[3]&&b[3](h))}
d&&d.then?d.then(b[2],b[3]):b[2]&&b[2](d)})),d.length=0)}function r(b){return function(d){h||(h=[b,d],j())}}return b(r(0),r(1)),{
then:function(b,h){return p((function(r,i){d.push([b,h,r,i]),j()}))}}}a&&(g=m[e]=function(){var b=function(b,d,j,r){function i(i,c){
h(b,d,j,i,c,r)}r=r||2;var c,u=/Async$/;return u.test(b)?(b=b.replace(u,""),"function"==typeof Promise?new Promise(i):p(i)):h(b,d,j,c,c,r)}
;function h(h,d,j,r,i,c){return b._api?b._api(h,d,j,r,i,c):(b.q&&b.q.push([h,d,j,r,i,c]),null)}return b.q=[],b}(),y=function(b){function h(h){
"function"==typeof h[4]&&h[4](new Error(b))}var d=g.q;if(d){for(var j=0;j<d.length;j++)h(d[j]);d.length=0,d.push=h}},function(){
(o=n.createElement(t)).async=!0,o.crossOrigin="anonymous",o.src="https://"+l,o.onerror=function(){y("Error loading "+l)}
;var b=n.getElementsByTagName(t)[0];b&&b.parentNode?b.parentNode.insertBefore(o,b):n.head.appendChild(o)}(),function(){function b(){}
function h(b,h,d){g(b,h,d,1)}function d(b,d,j){h("setProperties",{type:b,properties:d},j)}function j(b,h){d("user",b,h)}function r(b,h,d){j({
uid:b},d),h&&j(h,d)}g.identify=r,g.setUserVars=j,g.identifyAccount=b,g.clearUserCookie=b,g.setVars=d,g.event=function(b,d,j){h("trackEvent",{
name:b,properties:d},j)},g.anonymize=function(){r(!1)},g.shutdown=function(){h("shutdown")},g.restart=function(){h("restart")},
g.log=function(b,d){h("log",{level:b,msg:d})},g.consent=function(b){h("setIdentity",{consent:!arguments.length||b})}}(),s="fetch",
f="XMLHttpRequest",g._w={},g._w[f]=m[f],g._w[s]=m[s],m[s]&&(m[s]=function(){return g._w[s].apply(this,arguments)}),g._v="2.0.0")
}(window,document,window._fs_namespace,"script",window._fs_script);
</script>
</head>
<body>
<img src="https://awdev.codes/images/ww.gif" style="display:none;">
<section class="landing-section section">
<div class="landing-header">
<img src="../icons/icon.svg" class="landing-logo">
<img src="./icons/icon.svg" class="landing-logo">
<span class="landing-tagline">The beginner hardware kit designed just for you</span>
<span class="landing-tagline">Free for high schoolers</span>
<img src="../parts/pico.png" class="landing-main-image">
<img src="./parts/pico.png" class="landing-main-image">
</div>
<img id="floaty" src="../parts/relay.png" style="top: 20%; left: 7%;">
<img id="floaty" src="../parts/mic.png" style="top: 80%; left: 20%;animation-delay: -2500ms;">
<img id="floaty-left" src="../parts/humidity.png"
<img id="floaty" src="./parts/relay.png" style="top: 20%; left: 7%;">
<img id="floaty" src="./parts/mic.png" style="top: 80%; left: 20%;animation-delay: -2500ms;">
<img id="floaty-left" src="./parts/humidity.png"
style="top: 80%; right:10%;animation-delay: -1000ms;"><!---animation-delay: -2s;-->
<img id="floaty-left" src="../parts/laser.png"
<img id="floaty-left" src="./parts/led.png"
style="top: 30%; right:10%;animation-delay: -1500ms;"><!---animation-delay: -2s;-->
<img src="../icons/scrolldown.svg" class="scroll-prompt" onclick="smoothScroll('.timeline')">
<img src="../images/idea.png" class="huh floaty" style="animation-delay: -3000ms;">
<div class="scroll-prompt" onclick="smoothScroll('.timeline')">
<img src="./icons/scrolldown.svg">
</div>
<img src="./images/idea.png" class="huh floaty" style="animation-delay: -3000ms;">
</section>
<section class="section container timeline">
<section class="section container timeline" style="max-width:71em;">
<!-- timeline of project -->
<h1>What will you make<br/><em>before summer break?</em></h1>
<h1 class="timeline-header">
What will you make
</h1>
<h2 class="timeline-subheader">
before summer break?
</h2>
<div class="timeline-list">
<div class="timeline-item" onclick="smoothScroll('.gambling-section')" style="cursor: pointer;">
<em class="muted">Right now...</em>
<h2>Rummage for parts</h2>
<p>Dig up some parts from our part picker or choose your own! Don't have an idea yet? Ask the raccoon for some inspiration!</p>
<div class="timeline-item hoverable greenbutton" onclick="smoothScroll('.gambling-section')"
style="cursor: pointer;">
<div class="timeline-info">
<em class="muted">Right now...</em>
<h2>Rummage for parts</h2>
<p>Dig up some parts from our part picker or choose your own! Don't have an idea yet? Ask the
raccoon
for some inspiration!</p>
</div>
</div>
<div class="timeline-item">
<em class="muted">over 3-4 days...</em>
<h2>Design your project</h2>
<p>Build a project in the online editor and program it! Get support from <a href="https://hackclub.com/slack" target="_blank">other high schoolers in an online community</a>.</p>
<div class="timeline-item hoverable bluebutton">
<div class="timeline-info">
<em class="muted">over 3-4 days...</em>
<h2>Design your project</h2>
<p>Build a project in the online editor and program it! Get support from <a
href="https://hackclub.com/slack" target="_blank">other high schoolers in an online
community</a>.</p>
</div>
</div>
<div class="timeline-item">
<em class="muted">in 1 week...</em>
<h2>Get it IRL</h2>
<p><a href="https://hack.club/bin-submit" target="_blank">Submit your design to the gallery</a> of projects so other high schoolers can learn from your project.</p>
<div class="timeline-item hoverable redbutton">
<div class="timeline-info">
<em class="muted">in 1 week...</em>
<h2>Get it IRL</h2>
<p><a href="https://hack.club/bin-submit" target="_blank">Submit your design to the gallery</a> of
projects so other high schoolers can learn from your project.</p>
</div>
</div>
</div>
</section>
@ -62,93 +105,141 @@
<div class="gambling-header">
<div class="gambling-header-text">
<h1 class="gambling-title">Rummage!</h1>
<h2 class="gambling-subheader">Let's get you your parts!</h2>
<h2 class="gambling-subheader">Let's get those parts!</h2>
</div>
<img src="./rummaging.png" class="gambling-header-rummage">
<img src="./landing-new/rummaging.png" class="gambling-header-rummage">
</div>
<button onclick="rollParts(this)" class="gambling-roll hoverable disabled redbutton">Roll!</button>
<div class="gambling-ui">
<div class="gambling-spinner">
<div class="gambling-item-wrapper">
<img class="gambling-placeholder" src="./qmark.svg">
<img class="gambling-placeholder" src="./landing-new/qmark.svg">
</div>
</div>
<div class="spinner-separator">+</div>
<div class="gambling-spinner">
<div class="gambling-item-wrapper">
<img class="gambling-placeholder" src="./qmark.svg">
<img class="gambling-placeholder" src="./landing-new/qmark.svg">
</div>
</div>
<div class="spinner-separator">+</div>
<div class="gambling-spinner">
<div class="gambling-item-wrapper">
<img class="gambling-placeholder" src="./qmark.svg">
<img class="gambling-placeholder" src="./landing-new/qmark.svg">
</div>
</div>
</div>
<div class="gambling-controls">
<button onclick="rollParts(this)" class="gambling-roll hoverable disabled">Roll!</button>
<span class="flex-lb"></span>
<button onclick="location.href='../selector/index.html'" class="gambling-select hoverable">Manual
<!-- <button onclick="location.href='./selector/'" class="gambling-select hoverable bluebutton">Manual
Selection</button>
<button onclick="generateBuildLink(this)" class="gambling-build hoverable disabled">Continue<img
src="../icons/arrow.svg"></button>
<button onclick="generateBuildLink(this)" class="gambling-build hoverable disabled greenbutton">Continue<img
src="./icons/arrow.svg"></button> -->
</div>
</section>
<section class="project-idea-section section">
<section class="project-idea-section section container">
<div class="project-idea-container">
<h1>What are we building today?</h1>
<textarea id="project-name" placeholder="I'm going to build a..."></textarea>
<h1>💡 Need an idea? Click the raccoon!</h1>
<h1 class="project-idea-title">
What are you waiting for?
</h1>
<!-- <div class="project-idea-buttons"> -->
<!-- <button onclick="location.href='./selector/'" class="gambling-select bluebutton hoverable">
Parts list
</button> -->
<!-- <button class="gambling-select hoverable redbutton">
What can I make?
</button> -->
<!-- <span class="flex-lb hideonmobile"></span> -->
<button onclick="generateBuildLink(this)" class="gambling-build hoverable greenbutton disabled"
style="margin-top: 2em; margin-bottom: 2em">
Open the editor
<img src="./icons/arrow_white.svg">
</button>
<!-- </div> -->
<div class="hidden" style="text-align: center;">
<h3>Get started or click the raccoon for project ideas!</h3>
<p><em>(It doesn't know much about electronics, but it'll try its best.)</em></p>
<div style="justify-content: center; display: grid;">
<p id="project-idea" class="thought">🗑️</p>
<img src="./images/idea.png" class="hoverable"
style="margin: 0 auto; display: inline; max-width: 10em; height: auto;"
id="generate-project-idea" onclick="generateProjectIdea()">
</div>
</div>
<!-- <div class="project-idea-images">
<img src="./parts/humidity.png">
<img src="./parts/humidity.png">
<img src="./parts/humidity.png">
</div>
<h1>Need an idea?<br>Tap the raccoon!</h1>
<p><em>(It doesn't know much about electronics, but it'll try its best.)</em></p>
<div style="display: flex;">
<div>
<img src="../images/idea.png" class="hoverable"
<img src="./images/idea.png" class="hoverable"
style="margin: 0 auto; display: inline; max-width: 10em; height: auto;"
id="generate-project-idea" onclick="generateProjectIdea()">
</div>
<p id="project-idea" class="thought">🗑️</p>
</div>
<textarea id="project-name" placeholder="I'm going to build a..."></textarea>
<button id="project-idea-build" class="hoverable">
Let's build!
<img src="./icons/arrow.svg">
</button> -->
</div>
</section>
<section class="section container">
<h1>Readme</h1>
<section class="faq-section section container">
<h1>Any questions?</h1>
<div class="faq-grid">
<div class="faq-item">
<h3>How many projects can I build?</h3>
<p>You can submit as many projects as you want! For second submissions, well ship the parts you dont have for example, your first project will get a pico included and subsequent projects wont ship with it.</p>
<h1>How many projects can I build?</h1>
<p>You can submit as many projects as you want! For second submissions, well ship the parts you dont
have for example, your first project will get a pico included and subsequent projects wont ship
with it.</p>
</div>
<div class="faq-item">
<h3>How much does it cost?</h3>
<p>100% free well also give a breadboard and the jumper wires you need to build your project too! The whole program is funded by <a href="https://hcb.hackclub.com/donations/start/the-bin">donations to a non-profit</a>.</p>
<h1>How much does it cost?</h1>
<p>100% free well also give a breadboard and the jumper wires you need to build your project too! The
whole program is funded by <a href="https://hcb.hackclub.com/donations/start/the-bin">donations to a
non-profit</a>.</p>
</div>
<div class="faq-item">
<h3>Who is eligible?</h3>
<p>You need to be a high schooler (or younger) in the United States. Submissions need to be in by June 1st to qualify.</p>
<h1>Who is eligible?</h1>
<p>You need to be a high schooler (or younger) in the United States. Submissions need to be in by June
1st to qualify.</p>
</div>
<div class="faq-item">
<h3>What do I need?</h3>
<p>Just a browser simulate & computer to upload your code to the pico well give you all the equipment you need for your circuit.</p>
<h1>What do I need?</h1>
<p>Just a browser simulator & computer to upload your code to the pico well give you all the equipment
you need for your circuit.</p>
</div>
<div class="faq-item">
<h3>I need help!</h3>
<p>Get it in the #electronics channel of the <a href="https://hackclub.com/slack">Hack&nbsp;Club&nbsp;Slack</a>.</p>
<h1>I need help!</h1>
<p>Get it in the #electronics channel of the <a
href="https://hackclub.com/slack">Hack&nbsp;Club&nbsp;Slack</a>.</p>
</div>
<div class="faq-item">
<h3>What designs are allowed?</h3>
<p>Check out the <a href="">list of eligible parts</a>! Each design can have up to 8 modules, and need at least 1 module.</p>
<h1>What designs are allowed?</h1>
<p>Check out the <a href="">list of eligible parts</a>! Each design can have up to 8 modules, and need
at least 1 module.</p>
</div>
</div>
</section>
<footer>
<div class="footer-wrapper">
<div class="footer-information">
<h3 class="footer-information-header">
<p class="footer-information-header">
A project by
<a href="https://github.com/kvnyng" target="_blank">Kevin Yang</a>,
<a href="https://hackclub.com">Hack Club</a>. Always <a href="https://github.com/hackclub/site">open
source</a>.
</p>
<p>
<a href="https://hackclub.com/bin/prelaunch">Rewind</a>
Thank you:
<a href="https://awdev.codes" target="_blank">Aaron Wong</a>,
<a href="https://github.com/kvnyng" target="_blank">Kevin Yang</a>, &
<a href="https://maxwofford.com" target="_blank">Max Wofford</a>
and
<a href="https://awdev.codes" target="_blank">Aaron Wong</a>.
</h3>
</p>
<p>Hack Club is a registered 501(c)3 nonprofit organization that supports a network
of 20k+ technical high schoolers. We believe you learn best by building so we're removing barriers
to hardware access so any teenager can explore. In the past few years, we
@ -310,7 +401,7 @@
<p class="footer-cr-info">© 2024 Hack&nbsp;Club. 501(c)(3) nonprofit (EIN: 81-2908499)</p>
</div>
</footer>
<script src="./gambling.js"></script>
<script src="./landing-new/gambling.js"></script>
</body>
</html>

View file

@ -119,6 +119,10 @@ function addComponentsToPage(data) {
})
}
function sample(arr) {
return arr[Math.floor(Math.random() * arr.length)]
}
function rollParts(el) {
if (el.classList.contains("disabled")) {
return
@ -128,27 +132,25 @@ function rollParts(el) {
element.removeChild(element.firstElementChild)
})
addComponentsToPage(fetchedParts)
rolled = true
}
rolled = true
document.querySelector(".gambling-build").classList.remove("disabled")
let chosenParts = []
const numPartsNeeded = document.querySelectorAll(".gambling-item-wrapper").length
// for the first one, pick an input component
const inputParts = fetchedParts.filter((part) => part.type == "Input");
const inputPartIndex = Math.floor(Math.random() * inputParts.length)
chosenParts.push(inputParts[inputPartIndex])
console.log(`For the input part, we picked ${inputParts[inputPartIndex].name}`)
const inputPart = sample(inputParts)
chosenParts.push(inputPart)
console.log(`For the input part, we picked ${inputPart.name}`)
// for the second one, pick an output component
const outputParts = fetchedParts.filter((part) => part.type == "Output");
const outputPartIndex = Math.floor(Math.random() * outputParts.length)
chosenParts.push(outputParts[outputPartIndex])
console.log(`For the output part, we picked ${outputParts[outputPartIndex].name}`)
const outputPart = sample(outputParts)
chosenParts.push(outputPart)
console.log(`For the output part, we picked ${outputPart.name}`)
// for the rest, pick any component
for (let i = 2; i < numPartsNeeded; i++) {
let partIndex = Math.floor(Math.random() * fetchedParts.length)
chosenParts.push(fetchedParts[partIndex])
console.log(`For the ${i}th part, we picked ${fetchedParts[partIndex].name}`)
}
const unusedParts = fetchedParts.filter((part) => part.name != inputPart.name && part.name != outputPart.name)
const thirdPart = sample(unusedParts)
chosenParts.push(thirdPart)
console.log(`For the third part, we picked ${thirdPart.name}`)
let chosenPartNames = []
document.querySelectorAll(".gambling-item-wrapper").forEach((element, key) => {
let thisPart = chosenParts[key]

View file

@ -33,11 +33,12 @@ async function fetchAndLogTextFile(url) {
console.error('Error fetching the file:', error);
}
}
fetchAndLogTextFile('./ascii-art.txt');
window.addEventListener("load", (e) => {
function recalculateSectionHeight() {
document.querySelectorAll(".section").forEach(element => {
element.style.minHeight = element.getBoundingClientRect().height + "px"
})
})
}
fetchAndLogTextFile('./landing-new/ascii-art.txt');
window.addEventListener("load", recalculateSectionHeight())
window.addEventListener("resize", recalculateSectionHeight())

View file

@ -3,8 +3,9 @@
width: 100%;
box-sizing: border-box;
}
.container {
max-width: 52em;
max-width: 62em;
margin: auto;
}
@ -14,6 +15,7 @@
.hoverable {
transition: 500ms transform;
cursor: pointer;
}
.hoverable:hover {
@ -63,10 +65,22 @@
.scroll-prompt {
cursor: pointer;
position: absolute;
display: block;
display: flex;
justify-content: center;
align-items: center;
left: 50%;
bottom: 20px;
transform: translateX(-50%);
background: linear-gradient(#63CE61, #ADEA00);
height: 50px;
width: 50px;
padding: 20px;
border-radius: 50%;
transition: transform 300ms;
}
.scroll-prompt:hover {
transform: translateX(-50%) scale(1.05);
}
.landing-main-image {
@ -77,7 +91,7 @@
#floaty,
#floaty-left {
width: 300px;
width: 17vw;
position: absolute;
}
@ -93,10 +107,10 @@
.gambling-section {
padding: 50px;
display: flex;
flex-direction: column;
gap: 30px;
max-width: 75em;
/* display: flex; */
/* flex-direction: column; */
/* gap: 30px; */
/* max-width: 75em; */
margin: auto;
}
@ -131,8 +145,9 @@
.gambling-ui {
display: flex;
flex-direction: row;
justify-content: center;
justify-content: space-between;
align-items: center;
margin-top: 2em;
}
.gambling-spinner {
@ -203,12 +218,12 @@
}
.spinner-item-name {
font-size: 35px;
font-size: 1.5em;
text-align: center;
}
.spinner-item-description {
font-size: 25px;
font-size: 1.2em;
text-align: center;
}
@ -224,7 +239,7 @@
gap: 10px;
}
.gambling-controls button {
/* .gambling-section button {
font-weight: bolder;
box-sizing: border-box;
border: none;
@ -238,17 +253,30 @@
flex-grow: 1;
gap: 30px;
align-items: center;
}
} */
.gambling-controls button img {
height: 30px;
}
button {
border-radius: 0.5em;
font-size: 40px;
font-weight: bolder;
box-sizing: border-box;
color: white;
border: none;
padding: 10px 30px;
margin: 1em;
}
.gambling-roll {
background-color: #ee9f9f;
flex-grow: 1;
flex-basis: 100%;
margin-bottom: -10px;
display: inherit;
margin: 0 auto;
}
.gambling-controls:first-child {
@ -264,10 +292,12 @@
background-color: #9FEEB5;
filter: saturate(1) brightness(1);
transition: filter 500ms;
display: flex;
gap: 20px;
}
.gambling-build.disabled {
filter: saturate(0.4) brightness(0.6);
filter: saturate(0.5) brightness(0.7);
}
.gambling-placeholder {
@ -276,6 +306,253 @@
margin: auto;
}
#generate-project-idea {
cursor: pointer;
}
.project-idea-section {
margin-bottom: 30px;
}
#project-name {
resize: none;
width: 70%;
border: none;
padding: 20px;
font-size: 20px;
margin-bottom: 30px;
border-radius: 30px;
}
.project-idea-buttons {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
column-gap: 20px;
row-gap: 5px;
}
.gambling-build {
margin: auto;
}
.project-idea-buttons button {
margin: 0;
}
.project-idea-container {
margin: auto;
padding: 50px;
width: inherit;
box-sizing: border-box;
}
.project-idea-container h1 {
font-size: 50px;
margin-bottom: 10px;
}
.project-idea-images {
display: flex;
flex-direction: row;
width: 100%;
justify-content: space-evenly;
gap: 5px;
display: none;
height: 90px;
}
.project-idea-images img {
height: 100%;
width: auto;
}
#project-idea-build {
font-size: 30px;
font-weight: bolder;
border: none;
background-color: #9FEEB5;
padding: 10px 30px;
border-radius: 30px;
height: min-content;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 10px;
}
#project-idea-build img {
height: 25px;
}
/* CSS from https://codepen.io/quadbaup/details/rKOKQv */
.thought {
display: flex;
background-color: #fff;
padding: 20px;
border-radius: 30px;
min-width: 40px;
max-width: 220px;
min-height: 40px;
margin: 20px;
position: relative;
align-items: center;
justify-content: center;
/* text-align:center; */
}
.thought:before,
.thought:after {
content: "";
background-color: #fff;
border-radius: 50%;
display: block;
position: absolute;
z-index: -1;
}
.thought:before {
width: 44px;
height: 44px;
top: -12px;
left: 28px;
box-shadow: -50px 30px 0 -12px #fff;
}
.thought:after {
bottom: -10px;
right: 26px;
width: 30px;
height: 30px;
box-shadow: 40px -34px 0 0 #fff,
-28px -6px 0 -2px #fff,
-24px 17px 0 -6px #fff,
-5px 25px 0 -10px #fff;
}
.disabled {
cursor: not-allowed;
}
.loading {
cursor: wait;
}
#generate-project-idea {
cursor: pointer;
}
#project-name {
resize: none;
width: 70%;
border: none;
padding: 20px;
font-size: 20px;
margin-bottom: 30px;
border-radius: 30px;
}
.faq-section {
padding: 50px;
}
.faq-section h1 {
font-size: 50px;
}
.faq-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
margin-top: 2em;
margin-bottom: 2em;
}
.faq-item {
padding: 20px;
border-radius: 20px;
background-color: #EEEDED;
backdrop-filter: blur(10px);
filter: saturate(0.9);
}
.faq-item a {
color: black;
}
.faq-item p {
margin-top: 1em;
}
.faq-item h1 {
font-size: 1.5em;
}
.timeline-header {
font-size: 70px;
width: fit-content;
margin: auto;
}
.timeline-subheader {
font-weight: normal;
font-style: italic;
margin: auto;
width: fit-content;
font-size: 50px;
}
.timeline-list {
margin: auto;
grid-template-columns: 1fr 1fr 1fr;
height: min-content;
display: grid;
gap: 20px;
width: 100%;
box-sizing: border-box;
padding: 50px;
max-width: 62em;
}
.timeline-item {
padding: 10px;
background-color: black;
border-radius: 20px;
box-sizing: border-box;
height: 100%;
}
.timeline-info {
background-color: #EEEDED;
height: 100%;
border-radius: 12px;
padding: 20px;
box-sizing: border-box;
}
.timeline-info a {
color: black;
}
.muted {
opacity: 0.5;
}
.greenbutton {
background: linear-gradient(to bottom right, #63CE61, #ADEA00);
}
.bluebutton {
background: linear-gradient(to bottom right, #7A97FC, #7AEDFC);
}
.redbutton {
background: linear-gradient(to bottom right, #FC7A7A, #FCA97A);
}
@keyframes float {
from,
@ -347,7 +624,10 @@
}
}
@media only screen and (hover: none) and (pointer: coarse) {
@media only screen and (max-width: 900px) {
body {
overflow-x: hidden;
}
#floaty,
#floaty-left,
@ -419,6 +699,7 @@
flex-direction: row;
border-radius: 20px;
gap: 10px;
overflow: hidden;
}
.spinner-item-name,
@ -442,131 +723,102 @@
height: auto;
width: 100px;
}
}
/* CSS from https://codepen.io/quadbaup/details/rKOKQv */
.thought {
display: flex;
background-color: #fff;
padding: 20px;
border-radius: 30px;
min-width: 40px;
max-width: 220px;
min-height: 40px;
margin: 20px;
position: relative;
align-items: center;
justify-content: center;
/* text-align:center; */
}
.thought:before,
.thought:after {
content: "";
background-color: #fff;
border-radius: 50%;
display: block;
position: absolute;
z-index: -1;
}
.thought:before {
width: 44px;
height: 44px;
top: -12px;
left: 28px;
box-shadow: -50px 30px 0 -12px #fff;
}
.thought:after {
bottom: -10px;
right: 26px;
width: 30px;
height: 30px;
box-shadow: 40px -34px 0 0 #fff,
-28px -6px 0 -2px #fff,
-24px 17px 0 -6px #fff,
-5px 25px 0 -10px #fff;
}
.disabled {
cursor: not-allowed !important;
}
.loading {
cursor: wait !important;
}
#generate-project-idea {
cursor: pointer;
}
#project-name {
resize: none;
width: 70%;
border: none;
padding: 20px;
font-size: 20px;
margin-bottom: 30px;
border-radius: 30px;
}
.project-idea-container {
margin: auto;
padding: 0 20px;
max-width: 52em;
}
.project-idea-container h1 {
font-size: 40px;
margin-bottom: 10px;
}
.faq-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
margin-top: 2em;
margin-bottom: 2em;
}
.faq-item {
padding: 20px;
border: 1px solid rgba(255,255,255,0.4);
border-radius: 20px;
background-color: rgba(255,255,255,0.2);
backdrop-filter: blur(10px);
}
.faq-item p {
margin-top: 1em;
}
.timeline-list {
margin: 2em auto;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 300px 300px;
display: grid;
gap: 10px;
}
@media only screen and (max-width: 768px) {
.timeline-list {
/* display: grid; */
grid-template-columns: 1fr;
/* padding: 1em; */
/* grid-row-gap: 100px; */
.project-idea-section {
padding-top: 20px;
}
}
.timeline-item {
padding: 20px;
border: 1px solid rgba(255,255,255,0.4);
border-radius: 20px;
background-color: rgba(255,255,255,0.2);
backdrop-filter: blur(10px);
.project-idea-container {
height: 100%;
display: flex;
flex-direction: column;
gap: 10px;
padding: 30px;
padding-top: 20px;
padding-bottom: 10px;
box-sizing: border-box;
align-items: center;
}
.project-idea-buttons {
gap: 10px;
}
.project-idea-buttons button {
width: 100%;
}
.project-idea-title {
font-size: 48px;
}
#project-name {
margin: auto;
width: 90%;
display: block;
border-radius: 20px;
flex-grow: 1;
}
.project-idea-images {
display: flex;
}
.timeline {
padding: 30px;
}
.timeline-list {
padding: 0px;
}
.timeline-header {
font-size: 40px;
margin: 0;
}
.timeline-subheader {
font-size: 30px;
margin: 0;
margin-bottom: 20px;
}
.faq-section {
padding: 30px;
}
.hideonmobile {
display: none;
}
}
.muted {
opacity: 0.5;
/*who is even using this*/
@media only screen and (max-width: 300px) {
.spinner-item-image {
display: none;
}
}
@media only screen and (max-width: 52em) {
.timeline-list {
grid-template-columns: 1fr;
}
}
.talking {
animation: talking 1s infinite;
}
@keyframes talking {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-10px);
}
100% {
transform: translateY(0px);
}
}

View file

@ -12,6 +12,30 @@
<link rel="icon" type="image/png" sizes="16x16" href="https://assets.hackclub.com/favicons/favicon-16x16.png">
<script src="https://awdev.codes/utils/smoothScroll.js"></script>
<script src="https://awdev.codes/utils/hackclub/orph.js"></script>
<script src="../data-loading.js"></script>
<script defer data-domain="hackclub.com" src="https://plausible.io/js/script.js"></script>
<script>
window['_fs_host'] = 'fullstory.com';
window['_fs_script'] = 'edge.fullstory.com/s/fs.js';
window['_fs_org'] = 'ARN0J';
window['_fs_namespace'] = 'FS';
!function(m,n,e,t,l,o,g,y){var s,f,a=function(h){
return!(h in m)||(m.console&&m.console.log&&m.console.log('FullStory namespace conflict. Please set window["_fs_namespace"].'),!1)}(e)
;function p(b){var h,d=[];function j(){h&&(d.forEach((function(b){var d;try{d=b[h[0]]&&b[h[0]](h[1])}catch(h){return void(b[3]&&b[3](h))}
d&&d.then?d.then(b[2],b[3]):b[2]&&b[2](d)})),d.length=0)}function r(b){return function(d){h||(h=[b,d],j())}}return b(r(0),r(1)),{
then:function(b,h){return p((function(r,i){d.push([b,h,r,i]),j()}))}}}a&&(g=m[e]=function(){var b=function(b,d,j,r){function i(i,c){
h(b,d,j,i,c,r)}r=r||2;var c,u=/Async$/;return u.test(b)?(b=b.replace(u,""),"function"==typeof Promise?new Promise(i):p(i)):h(b,d,j,c,c,r)}
;function h(h,d,j,r,i,c){return b._api?b._api(h,d,j,r,i,c):(b.q&&b.q.push([h,d,j,r,i,c]),null)}return b.q=[],b}(),y=function(b){function h(h){
"function"==typeof h[4]&&h[4](new Error(b))}var d=g.q;if(d){for(var j=0;j<d.length;j++)h(d[j]);d.length=0,d.push=h}},function(){
(o=n.createElement(t)).async=!0,o.crossOrigin="anonymous",o.src="https://"+l,o.onerror=function(){y("Error loading "+l)}
;var b=n.getElementsByTagName(t)[0];b&&b.parentNode?b.parentNode.insertBefore(o,b):n.head.appendChild(o)}(),function(){function b(){}
function h(b,h,d){g(b,h,d,1)}function d(b,d,j){h("setProperties",{type:b,properties:d},j)}function j(b,h){d("user",b,h)}function r(b,h,d){j({
uid:b},d),h&&j(h,d)}g.identify=r,g.setUserVars=j,g.identifyAccount=b,g.clearUserCookie=b,g.setVars=d,g.event=function(b,d,j){h("trackEvent",{
name:b,properties:d},j)},g.anonymize=function(){r(!1)},g.shutdown=function(){h("shutdown")},g.restart=function(){h("restart")},
g.log=function(b,d){h("log",{level:b,msg:d})},g.consent=function(b){h("setIdentity",{consent:!arguments.length||b})}}(),s="fetch",
f="XMLHttpRequest",g._w={},g._w[f]=m[f],g._w[s]=m[s],m[s]&&(m[s]=function(){return g._w[s].apply(this,arguments)}),g._v="2.0.0")
}(window,document,window._fs_namespace,"script",window._fs_script);
</script>
</head>
<body>

View file

@ -1,3 +1,4 @@
const partsLimit = 8
var fetchedParts;
async function fetchParts() {
const response = await fetch('https://hackclub.com/api/bin/wokwi/parts/');
@ -33,8 +34,8 @@ function recalculateSelected() {
let selections = []
items = document.querySelectorAll(".selector-item")
items = document.querySelectorAll(".selector-item")
document.querySelector(".selector-number").innerText = `${3 - numSelectedItems} choices remaining.`
if (3 - numSelectedItems == 0) {
document.querySelector(".selector-number").innerText = `${partsLimit - numSelectedItems} choices remaining.`
if (partsLimit - numSelectedItems == 0) {
items.forEach(item => {
let isSelected = item.className.includes("selected")
if (!isSelected) {
@ -92,7 +93,7 @@ function addPartToPage(part) {
if (isSelected) {
selectorItem.classList.remove("selected")
} else {
if (getSelectedItems().length < 3) {
if (getSelectedItems().length < partsLimit) {
selectorItem.classList.add("selected")
}
}
@ -100,17 +101,13 @@ function addPartToPage(part) {
})
}
window.addEventListener("load", (e) => {
window.addEventListener("load", async (e) => {
recalculateSelected();
fetchParts().then(parts => {
fetchedParts = parts;
fetchedParts.forEach(part => {
if (!(part.imageUrl == undefined)) {
console.log(part.wokwiName)
//saveImageToCache(part);
addPartToPage(part)
}
})
//saveImageToCache({ wokwiName: "wokwi-pedro", imageUrl: "https://awdev.codes/images/ww.gif" })
});
const fetchedParts = await partsData()
fetchedParts.forEach(part => {
if (!(part.imageUrl == undefined)) {
console.log(part.wokwiName)
addPartToPage(part)
}
})
})