commit b82adc93c77469492bab89d7c80211041bfb6b11 Author: dev Date: Sat Nov 15 18:40:39 2025 +0100 Initial commit diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1b3d8a6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM node:20-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +EXPOSE 3000 +CMD ["npm", "start"] \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..9fb853a --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "name": "whopays", + "version": "1.0.0", + "type": "module", + "scripts": { + "start": "node server.js" + }, + "dependencies": { + "express": "^4.19.2" + } +} \ No newline at end of file diff --git a/public/img/a.png b/public/img/a.png new file mode 100644 index 0000000..5294964 Binary files /dev/null and b/public/img/a.png differ diff --git a/public/img/b.png b/public/img/b.png new file mode 100644 index 0000000..8c33d60 Binary files /dev/null and b/public/img/b.png differ diff --git a/public/img/bgA.jpg b/public/img/bgA.jpg new file mode 100644 index 0000000..9073214 Binary files /dev/null and b/public/img/bgA.jpg differ diff --git a/public/img/bgB.jpg b/public/img/bgB.jpg new file mode 100644 index 0000000..5a48aac Binary files /dev/null and b/public/img/bgB.jpg differ diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..cd42239 --- /dev/null +++ b/public/index.html @@ -0,0 +1,48 @@ + + + + + + + + Wer zahlt? + + + + +
+

+ Who pays? +

+ +
+ Person +
+ Load ... +
+
+ + +
+ + + + diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..98566ff --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,20 @@ +{ + "name": "Who pays?", + "short_name": "Whopays", + "start_url": "/", + "display": "standalone", + "background_color": "#fff7f9", + "theme_color": "#ec4899", + "icons": [ + { + "src": "img/icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "img/icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} \ No newline at end of file diff --git a/public/script.js b/public/script.js new file mode 100644 index 0000000..d760d52 --- /dev/null +++ b/public/script.js @@ -0,0 +1,48 @@ +const img = document.getElementById("personImg"); +const nameEl = document.getElementById("personName"); +const button = document.getElementById("toggleButton"); + +async function loadStatus() { + const res = await fetch("/status"); + const data = await res.json(); + showStatus(data.current, false); +} + +function showStatus(person, animate = true) { + const file = person === "A" ? "img/a.png" : "img/b.png"; + const label = person === "A" ? "Honey" : "Kirby"; + + // Hintergrundbilder fßr A und B + const bgA = "url('img/bgA.jpg')"; + const bgB = "url('img/bgB.jpg')"; + + // Hintergrundanimation (optional) + document.body.style.transition = "background 0.4s ease"; + + // Hintergrund setzen + document.body.style.backgroundImage = person === "A" ? bgA : bgB; + document.body.style.backgroundSize = "cover"; + document.body.style.backgroundPosition = "center"; + + if (animate) { + img.classList.add("rotate"); + } + + setTimeout(() => { + img.src = file; + nameEl.textContent = label; + }, 150); + + setTimeout(() => { + img.classList.remove("rotate"); + }, 600); +} + + +button.addEventListener("click", async () => { + const res = await fetch("/toggle", { method: "POST" }); + const data = await res.json(); + showStatus(data.current); +}); + +loadStatus(); diff --git a/public/style.css b/public/style.css new file mode 100644 index 0000000..0742cc6 --- /dev/null +++ b/public/style.css @@ -0,0 +1,18 @@ +@keyframes pop { + 0% { transform: scale(0.9); opacity: 0.5; } + 100% { transform: scale(1); opacity: 1; } +} + +.status-box { + animation: pop 0.3s ease-out; +} +@keyframes rotate { + 0% { transform: rotateY(0deg); } + 50% { transform: rotateY(90deg); opacity: 0.6; } + 100% { transform: rotateY(180deg); opacity: 1; } +} + +.rotate { + animation: rotate 0.6s ease-in-out; + transform-style: preserve-3d; +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..b02d95e --- /dev/null +++ b/server.js @@ -0,0 +1,40 @@ +import express from "express"; +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const app = express(); +app.use(express.json()); +app.use(express.static(path.join(__dirname, "public"))); + +const stateFile = path.join(__dirname, "state.json"); + +// Initialzustand laden oder erzeugen +function getState() { + if (!fs.existsSync(stateFile)) { + fs.writeFileSync(stateFile, JSON.stringify({ current: "A" }, null, 2)); + } + return JSON.parse(fs.readFileSync(stateFile)); +} + +function setState(newState) { + fs.writeFileSync(stateFile, JSON.stringify(newState, null, 2)); +} + +// GET: aktuellen Zustand +app.get("/status", (req, res) => { + res.json(getState()); +}); + +// POST: wechseln +app.post("/toggle", (req, res) => { + const state = getState(); + state.current = state.current === "A" ? "B" : "A"; + setState(state); + res.json(state); +}); + +// Start +const PORT = process.env.PORT || 3000; +app.listen(PORT, () => console.log(`Zahl-Schalter läuft auf Port ${PORT}`)); diff --git a/state.json b/state.json new file mode 100644 index 0000000..2f297ec --- /dev/null +++ b/state.json @@ -0,0 +1 @@ +{"current": "A"} \ No newline at end of file