Prvotní nástřel fungující aplikace
This commit is contained in:
@@ -6,7 +6,7 @@ import fs from 'fs';
|
||||
|
||||
type PizzaSize = {
|
||||
size: string,
|
||||
pizzaPrice: string,
|
||||
pizzaPrice: number,
|
||||
boxPrice: number,
|
||||
price: number
|
||||
}
|
||||
@@ -21,12 +21,15 @@ type Pizza = {
|
||||
const baseUrl = 'https://www.pizzachefie.cz';
|
||||
const pizzyUrl = `${baseUrl}/pizzy.html?pobocka=plzen`;
|
||||
|
||||
// URL na Food API - získání jídelních lístků restaurací
|
||||
const foodUrl = process.env.FOOD_API_URL || 'http://localhost:3002';
|
||||
|
||||
const buildPizzaUrl = (pizzaUrl: string) => {
|
||||
return `${baseUrl}/${pizzaUrl}`;
|
||||
}
|
||||
|
||||
// Ceny krabic dle velikosti
|
||||
const boxPrices = {
|
||||
const boxPrices: { [key: string]: number } = {
|
||||
"30cm": 13,
|
||||
"35cm": 15,
|
||||
"40cm": 18,
|
||||
@@ -55,19 +58,20 @@ const downloadPizzy = async () => {
|
||||
// Název
|
||||
const name = $('.produkt > h2', pizzaHtml).first().text()
|
||||
// Přísady
|
||||
const ingredients = []
|
||||
const ingredients: string[] = []
|
||||
const ingredientsHtml = $('.prisady > li', pizzaHtml);
|
||||
ingredientsHtml.each((i, elm) => {
|
||||
ingredients.push($(elm).text());
|
||||
})
|
||||
// Velikosti
|
||||
const sizes = [];
|
||||
const sizes: PizzaSize[] = [];
|
||||
const a = $('.varianty > li > a', pizzaHtml);
|
||||
a.each((i, elm) => {
|
||||
const size = $('span', elm).text();
|
||||
const priceKc = $(elm).text().split(size).pop().trim();
|
||||
const price = Number.parseInt(priceKc.split(" Kč")[0]);
|
||||
sizes.push({ size: size, pizzaPrice: price, boxPrice: boxPrices[size], price: price + boxPrices[size] });
|
||||
// TODO nedoděláno
|
||||
// const size = $('span', elm).text();
|
||||
// const priceKc = $(elm).text().split(size).pop().trim();
|
||||
// const price = Number.parseInt(priceKc.split(" Kč")[0]);
|
||||
// sizes.push({ size: size, pizzaPrice: price, boxPrice: boxPrices[size], price: price + boxPrices[size] });
|
||||
})
|
||||
result.push({
|
||||
name: name,
|
||||
@@ -101,6 +105,15 @@ export const fetchPizzy = async () => {
|
||||
console.log(`Zapsán ${dataPath}`);
|
||||
return pizzy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO tohle sem absolutně nepatří! dát do vlastní servisky!
|
||||
export const fetchFood = async () => {
|
||||
try {
|
||||
const json = await rp(foodUrl);
|
||||
return JSON.parse(json);
|
||||
} catch (error) {
|
||||
console.error("Chyba při volání Food API", error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
3
server/src/database.ts
Normal file
3
server/src/database.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import JSONdb from 'simple-json-db';
|
||||
|
||||
export const db = new JSONdb('./data.json');
|
||||
@@ -1,7 +1,9 @@
|
||||
import express from "express";
|
||||
import { Server } from "socket.io";
|
||||
import bodyParser from "body-parser";
|
||||
import { fetchPizzy } from "./chefie";
|
||||
import { fetchFood, fetchPizzy } from "./chefie";
|
||||
import cors from 'cors';
|
||||
import { getData, updateChoice } from "./service";
|
||||
|
||||
const app = express();
|
||||
const server = require("http").createServer(app);
|
||||
@@ -13,12 +15,25 @@ const io = new Server(server, {
|
||||
|
||||
// Body-parser middleware for parsing JSON
|
||||
app.use(bodyParser.json());
|
||||
// app.use(express.json());
|
||||
|
||||
const cors = require('cors');
|
||||
app.use(cors({
|
||||
origin: '*'
|
||||
}));
|
||||
|
||||
/** Vrátí data pro aktuální den. */
|
||||
app.get("/api/data", (req, res) => {
|
||||
res.status(200).json(getData());
|
||||
});
|
||||
|
||||
/** Vrátí obědové menu pro dostupné podniky. */
|
||||
app.get("/api/food", (req, res) => {
|
||||
fetchFood().then(food => {
|
||||
res.status(200).json(food);
|
||||
})
|
||||
});
|
||||
|
||||
/** Vrátí seznam dostupných pizz. */
|
||||
app.get("/api/pizza", (req, res) => {
|
||||
fetchPizzy().then(pizzaList => {
|
||||
console.log("Výsledek", pizzaList);
|
||||
@@ -26,6 +41,30 @@ app.get("/api/pizza", (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// /** Založí pizza day pro aktuální den, za předpokladu že dosud neexistuje. */
|
||||
// app.post("/api/createPizzaDay", (req, res) => {
|
||||
// const data = createPizzaDay();
|
||||
// res.status(200).json(data);
|
||||
// io.emit("message", data);
|
||||
// });
|
||||
|
||||
// /** Smaže pizza day pro aktuální den, za předpokladu že existuje. */
|
||||
// app.post("/api/deletePizzaDay", (req, res) => {
|
||||
// deletePizzaDay();
|
||||
// io.emit("message", getData());
|
||||
// });
|
||||
|
||||
app.post("/api/updateChoice", (req, res) => {
|
||||
console.log("Změna výběru", req.body);
|
||||
if (!req.body.hasOwnProperty('name')) {
|
||||
res.status(400).json({});
|
||||
}
|
||||
const data = updateChoice(req.body.name, req.body.choice);
|
||||
io.emit("message", data);
|
||||
res.status(200).json(data);
|
||||
});
|
||||
|
||||
// TODO smazat
|
||||
app.post("/api/zprava", (req, res) => {
|
||||
const { username, message } = req.body;
|
||||
|
||||
@@ -49,6 +88,7 @@ io.on("connection", (socket) => {
|
||||
io.emit("message", message);
|
||||
});
|
||||
|
||||
// TODO smazat
|
||||
socket.on("jduKafe", ({ username, timeString }) => {
|
||||
console.log(`Received message: ${username}`);
|
||||
socket.broadcast.emit("jduKafe", `${timeString}: ${username} -> jdu Kafe`);
|
||||
@@ -60,7 +100,8 @@ io.on("connection", (socket) => {
|
||||
});
|
||||
|
||||
const PORT = process.env.PORT || 3001;
|
||||
const HOST = process.env.HOST || '0.0.0.0';
|
||||
|
||||
server.listen(PORT, () => {
|
||||
console.log(`Server listening on port ${PORT}`);
|
||||
console.log(`Server listening on ${HOST}, port ${PORT}`);
|
||||
});
|
||||
105
server/src/service.ts
Normal file
105
server/src/service.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { ClientData, Locations } from "./types";
|
||||
import { db } from "./database";
|
||||
import { getTodayString } from "./utils";
|
||||
import { getDate } from "./utils";
|
||||
|
||||
// /** Jedna konkrétní pizza */
|
||||
// interface Pizza {
|
||||
// name: string, // název pizzy
|
||||
// size: number, // velikost pizzy v cm
|
||||
// price: number, // cena pizzy v Kč, včetně krabice
|
||||
// }
|
||||
|
||||
// /** Objednávka jednoho člověka */
|
||||
// interface Order {
|
||||
// customer: string, // název člověka
|
||||
// pizzaList: Pizza[], // seznam objednaných pizz
|
||||
// totalPrice: number, // celková cena všech objednaných pizz a krabic
|
||||
// }
|
||||
|
||||
// /** Stav pizza dne. */
|
||||
// enum State {
|
||||
// NOT_CREATED, // Pizza day nebyl založen
|
||||
// CREATED, // Pizza day je založen
|
||||
// LOCKED // Objednávky uzamčeny
|
||||
// }
|
||||
|
||||
// /** Veškerá data pro zobrazení na klientovi */
|
||||
// interface ClientData {
|
||||
// date: string, // dnešní datum pro zobrazení
|
||||
// state: State, // stav pizza dne
|
||||
// orders?: Order[], // seznam objednávek, pokud není vyplněno, není založen pizza day
|
||||
// }
|
||||
|
||||
/** Vrátí "prázdná" (implicitní) data, pokud ještě nikdo nehlasoval. */
|
||||
function getEmptyData(): ClientData {
|
||||
return { date: getTodayString(), choices: {} };
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrátí veškerá klientská data pro aktuální den.
|
||||
*/
|
||||
export function getData(): ClientData {
|
||||
const data = db.get(getDate()) || getEmptyData();
|
||||
console.log("Vracím data pro dnešní den", data); // TODO smazat
|
||||
return data;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Vytvoří pizza day pro aktuální den a vrátí data pro klienta.
|
||||
// */
|
||||
// export function createPizzaDay(): ClientData {
|
||||
// const today = getDate();
|
||||
// if (db.has(today)) {
|
||||
// throw Error("Pizza day pro dnešní den již existuje");
|
||||
// }
|
||||
// const data = { date: getTodayString(), state: State.CREATED, orders: [] };
|
||||
// db.set(today, data);
|
||||
// return data;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Smaže pizza day pro aktuální den.
|
||||
// */
|
||||
// export function deletePizzaDay() {
|
||||
// const today = getDate();
|
||||
// if (!db.has(today)) {
|
||||
// throw Error("Pizza day pro dnešní den neexistuje");
|
||||
// }
|
||||
// db.delete(today);
|
||||
// }
|
||||
|
||||
export function initIfNeeded() {
|
||||
const today = getDate();
|
||||
if (!db.has(today)) {
|
||||
db.set(today, getEmptyData());
|
||||
}
|
||||
}
|
||||
|
||||
export function removeChoice(login: string, data: ClientData) {
|
||||
for (let key of Object.keys(data.choices)) {
|
||||
if (data.choices[key] && data.choices[key].includes(login)) {
|
||||
const index = data.choices[key].indexOf(login);
|
||||
data.choices[key].splice(index, 1);
|
||||
if (data.choices[key].length == 0) {
|
||||
delete data.choices[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
export function updateChoice(login: string, choice: Locations | null) {
|
||||
initIfNeeded();
|
||||
const today = getDate();
|
||||
let data: ClientData = db.get(today);
|
||||
data = removeChoice(login, data);
|
||||
if (choice !== null) {
|
||||
if (!data.choices?.[choice]) {
|
||||
data.choices[choice] = [];
|
||||
}
|
||||
data.choices[choice].push(login);
|
||||
}
|
||||
db.set(today, data);
|
||||
return data;
|
||||
}
|
||||
18
server/src/types.ts
Normal file
18
server/src/types.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
export interface Choices {
|
||||
[location: string]: string[],
|
||||
}
|
||||
|
||||
export interface ClientData {
|
||||
date: string, // dnešní datum pro zobrazení
|
||||
choices: Choices, // seznam voleb
|
||||
}
|
||||
|
||||
export enum Locations {
|
||||
SLADOVNICKA = 'Sladovnická',
|
||||
UMOTLIKU = 'U Motlíků',
|
||||
TECHTOWER = 'TechTower',
|
||||
SPSE = 'SPŠE',
|
||||
VLASTNI = 'Mám vlastní',
|
||||
OBJEDNAVAM = 'Objednávám',
|
||||
NEOBEDVAM = 'Neobědvám',
|
||||
}
|
||||
17
server/src/utils.ts
Normal file
17
server/src/utils.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
export function getDate() {
|
||||
const date = new Date();
|
||||
let currentDay = String(date.getDate()).padStart(2, '0');
|
||||
let currentMonth = String(date.getMonth() + 1).padStart(2, "0");
|
||||
let currentYear = date.getFullYear();
|
||||
return `${currentYear}-${currentMonth}-${currentDay}`;
|
||||
}
|
||||
|
||||
/** Vrátí human-readable reprezentaci dnešního data pro zobrazení. */
|
||||
export function getTodayString() {
|
||||
const date = new Date();
|
||||
let currentDay = String(date.getDate()).padStart(2, '0');
|
||||
let currentMonth = String(date.getMonth() + 1).padStart(2, "0");
|
||||
let currentYear = date.getFullYear();
|
||||
let currentDayOfWeek = date.toLocaleDateString("CZ-cs", { weekday: 'long' });
|
||||
return `${currentDay}.${currentMonth}.${currentYear} (${currentDayOfWeek})`;
|
||||
}
|
||||
Reference in New Issue
Block a user