diff --git a/api/index.php b/api/index.php index 2dc475c..7475b8e 100644 --- a/api/index.php +++ b/api/index.php @@ -1,5 +1,5 @@ add('', __DIR__ . '/generated-classes/'); // Propel ORM Classes require './generated-conf/config.php'; // Propel Config diff --git a/api/routes/category.php b/api/routes/category.php index cb5856e..137363d 100644 --- a/api/routes/category.php +++ b/api/routes/category.php @@ -7,6 +7,7 @@ $app->get('/category/all', function( $request, $response ) { $q = new CategoryQuery; $cats = $q::create()->find(); + $response_json = [ "status" => [ "code" => $response->getStatusCode(), @@ -14,14 +15,34 @@ ], "data" => [] ]; + foreach( $cats as $cat ) { + $rules = []; + $q = new CategoryRankNutrientQuery; + $requestedCatRules = $q->filterByCategoryId($cat->getId())->orderByRankId()->find(); + foreach($requestedCatRules as $rule) { + $rules[$rule->getNutrient()->getName()][] = [ + "nutrientName" => $rule->getNutrient()->getName(), + "nutrientId" => $rule->getNutrient()->getId(), + "operator" => $rule->getOperator(), + "threshold" => $rule->getThreshold(), + "units" => $rule->getUnits(), + "rank" => $rule->getRankId() + ]; + } + + $response_json["data"][] = [ "id" => $cat->getId(), - "name" => $cat->getName() + "name" => $cat->getName(), + "rules" => $rules ]; + } + $response = $response->withJSON($response_json); return $response; + }); /** diff --git a/api/routes/decision.php b/api/routes/decision.php index 90d0ca0..68bd951 100644 --- a/api/routes/decision.php +++ b/api/routes/decision.php @@ -124,86 +124,134 @@ function getProductInfo($upc) { $app->get('/getDecision/{upc}/{category}', function($request, $response) { +/** Checking to see if the food is already in the DB, in which case we save lots of time **/ -// get the nutrients by UPC -$prodInfo = getProductInfo($request->getAttribute('upc')); -$nutrients = $prodInfo['response']['body']['product_list']['products'][0]['product_nutrient_list']['product_nutrients']; + $q = new FoodQuery(); + $barcode = $request->getAttribute('upc'); + $food = $q::create() + ->useRankQuery() + ->endUse() + ->useCategoryQuery() + ->endUse() + ->filterByBarcode($barcode) + ->findOne(); -// get the whittled down nutrtient info shittily -$theNuts = array(); +if($food){ + + $rank = $food->getRank(); + $category = $food->getCategory(); + + $res['rankId'] = $food->getRankId(); + $res['rankName'] = $rank->getName(); + + + $res['request']['message'] = "Did not hit Fooducate. Food already exists in DB."; -foreach ($nutrients as $nutrient) { - $theNuts[$nutrient['nutrient']['@attributes']['name']] = $nutrient['@attributes']['value']; } -// echo "
"; -// print_r($theNuts); -// echo ""; +if(!$food) { + // get the nutrients by UPC + $prodInfo = getProductInfo($request->getAttribute('upc')); + $nutrients = $prodInfo['response']['body']['product_list']['products'][0]['product_nutrient_list']['product_nutrients']; -// get the rules by category - $q = new CategoryRankNutrientQuery; -$c = new CategoryQuery(); + // get the whittled down nutrtient info shittily + $theNuts = array(); + foreach ($nutrients as $nutrient) { + $theNuts[$nutrient['nutrient']['@attributes']['name']] = $nutrient['@attributes']['value']; + } - $allRules = $q->filterByCategoryId($request->getAttribute('category'))->find(); - //$res["food"] = $prodInfo; - $res["food"]['brand'] = $prodInfo['response']['body']['product_list']['products'][0]["@attributes"]['brand']; - $res["food"]['name'] = $prodInfo['response']['body']['product_list']['products'][0]["@attributes"]['name']; + // echo "
"; + // print_r($theNuts); + // echo ""; - $res["request"]["categoryRuleRun"] = $c->findPk($request->getAttribute("category"))->getName(); + // get the rules by category + $q = new CategoryRankNutrientQuery; + $c = new CategoryQuery(); -//default - $res["rankId"] = 0; - $res["rankName"] = "Red"; + $allRules = $q->filterByCategoryId($request->getAttribute('category'))->find(); + //$res["food"] = $prodInfo; + $res["food"]['brand'] = $prodInfo['response']['body']['product_list']['products'][0]["@attributes"]['brand']; + $res["food"]['name'] = $prodInfo['response']['body']['product_list']['products'][0]["@attributes"]['name']; -// for each rule, evaluate ingredients - foreach($allRules as $rule) { - $nut = $rule->getNutrient()->getName(); - $operator = $rule->getOperator(); - $threshold = $rule->getThreshold(); - $presentVal = $theNuts[$nut]; + $res["request"]["categoryRuleRun"] = $c->findPk($request->getAttribute("category"))->getName(); - $pass = 0; - switch($operator) { - case "lte": - $pass = ($presentVal <= $threshold); - break; + //default + $res["rankId"] = 3; + $res["rankName"] = "Red"; - case "lt": - $pass = ($presentVal < $threshold); - break; + // for each rule, evaluate ingredients + foreach($allRules as $rule) { + $nut = $rule->getNutrient()->getName(); + $operator = $rule->getOperator(); + $threshold = $rule->getThreshold(); + $presentVal = $theNuts[$nut]; - case "gt": - $pass = ($presentVal > $threshold); - break; - case "gte": - $pass = ($presentVal >= $threshold); - break; + $pass = 0; + switch($operator) { + case "lte": + $pass = ($presentVal <= $threshold); + break; - case "is": - $pass = ($presentVal == $threshold); - break; - } + case "lt": + $pass = ($presentVal < $threshold); + break; + case "gt": + $pass = ($presentVal > $threshold); + break; - $rules[$rule->getRank()->getName()][$rule->getNutrient()->getName()] = [ - "operator" => $operator, - "threshold" => $threshold, - "passed" => $pass?"true" : "false" - ]; + case "gte": + $pass = ($presentVal >= $threshold); + break; - $rules[$rule->getRank()->getName()]['passedRank'] = $pass?"true" : "false"; + case "is": + $pass = ($presentVal == $threshold); + break; + } - if($pass) { - $res["rankId"] = $rule->getRank()->getId(); - $res["rankName"] = $rule->getRank()->getName(); - } - } + $rules[$rule->getRank()->getName()][$rule->getNutrient()->getName()] = [ + "operator" => $operator, + "threshold" => $threshold, + "passed" => $pass?"true" : "false" + ]; + + $rules[$rule->getRank()->getName()]['passedRank'] = $pass?"true" : "false"; + + if($pass) { + $res["rankId"] = $rule->getRank()->getId(); + $res["rankName"] = $rule->getRank()->getName(); + } + } + + + /** Now create this Food with the associated rank and category **/ + + $newFood = new Food; + + $newFoodCat = $request->getAttribute('category'); + + $newFoodRank = $res['rankId']; + + $newFood->setRankId($newFoodRank); + $newFood->setCategoryId($newFoodCat); + $newFood->setBarcode($barcode); + + + if($newFood->save()){ + $msg = "New Food also added to DB."; + } else { + $msg = "There was an error saving this new Food to the DB"; + } + + $res['request']['message'] = $msg; + +} // echo "
"; diff --git a/api/routes/rules.php b/api/routes/rules.php index f18979a..0b81736 100644 --- a/api/routes/rules.php +++ b/api/routes/rules.php @@ -48,7 +48,59 @@ $newRule->setRankId($rank); $newRule->setNutrientId($nutrient); - $newRule->save(); + if($newRule->save()){ + $msg = "New Rule Saved"; + } else { + $msg = "There was an error saving this rule"; + } + + + + $response_json = [ + "status" => [ + "code" => $response->getStatusCode(), + "message" => [$msg] + ] + ]; + + $response = $response->withJSON($response_json); + return $response; + + +}); + +$app->post('/rules/updateRuleById/{ruleId}', function($request, $response) { + + $rule = CategoryRankNutrientQuery::create()->findPk($request->getAttribute("ruleId")); + + $cat = $request->getParam('catId'); + $nutrient = $request->getParam('nutrientId'); + + $rank = $request->getParam('rankId'); + + + $rule->setThreshold($request->getParam('threshold')); + $rule->setUnits($request->getParam('units')); + $rule->setOperator($request->getParam('operator')); + $rule->setCategoryId($cat); + $rule->setRankId($rank); + $rule->setNutrientId($nutrient); + + if($rule->save()){ + $msg = "Rule updated."; + } else { + $msg = "There was an error saving this rule"; + } + + + $response_json = [ + "status" => [ + "code" => $response->getStatusCode(), + "message" => [$msg] + ] + ]; + $response = $response->withJSON($response_json); + return $response; }); \ No newline at end of file diff --git a/app/app.js b/app/app.js index 8ae4155..dfe3e57 100644 --- a/app/app.js +++ b/app/app.js @@ -1,36 +1,40 @@ -var app = angular.module('app', ['ngRoute', 'ngResource']); +var app = angular.module('app', ['ngRoute', 'ngResource', 'ngCookies']); // Root controllers in /root/ folder // Page controllers in /pages/[your-page] folder // Factories -// TODO: 'Foods' factory TEMPORARY app.factory('Foods', function($resource) { return $resource('assets/json/foods.json'); }); -// Just does a PUT request when u call Food.update -app.factory('Food', function ($resource) { - // {food: '@id'} means replace :food with $scope.foodCRUD.id - var data = $resource('http://foodbank.develop.digitalmediauconn.org/api/food/:food', {food: '@id'}, { - update:{ method:'PUT' } - }); - return data; +app.factory('FoodDetail', function($resource) { + // http://foodbank.develop.digitalmediauconn.org/api/getProductInfo/049000031249 + // return $resource('https://example.com/api/food/:barcode', {barcode: '@barcode'}); + return $resource('assets/json/foodDetail.json'); }); app.factory('Categories', function($resource) { return $resource('http://foodbank.develop.digitalmediauconn.org/api/index.php/category/all'); }); -// TODO: 'Nutrients' factory TEMPORARY app.factory('Nutrients', function($resource) { return $resource('assets/json/nutrients.json'); }); -app.factory('Nutrient', function ($resource) { - var data = $resource('http://foodbank.develop.digitalmediauconn.org/api/nutrients/:nutrient', {nutrient: '@id'}, { - update:{ method:'PUT' } - }); - return data; -}); +// Just does a PUT request when u call Food.update +// app.factory('Food', function ($resource) { +// // {food: '@id'} means replace :food with $scope.foodCRUD.id +// var data = $resource('http://foodbank.develop.digitalmediauconn.org/api/food/:food', {food: '@id'}, { +// update:{ method:'PUT' } +// }); +// return data; +// }); + +// app.factory('Nutrient', function ($resource) { +// var data = $resource('http://foodbank.develop.digitalmediauconn.org/api/nutrients/:nutrient', {nutrient: '@id'}, { +// update:{ method:'PUT' } +// }); +// return data; +// }); diff --git a/app/pages/food/ctrl.js b/app/pages/food/ctrl.js index e683268..ee72c58 100644 --- a/app/pages/food/ctrl.js +++ b/app/pages/food/ctrl.js @@ -1,27 +1,28 @@ -app.controller('FoodCtrl', ['$scope', '$http', 'Foods', 'Food', 'Categories', function ($scope, $http, Foods, Food, Categories) { +app.controller('FoodCtrl', ['$scope', '$http', 'Foods', 'FoodDetail', 'Categories', '$cookies', function ($scope, $http, Foods, FoodDetail, Categories, $cookies) { $scope.page.title = 'Food'; $scope.page.id = 'food'; + // Cookie for Table/Card view prefence + $scope.tableView = $cookies.get('showTable') === 'true'; + $scope.$watch('tableView', function () { + $cookies.put('showTable', $scope.tableView ? 'true' : 'false'); + }); + // Initialize Filters $scope.foods = []; $scope.categories = []; $scope.rankSelection = { - "green": true, - "yellow": true, - "red": true, - "gray": true + "1": true, + "2": true, + "3": true, + "4": true }; $scope.categorySelection = { "all": true }; $scope.searchTerm = ""; - - - // Initialize CRUD modes - $scope.editMode = false; - $scope.createMode = false; - // Initialize CRUD form $scope.foodCRUD = {}; + $scope.nutrientDetail = []; // GET foods Foods.get({}, function (data) { @@ -42,7 +43,6 @@ app.controller('FoodCtrl', ['$scope', '$http', 'Foods', 'Food', 'Categories', fu }); - // Set category filters to false $scope.resetCategorySelection = function () { $scope.categories.forEach(function(c){ @@ -51,43 +51,66 @@ app.controller('FoodCtrl', ['$scope', '$http', 'Foods', 'Food', 'Categories', fu } // Category filter function $scope.categoryFilter = function (food) { - return ( $scope.categorySelection[food.category_id] | $scope.categorySelection["all"] ); + return ( $scope.categorySelection[food.category.id] | $scope.categorySelection["all"] ); } // Rank filter function $scope.rankFilter = function (food) { - return ( $scope.rankSelection[food.rank_id] ); + return ( $scope.rankSelection[food.rank.id] ); } - - // CRUD: edit food - $scope.edit = function (foodToEdit) { - $scope.editMode = true; - $scope.foodCRUD = foodToEdit; - $scope.foodCRUD.action = "update"; - // console.log($scope.foodCRUD); - }; - - // CRUD: create food - $scope.create = function () { - $scope.createMode = true; - $scope.foodCRUD = {}; - $scope.foodCRUD.rank_mode = "auto"; - $scope.foodCRUD.action = "create"; - // console.log($scope.foodCRUD); + // Modal : View Food + $scope.view = function (foodToView) { + $scope.showModal = true; + $scope.foodCRUD = foodToView; + FoodDetail.get({barcode: foodToView.barcode}, function (data) { + $scope.nutrientDetail = data.data.nutrients; + }); }; - // CRUD: cancel + // Modal : Cancel $scope.cancel = function () { - $scope.editMode = false; - $scope.createMode = false; + $scope.showModal = false; }; - // CRUD: POST - $scope.submit = function () { - $scope.cancel(); // hide modal - Food.update($scope.foodCRUD); - }; + // NOTE: End of code for now + + + + + + // Initialize CRUD modes + // $scope.editMode = false; + // $scope.createMode = false; + + // CRUD: edit food + // $scope.edit = function (foodToEdit) { + // $scope.editMode = true; + // $scope.foodCRUD = foodToEdit; + // $scope.foodCRUD.action = "update"; + // console.log($scope.foodCRUD); + // }; + // + // // CRUD: create food + // $scope.create = function () { + // $scope.createMode = true; + // $scope.foodCRUD = {}; + // $scope.foodCRUD.rank_mode = "auto"; + // $scope.foodCRUD.action = "create"; + // // console.log($scope.foodCRUD); + // }; + // + // // CRUD: cancel + // $scope.cancel = function () { + // $scope.editMode = false; + // $scope.createMode = false; + // }; + // + // // CRUD: POST + // $scope.submit = function () { + // $scope.cancel(); // hide modal + // Food.update($scope.foodCRUD); + // }; }]); diff --git a/app/pages/food/style.styl b/app/pages/food/style.styl index ea3dde1..1b07d95 100644 --- a/app/pages/food/style.styl +++ b/app/pages/food/style.styl @@ -67,10 +67,6 @@ -// Table view - - - .foods display: flex @@ -113,13 +109,13 @@ background-color: purple i color: white - .rank-green + .rank-1 background-color: green - .rank-yellow + .rank-2 background-color: yellow - .rank-red + .rank-3 background-color: red - .rank-gray + .rank-4 background-color: gray @@ -157,6 +153,7 @@ font-size: 1.1em padding: 1em border: 1px solid lightgray + min-width 300px my-box-shadow() background: white [type="radio"]:not(:checked)+label, [type="radio"]:checked+label @@ -171,6 +168,9 @@ font-weight: 500 color: #BBB margin-bottom: 5px + span + color initial + font-weight normal a.btn width: 48% .orange @@ -183,3 +183,48 @@ td:first-child font-weight: 500 width: 50% + + + +// Table view +.foodTable + display flex + flex-flow: row wrap; + align-content: stretch; + width 100% + +.foodTableItem + display inline-flex + flex 1 430px + margin-bottom 12px + font-size 1.2em + align-items center + margin-right 1em + padding-right 1em + background #f5f5f5 + +above(760px) + max-width calc(50% - 1em) + transition: all .2s + cursor: pointer + my-box-shadow() + &:hover + transform: scale(.95) + span + flex-basis 100px + margin-right 1em + .name + flex-basis 140px + .barcode + color #888 + font-size 1rem + text-align right + margin-right 0 + .health + height 35px + width @height + min-height @height + min-width @height + max-height @height + max-width @height + i + font-size 21px diff --git a/app/pages/food/view.html b/app/pages/food/view.html index 2b46dc1..0384f0f 100644 --- a/app/pages/food/view.html +++ b/app/pages/food/view.html @@ -32,16 +32,16 @@By Category
@@ -65,69 +65,63 @@By Grade
Table
- --- -add-Add new food
---favorite++- - -favorite{{food.name}}
-
-- - - -Rank -Food -Category -- - - -- Add new food -- - +- {{food.name}} -{{categories[food.category_id].name}} -++ favorite + {{food.name}} + {{food.category.name}} + +-++{{foodCRUD.name || "Add New Food"}}
+Barcode: {{foodCRUD.barcode}}
+Grade: {{foodCRUD.rank.name}}
+Category: {{foodCRUD.category.name}}
+Nutrition Facts:
++ {{nutrient.nutrientName}} + {{nutrient.nutrientId}} + {{nutrient.units}} + {{nutrient.rank}} ++ + + + + + -