Ukládání pizz do DB místo dočasného souboru
This commit is contained in:
parent
3f303ea5ea
commit
18cb172e06
@ -32,10 +32,6 @@ export const getFood = async () => {
|
|||||||
return await api.get<any>('/api/food');
|
return await api.get<any>('/api/food');
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getPizzy = async () => {
|
|
||||||
return await api.get<any>('/api/pizza');
|
|
||||||
}
|
|
||||||
|
|
||||||
export const createPizzaDay = async () => {
|
export const createPizzaDay = async () => {
|
||||||
return await api.post<any, any>('/api/createPizzaDay', undefined);
|
return await api.post<any, any>('/api/createPizzaDay', undefined);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import { EVENT_DISCONNECT, EVENT_MESSAGE, SocketContext } from './context/socket';
|
import { EVENT_DISCONNECT, EVENT_MESSAGE, SocketContext } from './context/socket';
|
||||||
import { addChoice, addPizza, changeDepartureTime, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getPizzy, getQrUrl, lockPizzaDay, removeChoice, removeChoices, removePizza, unlockPizzaDay, updateNote } from './Api';
|
import { addChoice, addPizza, changeDepartureTime, createPizzaDay, deletePizzaDay, finishDelivery, finishOrder, getData, getFood, getQrUrl, lockPizzaDay, removeChoice, removeChoices, removePizza, unlockPizzaDay, updateNote } from './Api';
|
||||||
import { useAuth } from './context/auth';
|
import { useAuth } from './context/auth';
|
||||||
import Login from './Login';
|
import Login from './Login';
|
||||||
import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap';
|
import { Alert, Button, Col, Form, Row, Table } from 'react-bootstrap';
|
||||||
@ -14,7 +14,7 @@ import './App.css';
|
|||||||
import { SelectSearchOption } from 'react-select-search';
|
import { SelectSearchOption } from 'react-select-search';
|
||||||
import { faCircleCheck, faTrashCan } from '@fortawesome/free-regular-svg-icons';
|
import { faCircleCheck, faTrashCan } from '@fortawesome/free-regular-svg-icons';
|
||||||
import { useBank } from './context/bank';
|
import { useBank } from './context/bank';
|
||||||
import { ClientData, Restaurants, Food, Pizza, Order, Locations, PizzaOrder, PizzaDayState, FoodChoices } from './types';
|
import { ClientData, Restaurants, Food, Order, Locations, PizzaOrder, PizzaDayState, FoodChoices } from './types';
|
||||||
import Footer from './components/Footer';
|
import Footer from './components/Footer';
|
||||||
|
|
||||||
const EVENT_CONNECT = "connect"
|
const EVENT_CONNECT = "connect"
|
||||||
@ -42,7 +42,6 @@ function App() {
|
|||||||
const [isConnected, setIsConnected] = useState<boolean>(false);
|
const [isConnected, setIsConnected] = useState<boolean>(false);
|
||||||
const [data, setData] = useState<ClientData>();
|
const [data, setData] = useState<ClientData>();
|
||||||
const [food, setFood] = useState<{ [key in Restaurants]: Food[] }>();
|
const [food, setFood] = useState<{ [key in Restaurants]: Food[] }>();
|
||||||
const [pizzy, setPizzy] = useState<Pizza[]>();
|
|
||||||
const [myOrder, setMyOrder] = useState<Order>();
|
const [myOrder, setMyOrder] = useState<Order>();
|
||||||
const [foodChoiceList, setFoodChoiceList] = useState<Food[]>();
|
const [foodChoiceList, setFoodChoiceList] = useState<Food[]>();
|
||||||
const socket = useContext(SocketContext);
|
const socket = useContext(SocketContext);
|
||||||
@ -55,9 +54,6 @@ function App() {
|
|||||||
if (!auth || !auth.login) {
|
if (!auth || !auth.login) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
getPizzy().then(pizzy => {
|
|
||||||
setPizzy(pizzy);
|
|
||||||
});
|
|
||||||
getData().then(data => {
|
getData().then(data => {
|
||||||
setData(data);
|
setData(data);
|
||||||
})
|
})
|
||||||
@ -174,11 +170,11 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const pizzaSuggestions = useMemo(() => {
|
const pizzaSuggestions = useMemo(() => {
|
||||||
if (!pizzy) {
|
if (!data?.pizzaList) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const suggestions: SelectSearchOption[] = [];
|
const suggestions: SelectSearchOption[] = [];
|
||||||
pizzy.forEach((pizza, index) => {
|
data.pizzaList.forEach((pizza, index) => {
|
||||||
const group: SelectSearchOption = { name: pizza.name, type: "group", items: [] }
|
const group: SelectSearchOption = { name: pizza.name, type: "group", items: [] }
|
||||||
pizza.sizes.forEach((size, sizeIndex) => {
|
pizza.sizes.forEach((size, sizeIndex) => {
|
||||||
const name = `${size.size} (${size.price} Kč)`;
|
const name = `${size.size} (${size.price} Kč)`;
|
||||||
@ -188,10 +184,10 @@ function App() {
|
|||||||
suggestions.push(group);
|
suggestions.push(group);
|
||||||
})
|
})
|
||||||
return suggestions;
|
return suggestions;
|
||||||
}, [pizzy]);
|
}, [data?.pizzaList]);
|
||||||
|
|
||||||
const handlePizzaChange = async (value: SelectedOptionValue | SelectedOptionValue[]) => {
|
const handlePizzaChange = async (value: SelectedOptionValue | SelectedOptionValue[]) => {
|
||||||
if (auth?.login && pizzy) {
|
if (auth?.login && data?.pizzaList) {
|
||||||
if (!(typeof value === 'string')) {
|
if (!(typeof value === 'string')) {
|
||||||
throw Error('Nepodporovaný typ hodnoty');
|
throw Error('Nepodporovaný typ hodnoty');
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import os from 'os';
|
|
||||||
import path from 'path';
|
|
||||||
import fs from 'fs';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { load } from 'cheerio';
|
import { load } from 'cheerio';
|
||||||
import { formatDate } from './utils';
|
|
||||||
|
|
||||||
// TODO přesunout do types
|
// TODO přesunout do types
|
||||||
type PizzaSize = {
|
type PizzaSize = {
|
||||||
@ -40,7 +36,7 @@ const boxPrices: { [key: string]: number } = {
|
|||||||
/**
|
/**
|
||||||
* Stáhne a scrapne aktuální pizzy ze stránek Pizza Chefie.
|
* Stáhne a scrapne aktuální pizzy ze stránek Pizza Chefie.
|
||||||
*/
|
*/
|
||||||
const downloadPizzy = async () => {
|
export async function downloadPizzy(): Promise<Pizza[]> {
|
||||||
// Získáme seznam pizz
|
// Získáme seznam pizz
|
||||||
const html = await axios.get(pizzyUrl).then(res => res.data);
|
const html = await axios.get(pizzyUrl).then(res => res.data);
|
||||||
const $ = load(html);
|
const $ = load(html);
|
||||||
@ -81,26 +77,4 @@ const downloadPizzy = async () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vrátí pizzy z tempu, nebo čerstvě stažené, pokud v tempu nejsou.
|
|
||||||
*/
|
|
||||||
export const fetchPizzy = async (): Promise<Pizza[]> => {
|
|
||||||
const tmpDir = os.tmpdir();
|
|
||||||
const date_ob = new Date();
|
|
||||||
const dateStr = formatDate(date_ob);
|
|
||||||
const dataPath = path.join(tmpDir, `chefie-${dateStr}.json`);
|
|
||||||
|
|
||||||
if (fs.existsSync(dataPath)) {
|
|
||||||
console.log(`Soubor pro ${dataPath} již existuje, bude použit.`);
|
|
||||||
const rawdata = fs.readFileSync(dataPath);
|
|
||||||
return JSON.parse(rawdata.toString());
|
|
||||||
} else {
|
|
||||||
console.log(`Soubor pro ${dataPath} neexistuje, stahuji...`);
|
|
||||||
const pizzy = await downloadPizzy();
|
|
||||||
fs.writeFileSync(dataPath, JSON.stringify(pizzy));
|
|
||||||
console.log(`Zapsán ${dataPath}`);
|
|
||||||
return pizzy;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,15 +1,15 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import { Server } from "socket.io";
|
import { Server } from "socket.io";
|
||||||
import bodyParser from "body-parser";
|
import bodyParser from "body-parser";
|
||||||
import { fetchPizzy } from "./chefie";
|
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
import { addChoice, addPizzaOrder, createPizzaDay, deletePizzaDay, finishPizzaDelivery, finishPizzaOrder, getData, lockPizzaDay, removeChoice, removeChoices, removePizzaOrder, unlockPizzaDay, updateDepartureTime, updateNote } from "./service";
|
import { addChoice, addPizzaOrder, createPizzaDay, deletePizzaDay, finishPizzaDelivery, finishPizzaOrder, getData, getPizzaList, lockPizzaDay, removeChoice, removeChoices, removePizzaOrder, savePizzaList, unlockPizzaDay, updateDepartureTime, updateNote } from "./service";
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku } from "./restaurants";
|
import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku } from "./restaurants";
|
||||||
import { getQr } from "./qr";
|
import { getQr } from "./qr";
|
||||||
import { generateToken, getLogin, getTrusted, verify } from "./auth";
|
import { generateToken, getLogin, getTrusted, verify } from "./auth";
|
||||||
import { Locations, Restaurants } from "../../types";
|
import { Locations, Restaurants } from "../../types";
|
||||||
|
import { downloadPizzy } from "./chefie";
|
||||||
|
|
||||||
const ENVIRONMENT = process.env.NODE_ENV || 'production';
|
const ENVIRONMENT = process.env.NODE_ENV || 'production';
|
||||||
dotenv.config({ path: path.resolve(__dirname, `./.env.${ENVIRONMENT}`) });
|
dotenv.config({ path: path.resolve(__dirname, `./.env.${ENVIRONMENT}`) });
|
||||||
@ -121,13 +121,6 @@ app.get("/api/food", async (req, res) => {
|
|||||||
res.status(200).json(data);
|
res.status(200).json(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Vrátí seznam dostupných pizz. */
|
|
||||||
app.get("/api/pizza", async (req, res) => {
|
|
||||||
const pizzaList = await fetchPizzy();
|
|
||||||
// console.log("Výsledek", pizzaList);
|
|
||||||
res.status(200).json(pizzaList);
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Založí pizza day pro aktuální den, za předpokladu že dosud neexistuje. */
|
/** Založí pizza day pro aktuální den, za předpokladu že dosud neexistuje. */
|
||||||
app.post("/api/createPizzaDay", async (req, res) => {
|
app.post("/api/createPizzaDay", async (req, res) => {
|
||||||
const login = getLogin(parseToken(req));
|
const login = getLogin(parseToken(req));
|
||||||
@ -153,7 +146,11 @@ app.post("/api/addPizza", async (req, res) => {
|
|||||||
throw Error("Nebyl předán index velikosti pizzy");
|
throw Error("Nebyl předán index velikosti pizzy");
|
||||||
}
|
}
|
||||||
const pizzaSizeIndex = req.body.pizzaSizeIndex;
|
const pizzaSizeIndex = req.body.pizzaSizeIndex;
|
||||||
const pizzy = await fetchPizzy();
|
let pizzy = await getPizzaList();
|
||||||
|
if (!pizzy) {
|
||||||
|
pizzy = await downloadPizzy();
|
||||||
|
savePizzaList(pizzy);
|
||||||
|
}
|
||||||
if (!pizzy[pizzaIndex]) {
|
if (!pizzy[pizzaIndex]) {
|
||||||
throw Error("Neplatný index pizzy: " + pizzaIndex);
|
throw Error("Neplatný index pizzy: " + pizzaIndex);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,31 @@ export async function getData(): Promise<ClientData> {
|
|||||||
return await storage.getData(formatDate(getToday())) || getEmptyData();
|
return await storage.getData(formatDate(getToday())) || getEmptyData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vrátí seznam dostupných pizz pro dnešní den.
|
||||||
|
*/
|
||||||
|
export async function getPizzaList(): Promise<Pizza[] | undefined> {
|
||||||
|
await initIfNeeded();
|
||||||
|
const today = formatDate(getToday());
|
||||||
|
const clientData: ClientData = await storage.getData(today);
|
||||||
|
return Promise.resolve(clientData.pizzaList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uloží seznam dostupných pizz pro dnešní den.
|
||||||
|
*
|
||||||
|
* @param pizzaList seznam dostupných pizz
|
||||||
|
*/
|
||||||
|
export async function savePizzaList(pizzaList: Pizza[]): Promise<ClientData> {
|
||||||
|
await initIfNeeded();
|
||||||
|
const today = formatDate(getToday());
|
||||||
|
const clientData: ClientData = await storage.getData(today);
|
||||||
|
clientData.pizzaList = pizzaList;
|
||||||
|
clientData.pizzaListLastUpdate = new Date();
|
||||||
|
await storage.setData(today, clientData);
|
||||||
|
return clientData;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vytvoří pizza day pro aktuální den a vrátí data pro klienta.
|
* Vytvoří pizza day pro aktuální den a vrátí data pro klienta.
|
||||||
*/
|
*/
|
||||||
|
@ -72,6 +72,8 @@ export interface ClientData {
|
|||||||
isWeekend: boolean, // příznak, zda je dnes víkend
|
isWeekend: boolean, // příznak, zda je dnes víkend
|
||||||
choices: Choices, // seznam voleb
|
choices: Choices, // seznam voleb
|
||||||
pizzaDay?: PizzaDay, // pizza day pro dnešní den, pokud existuje
|
pizzaDay?: PizzaDay, // pizza day pro dnešní den, pokud existuje
|
||||||
|
pizzaList?: Pizza[], // seznam dostupných pizz pro dnešní den
|
||||||
|
pizzaListLastUpdate?: Date, // datum a čas poslední aktualizace pizz
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Jídlo z obědového menu restaurace. */
|
/** Jídlo z obědového menu restaurace. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user