Update 2025-04-17_20:31:51

This commit is contained in:
root
2025-04-17 20:31:52 +02:00
commit 69427b62cc
9 changed files with 302 additions and 0 deletions

110
static/app.js Normal file
View File

@ -0,0 +1,110 @@
import { createEmojiButton } from './button.js'
const gameBoard = document.getElementById("game-board")
fetch("/api/riddle")
.then(res => res.json())
.then(data => {
renderEquations(data.equations)
renderInputForm(data.emojis);
setTimeout(() => document.querySelector('input')?.focus(), 10)
})
function renderEquations(equations) {
const container = document.createElement("div")
container.id = "equation-block"
equations.forEach(eq => {
const row = document.createElement("div")
row.innerText = `${eq.left[0]} + ${eq.left[1]} = ${eq.right}`
row.style.fontSize = "1.5rem"
row.style.margin = "0.3rem"
container.appendChild(row)
})
gameBoard.appendChild(container)
}
function renderInputForm(emojis) {
const wrapper = document.createElement("div")
wrapper.id = "guess-wrapper"
const form = document.createElement("form")
form.id = "guess-form"
emojis.forEach(emoji => {
const label = document.createElement("label")
label.classList.add("guess-label")
const emojiSpan = document.createElement("span")
emojiSpan.textContent = emoji
emojiSpan.style.marginRight = "0.5rem"
const input = document.createElement("input")
input.type = "number"
input.name = emoji
input.required = true
input.classList.add("input-field")
label.appendChild(emojiSpan)
label.appendChild(input)
form.appendChild(label)
})
const btn = document.createElement("button")
btn.type = "submit"
btn.innerText = "Check ✅"
btn.classList.add("btn-check")
form.appendChild(btn)
const feedback = document.createElement("div")
feedback.id = "feedback"
wrapper.appendChild(feedback)
form.querySelector("input")?.focus()
form.onsubmit = async (e) => {
e.preventDefault()
try {
const formData = new FormData(form)
const guess = {}
for (let [key, value] of formData.entries()) {
guess[key] = parseInt(value)
}
const res = await fetch("/api/check", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ guess })
})
if (!res.ok) throw new Error("Server returned " + res.status)
const result = await res.json()
feedback.textContent = result.result
feedback.style.color = result.result.includes("✅") ? "#1e7c1e" : "#cc3333"
feedback.style.opacity = 0
if (result.result.includes("❌")) {
feedback.classList.remove("shake")
void feedback.offsetWidth
feedback.classList.add("shake")
}
setTimeout(() => {
feedback.style.opacity = 1
form.querySelector("input")?.focus()
if (feedback.textContent.includes("✅")) {
feedback.textContent += " 🎉 Neue Runde startet in 3 Sekunden..."
setTimeout(() => location.reload(), 3000)
}
}, 50)
} catch (err) {
feedback.textContent = "⚠️ Error: " + err.message
feedback.style.color = "#cc3333"
feedback.style.opacity = 1
}
}
wrapper.appendChild(form)
gameBoard.appendChild(wrapper)
}

7
static/button.js Normal file
View File

@ -0,0 +1,7 @@
export function createEmojiButton() {
const btn = document.createElement('button')
btn.className = 'emoji-btn'
btn.textContent = '❓'
return btn
}

15
static/index.html Normal file
View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EmojiRiddle</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<h1>🧠 EmojiRiddle</h1>
<div id="game-board"></div>
<script type="module" src="/static/app.js"></script>
</body>
</html>

8
static/routes.js Normal file
View File

@ -0,0 +1,8 @@
from fastapi import APIRouter
router = APIRouter(prefix="/api")
@router.get("/ping")
def ping():
return {"status": "ok"}

81
static/style.css Normal file
View File

@ -0,0 +1,81 @@
body {
max-width: 960px;
margin: auto;
font-family: sans-serif;
text-align: center;
}
#game-board {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 1rem;
}
#guess-form {
margin-top: 1rem;
display: flex;
flex-direction: column;
align-items: center;
}
.input-field {
font-size: 1.5rem;
line-height: 1.5rem;
width: 100px;
text-align: center;
border: 1px solid #ccc;
border-radius: 4px;
background-color: #f9f9f9;
padding: 0.3rem 0.5rem;
box-sizing: border-box;
appearance: textfield;
}
.guess-label {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0.5rem;
font-size: 1.5rem;
}
.btn-check {
margin-top: 1rem;
font-size: 1.5rem;
}
#feedback {
margin-top: 1rem;
font-size: 1.2rem;
font-weight: bold;
transition: opacity 0.4s ease-in-out;
opacity: 0;
}
#feedback.shake {
animation: shake 0.3s;
}
@keyframes shake {
0% { transform: translateX(0); }
25% { transform: translateX(-4px); }
50% { transform: translateX(4px); }
75% { transform: translateX(-4px); }
100% { transform: translateX(0); }
}
button.emoji-btn {
font-size: 2rem;
width: 80px;
height: 80px;
margin: 0.5rem;
border: 2px solid #ccc;
background: white;
cursor: pointer;
}
button.emoji-btn:hover {
background: #eee;
}