first online Version

This commit is contained in:
Thomas Mack 2018-12-30 19:35:10 +01:00
parent 77c1c089d5
commit eceff163a9
16 changed files with 4213 additions and 257 deletions

2
app.js
View File

@ -2,6 +2,7 @@ var createError = require('http-errors');
var express = require('express');
var path = require('path');
var logger = require('morgan');
var cors = require('cors');
var sassMiddleware = require('node-sass-middleware');
const db = require('./db')
@ -20,6 +21,7 @@ var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

90
bin/www
View File

@ -1,90 +0,0 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('myrezeptapp:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}

View File

@ -63,7 +63,7 @@ const dataStructure = {
}
const selectAllFromTable = (table) => {
return "SELECT * FROM "+table+";";
return "SELECT * FROM "+table+" order by name;";
}
const selectAllFromTableByFieldValue = (table, field, value) => {
@ -84,7 +84,7 @@ const deleteNameKeyObject = function(req, res, next) {
let obj = req.body[structure.jsonName][0];
let query = "DELETE FROM "+structure.tableName+
" WHERE id = "+req.itemId;
query(query, (err, rs) => {
pool.query(query, (err, rs) => {
if(err) {
console.log(query);
next(err)
@ -105,7 +105,7 @@ const updateNameKeyObject = function(req, res, next) {
"', name = '"+obj.name+
"', beschreibung = '"+obj.beschreibung+
"' WHERE id = "+req.itemId+" returning *";
query(query, (err, rs) => {
pool.query(query, (err, rs) => {
if(err) {
console.log(query);
next(err)
@ -127,7 +127,7 @@ const insertNameKeyObject = function(req, res, next) {
" VALUES ('"+obj.schluessel+"','"+obj.name+"','"+obj.beschreibung+"')" +
" returning *";
if(DEBUG) console.log(query);
query(query, (err, rs) => {
pool.query(query, (err, rs) => {
if(err) {
console.log(query);
next(err)
@ -156,7 +156,7 @@ const getAllFromTable = function(req, res, next) {
console.log(structure);
}
if(structure === undefined) return res.status(404).send();
query(selectAllFromTable(structure.tableName), (err, rs) => {
pool.query(selectAllFromTable(structure.tableName), (err, rs) => {
if(err) next(err)
else {
if(DEBUG) console.log(res);

3953
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
{
"name": "bidatCookbook",
"name": "schmeckWieDaheim-API",
"version": "0.5.0",
"description": "Cookbook app for Families to share their recipies",
"main": "app.js",
@ -23,6 +23,16 @@
"rand-token": "^0.4.0",
"react": "^16.7.0",
"react-dom": "^15.6.1",
"react-router-dom": "^4.2.2"
"react-router-dom": "^4.2.2",
"whatwg-fetch": "^3.0.0"
},
"devDependencies": {
"babel": "^6.23.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"webpack": "^3.5.5"
}
}

View File

@ -7,6 +7,7 @@ const randToken = require('rand-token');
const ingredientsRouter = require('./recepieIngredients');
const toolsRouter = require('./recepieTools');
const durationsRouter = require('./recepieDurations');
const stepsRouter = require('./recepieSteps');
const DEBUG = false;
@ -15,14 +16,16 @@ const DEBUG = false;
router.param('recepieId', function(req, res, next, id) {
req.recepieId = id;
let query = " Select id, schluessel, schwierigkeit, name, portionen, nutzer, beschreibung, "+
" (SELECT sum(dauer) FROM rezept_dauer WHERE rezept = $1) as overall_duration "+
" FROM rezept ";
let query = " Select rezept.id, rezept.schluessel, schwierigkeit, schwierigkeit.name as schwierigkeitName, rezept.name, portionen, nutzer, rezept.beschreibung, "+
" (SELECT sum(dauer) FROM rezept_dauer WHERE rezept = rezept.id) as overall_duration, "+
" (SELECT round(avg(wert),1) FROM rezept_wertung WHERE rezept = rezept.id) as rating "+
" FROM rezept JOIN schwierigkeit on schwierigkeit = schwierigkeit.id ";
if(isNaN(req.recepieId)) {
query += " WHERE schluessel ilike '$1'";
query += " WHERE rezept.schluessel ilike '$1'";
} else {
query += " WHERE id = $1";
query += " WHERE rezept.id = $1";
}
if(DEBUG) console.log(query);
req.db.query(query, [req.recepieId], (err, rs) => {
if (err) {
@ -36,13 +39,26 @@ router.param('recepieId', function(req, res, next, id) {
router.use('/:recepieId/ingredients/', ingredientsRouter);
router.use('/:recepieId/tools/', toolsRouter);
router.use('/:recepieId/durations/', durationsRouter);
router.use('/:recepieId/steps/', stepsRouter);
/* GET recepies listing. */
router.get('/', function(req, res, next) {
let query = "Select * FROM rezept ";
let query = " Select rezept.id, rezept.schluessel, schwierigkeit, schwierigkeit.name as schwierigkeitName, rezept.name, portionen, nutzer, rezept.beschreibung, "+
" (SELECT sum(dauer) FROM rezept_dauer WHERE rezept = rezept.id) as overall_duration, "+
" (SELECT round(avg(wert),1) FROM rezept_wertung WHERE rezept = rezept.id) as rating "+
" FROM rezept JOIN schwierigkeit on schwierigkeit = schwierigkeit.id ";
if(req.query.term) query += " WHERE rezept.name ilike '%"+req.query.term+"%' "
if(req.query['sort_by']) {
if(req.query['sort_by'] === 'creation') query += " ORDER BY rezept.id desc";
if(req.query['sort_by'] === 'best_match') query += " ORDER BY rezept.name ";
if(req.query['sort_by'] === 'rating') query += " ORDER BY rating ";
}
if(DEBUG) console.log(query);
req.db.query(query, (err, rs) => {
if (err){
console.log(query);
next(err);
} else {
let result = {};
@ -54,13 +70,11 @@ router.get('/', function(req, res, next) {
});
router.post('/', function(req, res, next) {
let recepie = req.body.recepies[0];
let recepie = req.body.recepies;
if(!recepie.schluessel) recepie.schluessel = randToken.uid(8);
if(!recepie.schwierigkeit || !recepie.name || !recepie.nutzer) {
return res.status(400).send("Wrong Params")
}
let query = "INSERT INTO rezept (nutzer, name, schluessel, schwierigkeit, portionen, beschreibung) "+
" VALUES ($1, $2, $3, $4, $5, $6)" +
" returning *";
@ -70,12 +84,18 @@ router.post('/', function(req, res, next) {
req.db.query(query, values, (err, rs) => {
if(err && err.constraint && err.constraint ==='idx_rezept_email') {
return res.status(409).send("Email-adress already in use");
return res.status(409).send("Recipie Key already in use");
} else if (err){
next(err);
} else {
let result = {};
result['recepies'] = rs.rows[0];
req.db.query("INSERT into rezept_dauer (rezept, sort, name, dauer) VALUES ($1, 1, 'Zubereitung', '30m')", [rs.rows[0].id], (err, rs) => {});
req.db.query("INSERT into rezept_wertung (nutzer, rezept, wert, wertungskategorie) VALUES ($1, $2, 5, (SELECT id FROM wertungskategorie WHERE schluessel = 'sum'))", [rs.rows[0].nutzer, rs.rows[0].id], (err, rs) => {});
req.db.query("INSERT into rezept_schitt (rezept, sort, name, beschreibung) VALUES ($1, 1, 'Zubreitung', 'Mit Sherry ablöschen, Sahne hinzugeben und Parmesan reiben.')", [rs.rows[0].id], (err, rs) => {});
res.status(200).json(result);
}
});
@ -87,8 +107,12 @@ router.get('/:recepieId', function(req, res, next) {
});
router.put('/:recepieId', function(req, res, next) {
let recepie = req.body.recepies[0];
let query = "UPDATE rezept set name = '"+recepie.name+"', email='"+recepie.email+"', beschreibung = '"+recepie.beschreibung+"' "+
let recepie = req.body.recepies;
let query = "UPDATE rezept set name = '"+recepie.name+
"', schluessel='"+recepie.schluessel+
"', portionen='"+recepie.portionen+
"', schwierigkeit='"+recepie.schwierigkeit+
"', beschreibung = '"+recepie.beschreibung+"' "+
" WHERE id = "+req.recepieId +
" returning *";
if(DEBUG) console.log(query);
@ -103,54 +127,12 @@ router.put('/:recepieId', function(req, res, next) {
});
});
router.put('/:recepieId/changepasswd', function(req, res, next) {
let recepie = req.body.recepies[0];
let oldPasswd = req.body.recepies[0]['oldPasswd'];
let newPasswd = req.body.recepies[0]['newPasswd'];
if(!oldPasswd || !newPasswd) {
return res.status(400).send("Wrong Params");
}
bcrypt.compare(oldPasswd, req.recepie.kennwort, function(err, checkResult) {
console.log("Compare: "+oldPasswd+" WITH "+req.recepie.kennwort+" Result:");
console.log(checkResult);
if(checkResult) {
bcrypt.hash('myPassword', 10, function(err, hash) {
let query = "UPDATE rezept set kennwort = '"+hash+"'"+
" WHERE id = "+req.recepieId +
" returning *";
req.db.query(query, (err, rs) => {
if (err){
next(err);
} else {
let result = {};
let recepie = {};
recepie['name'] = rs.rows[0].name;
recepie['email'] = rs.rows[0].email;
recepie['id'] = rs.rows[0].id;
recepie['beschreibung'] = rs.rows[0].beschreibung;
result['recepies'] = recepie;
console.log(result);
res.status(200).json(result);
}
});
});
} else {
console.log(err);
res.status(409).send("Old Passwd didn't match");
}
});
});
router.delete('/:recepieId', function(req, res, next) {
let query = [
"DELETE FROM rezept_favorit where rezept = $1;",
"DELETE FROM rezept_kommentar where rezept = $1;",
"DELETE FROM rezept_rolle where rezept = $1;",
"DELETE FROM rezept_dauer where rezept = $1;",
"DELETE FROM rezept_zutat where rezept = $1;",
"DELETE FROM rezept_geraet where rezept = $1;",
"DELETE FROM rezept where id = $1;"
];
for(let i = 0; i< query.length; i++) {

View File

@ -8,7 +8,7 @@ const DEBUG = false;
router.param('ingredientId', function(req, res, next, id) {
req.ingredientId = id;
let query = " Select rezept_zutat.id, rezept, einheit, einheit.name as einheitname, einheit.schluessel as einheitschluessel , zutat, zutat.name as zutatname, menge "+
let query = " Select rezept_zutat.id, rezept, einheit, einheit.name as einheitname, einheit.schluessel as einheitschluessel , zutat, zutat.name as zutatname, menge, rezept_zutat.beschreibung "+
" FROM rezept_zutat "+
" JOIN zutat on zutat.id = zutat "+
" JOIN einheit on einheit.id = einheit "+
@ -25,11 +25,11 @@ router.param('ingredientId', function(req, res, next, id) {
/* GET recepieIngredients listing. */
router.get('/', function(req, res, next) {
let query = " Select rezept_zutat.id, rezept, einheit, einheit.name as einheitname, einheit.schluessel as einheitschluessel , zutat, zutat.name as zutatname, menge "+
let query = " Select rezept_zutat.id, rezept, einheit, einheit.name as einheitname, einheit.schluessel as einheitschluessel , zutat, zutat.name as zutatname, menge , rezept_zutat.beschreibung"+
" FROM rezept_zutat "+
" JOIN zutat on zutat.id = zutat "+
" JOIN einheit on einheit.id = einheit "+
" WHERE rezept =$1";
" WHERE rezept =$1 order by 1";
if(DEBUG) console.log(query);
req.db.query(query,[req.recepieId], (err, rs) => {
if (err){
@ -45,7 +45,10 @@ router.get('/', function(req, res, next) {
router.post('/', function(req, res, next) {
let recepieIngredient = req.body.recepieIngredients[0];
if(!recepieIngredient.zutat || !recepieIngredient.einheit || !recepieIngredient.menge) {
if(!recepieIngredient.menge) recepieIngredient.menge = null;
if(!recepieIngredient.zutat || !recepieIngredient.einheit) {
return res.status(400).send("Wrong Params")
}
let query = "INSERT INTO rezept_zutat (rezept, menge, einheit, zutat, beschreibung) "+

View File

@ -8,7 +8,7 @@ const DEBUG = false;
router.param('stepId', function(req, res, next, id) {
req.stepId = id;
let query = " Select rezept_schritt.id, dauer, name, sort, beschreibung "+
let query = " Select rezept_schritt.id, name, sort, beschreibung "+
" FROM rezept_schritt "+
" WHERE rezept =$1 AND rezept_schritt.id = $2";
if(DEBUG) console.log(query);
@ -23,7 +23,7 @@ router.param('stepId', function(req, res, next, id) {
/* GET recepieSteps listing. */
router.get('/', function(req, res, next) {
let query = " Select rezept_schritt.id, dauer, name, sort, beschreibung "+
let query = " Select rezept_schritt.id, name, sort, beschreibung "+
" FROM rezept_schritt "+
" WHERE rezept =$1";
if(DEBUG) console.log(query);
@ -41,13 +41,13 @@ router.get('/', function(req, res, next) {
router.post('/', function(req, res, next) {
let recepieStep = req.body.recepieSteps[0];
if(!recepieStep.dauer || !recepieStep.name || !recepieStep.sort) {
if(!recepieStep.name || !recepieStep.sort) {
return res.status(400).send("Wrong Params")
}
let query = "INSERT INTO rezept_schritt (rezept, dauer, name, sort, beschreibung) "+
" VALUES ($1, $2, $3, $4, $5)" +
let query = "INSERT INTO rezept_schritt (rezept, name, sort, beschreibung) "+
" VALUES ($1, $2, $3, $4)" +
" returning *";
let values = [req.recepieId, recepieStep.dauer, recepieStep.name, recepieStep.sort, recepieStep.beschreibung];
let values = [req.recepieId, recepieStep.name, recepieStep.sort, recepieStep.beschreibung];
if(DEBUG) console.log(query);
@ -69,10 +69,10 @@ router.get('/:stepId', function(req, res, next) {
router.put('/:stepId', function(req, res, next) {
let recepieStep = req.body.recepieSteps[0];
let query = "UPDATE rezept_schritt set name = $1, dauer = $2, sort =$3, beschreibung =$4"+
let query = "UPDATE rezept_schritt set name = $1, sort =$2, beschreibung =$3"+
" WHERE id = "+req.stepId +
" returning *";
let values = [recepieStep.name, recepieStep.dauer, recepieStep.sort, recepieStep.beschreibung];
let values = [recepieStep.name, recepieStep.sort, recepieStep.beschreibung];
if(DEBUG) console.log(query);
req.db.query(query, values, (err, rs) => {

44
seed.js
View File

@ -109,6 +109,40 @@ let defaultWertungskategorien = [
];
let defaultEinheiten = [
{ "name":"Gramm",
"schluessel":"g"},
{ "name":"Kilogramm",
"schluessel":"kg"},
{ "name":"Centiliter",
"schluessel":"cl"},
{ "name":"Liter",
"schluessel":"l"},
{ "name":"Milliliter",
"schluessel":"ml"},
{ "name":"Dose",
"schluessel":"dose"},
{ "name":"Glas",
"schluessel":"glas"},
{ "name":"Tasse",
"schluessel":"tasse"},
{ "name":"Messerspitze",
"schluessel":"msp"},
{ "name":"Teelöffel",
"schluessel":"tl"},
{ "name":"Esslöffel",
"schluessel":"el"},
{ "name":"Prise",
"schluessel":"pr"},
{ "name":"Milligramm",
"schluessel":"mg"},
{ "name":"Pfund",
"schluessel":"pd"},
{ "name":"Stück",
"schluessel":"stk"}
];
const makeKey = (input) => {
let result = input.toLowerCase();
result = result.replace(/[\(\)]/g,"");
@ -129,7 +163,7 @@ for(let i = 0; i<defaultSchwierigkeiten.length; i++) {
for(let i = 0; i<defaultWertungskategorien.length; i++) {
let query = "INSERT INTO wertungkategorie (name, schluessel) "+
"VALUES ($1, $2) returning *";
db.query(query, [defaultWertungskategorien[i]['name'], makeKey(defaultWertungskategorien[i]['schluessel'])], (err, rs) => {
db.query(query, [defaultWertungskategorien[i]['name'], defaultWertungskategorien[i]['schluessel']], (err, rs) => {
console.log(err);
})
}
@ -142,3 +176,11 @@ for(let i = 0; i<defaultZutaten.length; i++) {
console.log(err);
})
}
for(let i = 0; i<defaultEinheiten.length; i++) {
let query = "INSERT INTO einheit (name, schluessel) "+
"VALUES ($1, $2) returning *";
db.query(query, [defaultEinheiten[i]['name'], defaultEinheiten[i]['schluessel']], (err, rs) => {
console.log(err);
})
}

4
src/index.js Normal file
View File

@ -0,0 +1,4 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './views/App';
ReactDOM.render(<App />, document.getElementById('root'));

26
src/package.json Normal file
View File

@ -0,0 +1,26 @@
{
"name": "schmeckWieDaheim-FrontEnd",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-scripts": "2.1.2",
"whatwg-fetch": "^3.0.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}

25
src/util/Cookbook.js Normal file
View File

@ -0,0 +1,25 @@
// API-Class to fetch Information from "schmektWieDaheim"
import 'whatwg-fetch';
const Cookbook = {};
const baseUrl = 'http://localhost:4000';
Cookbook.getRecepies = () => {
const url = `${baseUrl}/recepies`;
return fetch(url).then(response => {
if(!response.ok) {
return new Proimse(resolve => resolve([]));
}
return response.json().then(jsonResponse => {
return jsonResponse.recepies.map(recepie);
})
})
};
// Export Module
export default Cookbook;

33
src/views/App.js Normal file
View File

@ -0,0 +1,33 @@
import React, { Component } from 'react';
import { Link, HashRouter as Router, Route, browserHistory } from 'react-router-dom';
import Recepie from './Recepie';
class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
render () {
return (
<Router history={browserHistory}>
<div className="App">
<header>
<Link to="/" className="logo">
<img src='public/img/logo.svg' alt="logo" />
</Link>
</header>
<Route exact path="/" component={Landing} />
<Route path="/recepies/:id" component={Employee} />
</div>
</Router>
);
}
}
export default App;

34
src/views/Recepie.js Normal file
View File

@ -0,0 +1,34 @@
import React, { Component } from 'react';
import { withRouter } from "react-router-dom";
import Cookbook from '../utils/Cookbook';
class Cookbook extends Component {
constructor(props) {
super(props);
this.state = {
recepie: null,
ingredients: [],
durations: []
}
}
render() {
if (!this.state.recepie) {
return <div className="Recepie">Kein Rezept gefunden</div>
}
const recepie = this.state.recepie;
return (
<div className="Recepie">Rezept gefunden</div>
);
}
}
export default withRouter(Cookbook);

28
webpack.config.js Normal file
View File

@ -0,0 +1,28 @@
'use strict';
const webpack = require('webpack'); // eslint-disable-line no-unused-vars
module.exports = {
entry: './src/index.js',
output: {
path: __dirname,
filename: './public/js/bundle.js',
},
context: __dirname,
devtool: 'source-map',
module: {
loaders: [
{
test: /jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-2'],
}
}
]
},
node: {
fs: "empty"
}
};

View File

@ -1,76 +0,0 @@
Weißbrot
Kartoffeln
Kartoffeln (mehlig)
Kartofflen (festkochend)
Reis
Nudeln
Kroketten
Spätzle
Hähnchenbrustfilet
Putenschnitzel
Rindfleisch
Kalbfleisch
Rindersteak
Rinderhackfleisch
Hackfleisch gemischt
Schweineschnitzel
Schweinekotelett
Ente
Gans
Käse
Frischkäse
Kräuterquark
Quark
Mozzarella
Parmesan
Speisequark (40 % Fett)
Camembert
Gouda
Edamer
Raclette
Mascarpone
Schinken (gekocht)
Schinken (roh)
Schinken (geräuchert)
Salami
Oliven schwarz
Butter
Butterschmalz
Olivenöl
Rapsöl
Sonnenblumenöl
Margarine
Honig
Marmelade
Konfitüre
Nussnougatcreme
Eier
Joghurt, 1,5 % Fett
Joghurt, 3,5 % Fett
Seelachs
Zander
Kabeljau
Garnelen
Krabben
Forelle
Makrele
Lachs
Lachs (geräuchert)
Heringsfilet
passierte Tomaten
Saure Sahne
Pesto (rot)
Pesto (grün)
Mayonnaise
Sahne
Crème fraiche
Nüsse
Mandeln
Apfelmus
Preiselbeeren
Schokolade (Vollmilch)
Schokolade (Zartbitter)
Kuvertüre (Vollmilch)
Kuvertüre (Zartbitter)
Marzipan
Hefe