diff --git a/package.json b/package.json
index 07dd8a65..0c393a52 100644
--- a/package.json
+++ b/package.json
@@ -57,6 +57,7 @@
"next": "^12.3.1",
"next-transpile-modules": "^10.0.1",
"nextjs-current-url": "^1.0.3",
+ "openai": "^4.42.0",
"pcb-stackup": "^4.2.8",
"react": "^17.0.2",
"react-before-after-slider-component": "^1.1.8",
diff --git a/pages/api/bin/openai.js b/pages/api/bin/openai.js
new file mode 100644
index 00000000..d3374612
--- /dev/null
+++ b/pages/api/bin/openai.js
@@ -0,0 +1,40 @@
+import OpenAI from 'openai';
+
+const generateProjectIdea = async (parts) => {
+
+ let prompt = `I'm running a hardware program around the raspberry pi pico w where high schoolers will build a simple project using the following parts. Please propose a simple project in 1-2 sentences to use as a prompt for the high schoolers to build with:
+
+`
+ parts.forEach((part) => {
+ prompt += `- ${part}\n`
+ })
+
+ prompt += `
+ The project should only involve household items like lamps. The project should only use sensors provided, and use those sensors for their intended use. For example, an accelerometer cannot be used to measure humidity or tilt.`
+
+ // expects OPENAI_API_KEY
+ const openai = new OpenAI();
+ const chatCompletion = await openai.chat.completions.create({
+ messages: [{ role: 'user', content: prompt }],
+ model: 'gpt-3.5-turbo',
+ });
+
+ return chatCompletion.choices[0].message.content
+}
+
+export default async function handler(req, res) {
+ const requestedParts = req.body.parts
+
+ const availablePartsReq = await fetch('https://hackclub.com/api/bin/wokwi/parts')
+ const availableParts = await availablePartsReq.json()
+
+ // check that the requested parts are in the available parts
+ const parts = requestedParts.map((requestedPart) => {
+ return availableParts.find((availablePart) => availablePart.wokwiName === requestedPart)?.name
+ })
+
+ const recommendation = await generateProjectIdea(parts)
+
+ res.send({recommendation, parts})
+}
+
diff --git a/public/bin/landing-new/gambling.js b/public/bin/landing-new/gambling.js
index 33444f89..d5a78fba 100644
--- a/public/bin/landing-new/gambling.js
+++ b/public/bin/landing-new/gambling.js
@@ -1,7 +1,7 @@
var fetchedParts;
+var selectedParts = []
var rolled = false;
async function fetchParts() {
- /*
const response = await fetch('https://hackclub.com/api/bin/wokwi/parts/');
if (!response.ok) {
throw new Error('Network response was not ok.');
@@ -9,192 +9,19 @@ async function fetchParts() {
data = await response.json();
data = removeItemByAttribute(data, "type", "Microprocessor");
- console.log(data)*/
- data = [
- {
- "name": "Motion Sensor",
- "flavorText": "Detects movement.",
- "type": "Component",
- "wokwiName": "wokwi-pir-motion-sensor",
- "wokwiXOffset": 89
- },
- {
- "name": "Temperature Sensor",
- "flavorText": "Temp checker!",
- "type": "Component",
- "wokwiName": "board-ds18b20",
- "wokwiXOffset": 32.88
- },
- {
- "name": "Clock (RTC)",
- "flavorText": "It's a clock!",
- "type": "Component",
- "wokwiName": "wokwi-ds1307",
- "wokwiXOffset": 99
- },
- {
- "name": "Buzzer",
- "flavorText": "Make noise!",
- "type": "Component",
- "wokwiName": "wokwi-buzzer",
- "notes (internal)": "Double check if active or passive",
- "wokwiXOffset": 69
- },
- {
- "name": "Humidity",
- "flavorText": "Moisture monitor",
- "imageUrl": "https://cloud-q01dbzfhj-hack-club-bot.vercel.app/1humidity.png",
- "type": "Component",
- "wokwiName": "wokwi-dht22",
- "notes (internal)": "We actually send the dht11",
- "wokwiXOffset": 56
- },
- {
- "name": "Rotary Encoder",
- "flavorText": "Detect spinning!",
- "type": "Component",
- "wokwiName": "wokwi-ky-040",
- "wokwiXOffset": 120
- },
- {
- "name": "Shift Register",
- "flavorText": "Switch inputs!",
- "type": "Component",
- "wokwiName": "wokwi-74hc595",
- "wokwiXOffset": 76
- },
- {
- "name": "Range finder",
- "flavorText": "Measure distance!",
- "type": "Component",
- "wokwiName": "wokwi-hc-sr04",
- "wokwiXOffset": 168.7
- },
- {
- "name": "Keypad",
- "flavorText": "Dial a number!",
- "type": "Component",
- "wokwiName": "wokwi-membrane-keypad",
- "wokwiXOffset": 264.8
- },
- {
- "name": "Accelerometer",
- "flavorText": "Speedchecker!",
- "type": "Component",
- "wokwiName": "wokwi-mpu6050",
- "wokwiXOffset": 82
- },
- {
- "name": "Neopixel LED",
- "flavorText": "Technicolor!",
- "type": "Component",
- "wokwiName": "wokwi-neopixel",
- "wokwiXOffset": 21
- },
- {
- "name": "LED",
- "flavorText": "It's lit!",
- "imageUrl": "https://cloud-q01dbzfhj-hack-club-bot.vercel.app/4led.png",
- "type": "Component",
- "wokwiName": "wokwi-led",
- "wokwiXOffset": 24
- },
- {
- "name": "Stepper Motor",
- "flavorText": "It spins!",
- "type": "Component",
- "wokwiName": "wokwi-stepper-motor,wokwi-a4988",
- "wokwiXOffset": 162
- },
- {
- "name": "Slider",
- "flavorText": "A sliding input!",
- "type": "Component",
- "wokwiName": "wokwi-slide-potentiometer",
- "wokwiXOffset": 210.2
- },
- {
- "name": "Thermistor",
- "flavorText": "Temperature checker!",
- "type": "Component",
- "wokwiName": "wokwi-ntc-temperature-sensor",
- "wokwiXOffset": 139
- },
- {
- "name": "Relay",
- "flavorText": "Turn things on and off!",
- "imageUrl": "https://cloud-q01dbzfhj-hack-club-bot.vercel.app/0relay.png",
- "type": "Component",
- "wokwiName": "wokwi-relay-module",
- "wokwiXOffset": 130
- },
- {
- "name": "LCD",
- "flavorText": "Display text!",
- "type": "Component",
- "wokwiName": "wokwi-lcd1602",
- "wokwiXOffset": 303.2
- },
- {
- "name": "Servo",
- "flavorText": "Move stuff",
- "type": "Component",
- "wokwiName": "wokwi-servo",
- "wokwiXOffset": 178.2
- },
- {
- "name": "Joystick",
- "flavorText": "It's a joystick!",
- "type": "Component",
- "wokwiName": "wokwi-analog-joystick",
- "wokwiXOffset": 98
- },
- {
- "name": "Potentiometer",
- "flavorText": "It's a dial!",
- "type": "Component",
- "wokwiName": "wokwi-potentiometer",
- "wokwiXOffset": 76.6
- },
- {
- "name": "Multicolor LED",
- "flavorText": "Now, in color!",
- "type": "Component",
- "wokwiName": "wokwi-rgb-led",
- "wokwiXOffset": 30
- },
- {
- "name": "Photoresistor",
- "flavorText": "Detect light!",
- "type": "Component",
- "wokwiName": "wokwi-photoresistor-sensor",
- "wokwiXOffset": 173.6
- },
- {
- "name": "Button",
- "flavorText": "Bop it!",
- "type": "Component",
- "wokwiName": "wokwi-pushbutton",
- "wokwiXOffset": 67
- },
- {
- "name": "IR Reciever",
- "flavorText": "Detect Infrared!",
- "imageUrl": "https://cloud-q01dbzfhj-hack-club-bot.vercel.app/2ir.png",
- "type": "Component",
- "wokwiName": "wokwi-ir-receiver",
- "wokwiXOffset": 62
- },
- {
- "name": "LED Matrix",
- "flavorText": "Display stuff!",
- "type": "Component",
- "wokwiName": "wokwi-max7219-matrix",
- "wokwiXOffset": 340
- }
- ]
+ console.log(data)
return data
}
+async function preloadImage(item) {
+ let response = await fetch(item.imageUrl);
+ let blob = response.blob();
+ return blob
+}
+async function saveImageToCache(item) {
+ const image = await preloadImage(item)
+ const blob = URL.createObjectURL(image)
+ localStorage.setItem(item.wokwiName, blob);
+}
function removeItemByAttribute(arr, attr, value) {
return arr.filter(item => item[attr] !== value);
}
@@ -252,23 +79,79 @@ function rollParts() {
addComponentsToPage(data)
}
rolled = true
- let results = {}
- let counter = 0
+ document.querySelector(".gambling-build").classList.remove("disabled")
+ let results = []
document.querySelectorAll(".gambling-item-wrapper").forEach((element) => {
let randomThingy = getRandomInt(fetchedParts.length - 1)
let spinnerImage = element.childNodes[2].childNodes[0]
let partTitle = element.childNodes[2].childNodes[1]
let flavorText = element.childNodes[2].childNodes[2]
let result = fetchedParts[randomThingy]
- spinnerImage.src = (result.imageURL == "" || result.imageURL == undefined) ? "https://awdev.codes/images/ww.gif" : result.imageURL
+ //spinnerImage.src = (result.imageUrl == "" || result.imageUrl == undefined) ? "https://awdev.codes/images/ww.gif" : result.imageUrl
+ spinnerImage.src = (result.imageUrl == "" || result.imageUrl == undefined) ? localStorage.getItem("wokwi-pedro") : localStorage.getItem(result.wokwiName)
partTitle.innerText = result.name;
flavorText.innerText = result.flavorText;
- results[counter] = result.wokwiName
- counter++;
+ results.push(result.wokwiName)
})
- console.log(results)
+ selectedParts = results
}
+
+async function generateBuildLink(e) {
+ if (!rolled) {
+ return
+ }
+ e.classList.add("disabled")
+ e.classList.add("loading")
+ const payload = {
+ parts: selectedParts
+ };
+
+ try {
+ const response = await fetch('/api/bin/wokwi/new/', {
+ mode: 'cors',
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(payload)
+ })
+ if (!response.ok) {
+ throw new Error('Network response was not ok');
+ }
+ const json = await response.json()
+ const shareLink = json.shareLink
+
+ // window.open(shareLink, '_blank').focus()
+ } catch (error) {
+ console.error('Error:', error)
+ // e.classList.add("error")
+ }
+ e.classList.remove("disabled")
+ e.classList.remove("loading")
+}
window.addEventListener("load", (e) => {
- fetchParts().then(parts => { fetchedParts = parts });
+ fetchParts().then(parts => {
+ fetchedParts = parts;
+ fetchedParts.forEach(part => {
+ if (!(part.imageUrl == undefined)) {
+ console.log(part.wokwiName)
+ saveImageToCache(part);
+ }
+ })
+ saveImageToCache({ wokwiName: "wokwi-pedro", imageUrl: "https://awdev.codes/images/ww.gif" })
+ });
+
+ document.querySelector("#generate-project-idea").addEventListener("click", async (e) => {
+ document.querySelector('#project-idea').innerText = "Thinking..."
+ const res = await fetch('/api/bin/openai/', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({ parts: selectedParts })
+ })
+ const json = await res.json()
+ document.querySelector('#project-idea').innerText = json.recommendation
+ })
})
\ No newline at end of file
diff --git a/public/bin/landing-new/index.html b/public/bin/landing-new/index.html
index 29237413..5677945a 100644
--- a/public/bin/landing-new/index.html
+++ b/public/bin/landing-new/index.html
@@ -60,10 +60,26 @@
-
+
-
-
+
+
+
+
+
+
+
What are we building today?
+
+
💡 Need an idea? Click the raccoon!
+
+
+

+
(It doesn't know much about electronics, but it'll try its best.)
+
+
🗑️
+