final version?
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<div class="flex-container fill-height-medium-up">
|
||||
<div class="grow height-100 overflow-auto site-content">
|
||||
<div class="grow height-100 overflow-auto site-content hide-scrollbar">
|
||||
<h1>Gechenkliste</h1>
|
||||
<p>
|
||||
Ihr macht uns die größte Freude, wenn ihr mit uns feiert und den Tag verbringt. Wenn ihr uns gerne etwas
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</ul>
|
||||
<ul class="menu align-center-middle medium-horizontal hide-for-small-only">
|
||||
<li><img class="logo-img" src="img/logo.png" alt="J&S"></li>
|
||||
<li class="active" data-site="home" data-img="1"><a>Home</a></li>
|
||||
<li class="active" data-site="home" data-img-show-always="1"><a>Home</a></li>
|
||||
<li data-site="tagesablauf"><a>Tagesablauf</a></li>
|
||||
<li data-site="unterkunft"><a>Unterkunft</a></li>
|
||||
<li data-site="geschenke"><a>Geschenke</a></li>
|
||||
|
||||
@@ -1,20 +1,40 @@
|
||||
export class PresentsHandler {
|
||||
presents: {
|
||||
isBought: boolean,
|
||||
image: string,
|
||||
name: string,
|
||||
description: string
|
||||
link: string
|
||||
}[] = [];
|
||||
[id: number]: {
|
||||
id: number,
|
||||
version: number,
|
||||
isBought: boolean,
|
||||
image: string,
|
||||
name: string,
|
||||
description: string
|
||||
link: string
|
||||
}
|
||||
} = {};
|
||||
|
||||
// @ts-ignore
|
||||
private readonly basePath = __BASE_PATH__;
|
||||
|
||||
async loadPresents() {
|
||||
this.presents = require("./presents").default;
|
||||
const presents = require("./presents").default;
|
||||
presents.forEach(p => this.presents[p.id] = p);
|
||||
await this.updateStates();
|
||||
}
|
||||
|
||||
async updateStates() {
|
||||
//TODO vom server laden
|
||||
this.presents[3].isBought = true;
|
||||
const presentData: any[] = await fetch(this.basePath + "/presents", {
|
||||
"credentials": "same-origin",
|
||||
"method": "GET",
|
||||
}).then(function (res) {
|
||||
return res.json();
|
||||
});
|
||||
|
||||
presentData.forEach(data => {
|
||||
const present = this.presents[data.id];
|
||||
if (present){
|
||||
present.isBought = data.isBought === 1;
|
||||
present.version = data.version;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async showPresents() {
|
||||
@@ -26,8 +46,7 @@ export class PresentsHandler {
|
||||
await this.loadPresents();
|
||||
|
||||
presentContainer.innerText = "";
|
||||
console.log(this.presents);
|
||||
this.presents.forEach(present => {
|
||||
Object.values(this.presents).forEach(present => {
|
||||
const element = <HTMLLinkElement>presentTemplate.cloneNode(true);
|
||||
(<HTMLImageElement>element.querySelector(".present-image")).src = present.image;
|
||||
(<HTMLElement>element.querySelector(".present-name")).innerText = present.name;
|
||||
@@ -53,8 +72,56 @@ export class PresentsHandler {
|
||||
})
|
||||
}
|
||||
|
||||
private async setPresentIsBought(present: { isBought: boolean; image: string; name: string; description: string; link: string }, isBought: boolean) {
|
||||
//TODO auf Server updaten
|
||||
present.isBought = isBought;
|
||||
private async setPresentIsBought(present: { id: number, isBought: boolean; version: number, image: string; name: string; description: string; link: string }, isBought: boolean) {
|
||||
const url = this.basePath + "/presents"
|
||||
|
||||
const params = {
|
||||
id: present.id,
|
||||
version: present.version,
|
||||
isBought: isBought
|
||||
}
|
||||
|
||||
const res = await this.send(url, params);
|
||||
|
||||
console.log("result", res);
|
||||
|
||||
if (res.present && res.present.id === present.id) {
|
||||
present.version = res.present.version;
|
||||
present.isBought = res.present.isBought === 1
|
||||
}
|
||||
|
||||
if (res.success === false) {
|
||||
if (res.error === "wrong-version") {
|
||||
alert("Jemand hat schon vor dir das Geschenk bearbeitet. Bitte versuche es erneut.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async send(url, params) {
|
||||
let headers = {};
|
||||
if (!(params instanceof FormData) && typeof params === "object") {
|
||||
params = JSON.stringify(params);
|
||||
headers = {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
|
||||
return fetch(url, {
|
||||
"credentials": "same-origin",
|
||||
"method": "POST",
|
||||
"headers": headers,
|
||||
"body": params,
|
||||
}).then(function (res) {
|
||||
return res.json();
|
||||
}).catch(function (e) {
|
||||
debugger;
|
||||
console.error("error", e);
|
||||
return {
|
||||
"success": false,
|
||||
"errors": [
|
||||
"not-online"
|
||||
]
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@ const images = {
|
||||
geschenke: require("../img/geschenke.jpg").default,
|
||||
}
|
||||
|
||||
|
||||
const callbacks = {
|
||||
home: () => {
|
||||
},
|
||||
@@ -54,6 +53,7 @@ const callbacks = {
|
||||
|
||||
const navBar = document.querySelector(".top-bar");
|
||||
const anchors = document.querySelectorAll(".anchor");
|
||||
|
||||
const margin = navBar.clientHeight + 50;
|
||||
|
||||
const observerDown = new IntersectionObserver(entries => {
|
||||
@@ -63,7 +63,6 @@ const callbacks = {
|
||||
}
|
||||
});
|
||||
}, {threshold: 1, rootMargin: "-" + margin + "px 0px 0px 0px"});
|
||||
// }, {threshold: 1, rootMargin: "-100px 0px 0px 0px"});
|
||||
const observerUp = new IntersectionObserver(entries => {
|
||||
entries.some(entry => {
|
||||
if (entry.isIntersecting && entry.intersectionRect.top === navBar.clientHeight && !scrollToView) {
|
||||
@@ -95,7 +94,6 @@ $(document).foundation();
|
||||
$(function () {
|
||||
const container = document.getElementById("main-content");
|
||||
const img = document.getElementById("home-img-container");
|
||||
const navbar = document.getElementById("main-menu");
|
||||
|
||||
let currentSite = "home";
|
||||
|
||||
@@ -130,4 +128,10 @@ $(function () {
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
document.querySelectorAll(".logo-img").forEach(img => {
|
||||
img.addEventListener("click", () => {
|
||||
document.querySelector("li[data-site='home']").dispatchEvent(new Event("click"));
|
||||
})
|
||||
})
|
||||
});
|
||||
@@ -1,49 +1,65 @@
|
||||
export default [{
|
||||
id: 1,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/test.jpg").default,
|
||||
name: "Akku-Bohrer",
|
||||
description: "Der von BOSCH, weil ich den schon immer mal haben wollte",
|
||||
link: "http://www.onlinewahn.de/ende.htm",
|
||||
version: 0,
|
||||
}, {
|
||||
isBought: true,
|
||||
id: 2,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/test.jpg").default,
|
||||
name: "Windows",
|
||||
description: "Bisher konnte ich es mir nicht leisten und musste immer auf eine Web-Version zurückgreifen",
|
||||
link: "https://www.windows93.net/",
|
||||
version: 0,
|
||||
},{
|
||||
id: 3,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/test.jpg").default,
|
||||
name: "Akku-Bohrer",
|
||||
description: "Der von BOSCH, weil ich den schon immer mal haben wollte",
|
||||
link: "http://www.onlinewahn.de/ende.htm",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 4,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/test.jpg").default,
|
||||
name: "Windows",
|
||||
description: "Bisher konnte ich es mir nicht leisten und musste immer auf eine Web-Version zurückgreifen",
|
||||
link: "https://www.windows93.net/",
|
||||
version: 0,
|
||||
},{
|
||||
id: 5,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/test.jpg").default,
|
||||
name: "Akku-Bohrer",
|
||||
description: "Der von BOSCH, weil ich den schon immer mal haben wollte",
|
||||
link: "http://www.onlinewahn.de/ende.htm",
|
||||
version: 0,
|
||||
}, {
|
||||
id:6,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/test.jpg").default,
|
||||
name: "Windows",
|
||||
description: "Bisher konnte ich es mir nicht leisten und musste immer auf eine Web-Version zurückgreifen",
|
||||
link: "https://www.windows93.net/",
|
||||
version: 0,
|
||||
},{
|
||||
id:7,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/test.jpg").default,
|
||||
name: "Akku-Bohrer",
|
||||
description: "Der von BOSCH, weil ich den schon immer mal haben wollte",
|
||||
link: "http://www.onlinewahn.de/ende.htm",
|
||||
version: 0,
|
||||
}, {
|
||||
id: 8,
|
||||
isBought: false,
|
||||
image: require("../img/geschenke/test.jpg").default,
|
||||
name: "Windows",
|
||||
description: "Bisher konnte ich es mir nicht leisten und musste immer auf eine Web-Version zurückgreifen",
|
||||
link: "https://www.windows93.net/",
|
||||
version: 0,
|
||||
},]
|
||||
@@ -4,7 +4,7 @@
|
||||
background: white;
|
||||
padding: 0;
|
||||
|
||||
.grid-container{
|
||||
.grid-container {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@@ -13,47 +13,81 @@
|
||||
display: flex;
|
||||
|
||||
li {
|
||||
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
height: 5rem;
|
||||
padding-top: 0.9rem;
|
||||
height: 3rem;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
|
||||
@include breakpoint(large){
|
||||
padding-top: 0.5rem;
|
||||
&:first-child {
|
||||
flex: initial;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
@include breakpoint(large) {
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: black;
|
||||
font-family: "Bahnschrift", Helvetica, Arial, serif;
|
||||
font-size: 1.4rem;
|
||||
@include breakpoint(large){
|
||||
font-size: 2rem;
|
||||
font-size: 1.3rem;
|
||||
padding: 0.3rem;
|
||||
@include breakpoint(large) {
|
||||
padding: 0.7rem 1rem;
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: $background-color;
|
||||
background: white;
|
||||
|
||||
> a {
|
||||
background: $background-color;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
//background: red;
|
||||
background-image: url("../img/einkreiser.png");
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.active::after {
|
||||
display: initial;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.logo-img {
|
||||
height: 3rem;
|
||||
@include breakpoint(large){
|
||||
height: 4rem;
|
||||
cursor: pointer;
|
||||
height: 2rem;
|
||||
@include breakpoint(large) {
|
||||
height: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.responsive-menu{
|
||||
&.responsive-menu {
|
||||
position: absolute;
|
||||
right:0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
box-shadow: 0 0 5px $background-color;
|
||||
.menu-closer{
|
||||
|
||||
.menu-closer {
|
||||
z-index: -1;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -70,23 +104,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
$menuIconHeight : 2rem;
|
||||
.title-bar{
|
||||
$menuIconHeight: 2rem;
|
||||
.title-bar {
|
||||
background: $background-color;
|
||||
text-align: right;
|
||||
//justify-content: flex-end;
|
||||
display: block;
|
||||
.menu-icon{
|
||||
|
||||
.menu-icon {
|
||||
width: $menuIconHeight;
|
||||
height: $menuIconHeight;
|
||||
outline: none;
|
||||
&::after{
|
||||
|
||||
&::after {
|
||||
background: #fefefe;
|
||||
height: #{($menuIconHeight/9)};
|
||||
box-shadow: 0 #{($menuIconHeight/3)} 0 #fefefe, 0 #{($menuIconHeight*2/3)} 0 #fefefe;
|
||||
}
|
||||
}
|
||||
.logo-img{
|
||||
|
||||
.logo-img {
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
height: $menuIconHeight;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,12 @@ $states: godi fingerfood foto sekt essen spiel dance;
|
||||
|
||||
&.show-in-dialog {
|
||||
position: fixed;
|
||||
|
||||
}
|
||||
&:last-child{
|
||||
height: calc(100vh - 8rem - 1px);
|
||||
@include breakpoint(medium down) {
|
||||
height: calc(100vh - 7rem - 1px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +118,7 @@ $states: godi fingerfood foto sekt essen spiel dance;
|
||||
overflow: auto;
|
||||
padding: 2rem 1rem;
|
||||
background: $background-color;
|
||||
height: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,13 @@
|
||||
src: url("../img/WinterSunrise.ttf");
|
||||
}
|
||||
|
||||
@mixin fullHeight{
|
||||
height: calc(100vh - 4rem);
|
||||
@include breakpoint(medium down) {
|
||||
height: calc(100vh - 3rem);
|
||||
}
|
||||
}
|
||||
|
||||
.width-100 {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -39,10 +46,7 @@ body {
|
||||
height: 100%;
|
||||
|
||||
#main-content-container {
|
||||
height: calc(100% - 5rem);
|
||||
@include breakpoint(small only) {
|
||||
height: calc(100% - 3rem);
|
||||
}
|
||||
@include fullHeight;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
|
||||
@@ -103,10 +107,7 @@ h1 {
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: calc(100% - 5rem);
|
||||
@include breakpoint(small only) {
|
||||
height: calc(100% - 3rem);
|
||||
}
|
||||
@include fullHeight;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
@@ -151,15 +152,15 @@ img.full-screen-width {
|
||||
}
|
||||
|
||||
.fill-height {
|
||||
height: calc(100vh - 5rem);
|
||||
@include breakpoint(small only) {
|
||||
height: calc(100vh - 3rem);
|
||||
}
|
||||
@include fullHeight;
|
||||
}
|
||||
|
||||
.fill-height-medium-up {
|
||||
@include breakpoint(medium) {
|
||||
height: calc(100vh - 5rem);
|
||||
height: calc(100vh - 3rem);
|
||||
@include breakpoint(large){
|
||||
height: calc(100vh - 4rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,4 +170,16 @@ img.full-screen-width {
|
||||
img {
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.padding-bottom-0 {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.hide-scrollbar{
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
import * as express from "express";
|
||||
import {createServer, Server as HTTPServer} from "http";
|
||||
import * as path from "path";
|
||||
import * as mysql from "mysql";
|
||||
|
||||
export class Server {
|
||||
private httpServer: HTTPServer;
|
||||
private app: express.Application;
|
||||
private mysqlConnection;
|
||||
// private io: socketIO.Server;
|
||||
|
||||
// private activeSockets: string[] = [];
|
||||
@@ -13,20 +15,39 @@ export class Server {
|
||||
private readonly DEFAULT_PORT = parseInt(process.env.PORT) || 5000;
|
||||
|
||||
constructor() {
|
||||
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
private initialize(): void {
|
||||
this.app = express();
|
||||
this.httpServer = createServer(this.app);
|
||||
// this.io = socketIO(this.httpServer);
|
||||
this.mysqlConnection = mysql.createConnection({
|
||||
host: process.env.MYSQL_HOST || "localhost",
|
||||
user: process.env.MYSQL_USER || "root",
|
||||
password: process.env.MYSQL_PASSWORD || "",
|
||||
database: process.env.MYSQL_DATABASE || "hochzeit"
|
||||
});
|
||||
|
||||
this.configureApp();
|
||||
this.configureRoutes();
|
||||
// this.handleSocketConnection();
|
||||
}
|
||||
|
||||
private async query(sql): Promise<any[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.mysqlConnection.query(sql, (error, results) => {
|
||||
if (error) {
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(results);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
private configureApp(): void {
|
||||
this.app.use(express.json({limit: "1mb"}));
|
||||
this.app.use(express.static(path.join(__dirname, "../../dist")));
|
||||
}
|
||||
|
||||
@@ -34,98 +55,29 @@ export class Server {
|
||||
this.app.get("/", (req, res) => {
|
||||
res.sendFile("index.html");
|
||||
});
|
||||
}
|
||||
this.app.get("/presents", async (req, res) => {
|
||||
res.json(await this.query("SELECT * FROM presents"));
|
||||
})
|
||||
this.app.post("/presents", async (req, res) => {
|
||||
const id = parseInt(req.body.id);
|
||||
const isBought = (req.body.isBought === true)?1:0;
|
||||
const version = parseInt(req.body.version) || 0;
|
||||
const newVersion = version + 1;
|
||||
|
||||
// private handleSocketConnection(): void {
|
||||
// let webserverSocket = null;
|
||||
// this.io.on("connection", socket => {
|
||||
// console.log("new client", new Date());
|
||||
// const existingSocket = this.activeSockets.find(
|
||||
// existingSocket => existingSocket === socket.id
|
||||
// );
|
||||
//
|
||||
// if (!existingSocket) {
|
||||
// this.activeSockets.push(socket.id);
|
||||
//
|
||||
// socket.emit("update-user-list", {
|
||||
// users: this.activeSockets.filter(
|
||||
// existingSocket => existingSocket !== socket.id
|
||||
// )
|
||||
// });
|
||||
//
|
||||
// socket.broadcast.emit("update-user-list", {
|
||||
// users: [socket.id]
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// socket.on("message", (data: any) => {
|
||||
// console.log(new Date(), data.to, data.message.type);
|
||||
// if (data.message.type === undefined){
|
||||
// console.log(new Date(), data.message);
|
||||
// }
|
||||
// if (data.to) {
|
||||
// socket.to(data.to).emit("message", data);
|
||||
// } else if (webserverSocket) {
|
||||
// data.from = socket.id;
|
||||
// webserverSocket.emit("message", data)
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// socket.on("set-webserver", () => {
|
||||
// if (webserverSocket === null) {
|
||||
// console.log("setting webserver", new Date())
|
||||
// webserverSocket = socket;
|
||||
//
|
||||
// this.activeSockets.forEach(s => {
|
||||
// if (s !== socket.id){
|
||||
// socket.to(s).emit("ready");
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// })
|
||||
//
|
||||
// if (webserverSocket){
|
||||
// socket.emit("ready");
|
||||
// }
|
||||
// // socket.on("request-offer", () => {
|
||||
// // if (webserverSocket) {
|
||||
// // webserverSocket.emit("request-offer", {socket: socket.id})
|
||||
// // }
|
||||
// // });
|
||||
// //
|
||||
// // socket.on("answer", data => {
|
||||
// // console.log("got answer", data.answer);
|
||||
// // socket.to(data.to).emit("answer", data.answer);
|
||||
// // });
|
||||
// //
|
||||
// // socket.on("send-answer", data => {
|
||||
// // if (webserverSocket) {
|
||||
// // addMessage(socket.id, JSON.parse(data));
|
||||
// // webserverSocket.emit("send-answer", data)
|
||||
// // }
|
||||
// // });
|
||||
// //
|
||||
// // socket.on("send-ice-candidate", data => {
|
||||
// // if (socket.to(data.to)){
|
||||
// // addMessage(socket.id, data.candidate);
|
||||
// // socket.to(data.to).emit("ice-candidate", data.candidate)
|
||||
// // }
|
||||
// // });
|
||||
//
|
||||
// socket.on("disconnect", () => {
|
||||
// console.log("losing client", new Date())
|
||||
// this.activeSockets = this.activeSockets.filter(
|
||||
// existingSocket => existingSocket !== socket.id
|
||||
// );
|
||||
// socket.broadcast.emit("remove-user", {
|
||||
// socketId: socket.id
|
||||
// });
|
||||
// if (socket === webserverSocket){
|
||||
// webserverSocket = null;
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
const presents = await this.query("SELECT * FROM presents WHERE id = '" + id + "'");
|
||||
if (presents.length === 0) {
|
||||
await this.query("INSERT INTO presents (id, isBought, version) VALUES (" + id + ", " + isBought + ", " + newVersion + ");");
|
||||
} else {
|
||||
const present = presents[0];
|
||||
if (present.version === version) {
|
||||
await this.query("UPDATE presents SET version = " + newVersion + ", isBought = " + isBought + " WHERE ID = " + id);
|
||||
} else {
|
||||
return res.json({"success": false, "error": "wrong-version", present: present});
|
||||
}
|
||||
}
|
||||
return res.json({"success": true, present: {id: id, isBought: isBought, version: newVersion}})
|
||||
})
|
||||
}
|
||||
|
||||
public listen(callback: (port: number) => void): void {
|
||||
this.httpServer.listen(this.DEFAULT_PORT, () => {
|
||||
|
||||
Reference in New Issue
Block a user