Skip to content
Permalink
81dc0dc3fb
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
460 lines (385 sloc) 16.4 KB
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1,minimal-ui" name="viewport">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,400italic|Material+Icons">
<link rel="stylesheet" href="https://unpkg.com/vue-material@beta/dist/vue-material.min.css">
<link rel="stylesheet" href="https://unpkg.com/vue-material@beta/dist/theme/default.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
.Red {
background-color:red!important;
}
.Red {
color:white!important;
}
.Yellow{
background-color:yellow!important;
}
.Yellow * {
color:brown!important;
}
.Green{
background-color:green!important;
}
.Green * {
color:white!important;
}
.scn-target {
height:160px;
width:200px;
top:120px;
left:50%;
margin-left:-100px;
border:3px solid red;
position:absolute;
}
canvas.drawing, canvas.drawingBuffer {
position: absolute;
left: 0;
top: 0;
}
</style>
<title>SWAP / WellSCAN Barcode Lookup</title>
</head>
<body>
<div id="app">
<template>
<div class="page-container">
<md-dialog :md-active.sync="showDialog" @md-opened = "theScan">
<div id="scanner-container">
<div class="scn-target"></div>
</div>
<md-dialog-actions>
<md-button class="md-primary" @click="killScan">Close</md-button>
</md-dialog-actions>
</md-dialog>
<md-app>
<md-app-toolbar class="md-primary">
<md-button v-on:click = "showSettings = true" class="md-icon-button">
<md-icon>settings</md-icon>
</md-button>
<span style="flex:1;" class="md-title">WellSCAN (SWAP Food Lookup)</span>
<md-button v-if = "this.particpantId" v-on:click = "showCart = true" class="md-icon-button">
<md-icon>shopping_cart</md-icon>
</md-button>
</md-app-toolbar>
<md-app-content>
<md-card>
<md-card-header>
<div class="md-title">Search for a Food by UPC</div>
</md-card-header>
<md-card-content>
<md-field>
<label>Enter a UPC</label>
<md-input ref="searchBox" v-focus v-on:focus = "clearAndFocus()" v-on:keyup.enter="getData" id="searchTerm" v-model="searchTerm" placeholder="Enter UPC"></md-input>
<md-button v-if="searchTerm" v-on:click = "searchTerm = ''; clearAndFocus();" title="Clear"><md-icon > clear</md-icon></md-button>
<md-button v-on:click = "showDialog = true" title="Scan Barcode">[ <i class="fa fa-barcode"></i> ]</md-button>
</md-field>
<div class="notFound md-accent" v-if="notFound">
<div>Hmm...that food wasn't in SWAP Global. Enter a category to look it up.</div>
<md-field>
<label for="category">SWAP Category</label>
<md-select v-model="rulesCat" name="category">
<md-option value="1">Fruit</md-option>
<md-option value="2">Vegetables</md-option>
<md-option value="3">Grains</md-option>
<md-option value="4">Protein: Plant-Based</md-option>
<md-option value="5">Protein: Animal</md-option>
<md-option value="6">Combination Foods/Meals</md-option>
<md-option value="7">Dairy - Milk</md-option>
<md-option value="8">Dairy - Yogurt</md-option>
<md-option value="9">Dairy - Cheese</md-option>
<md-option value="10">Condiments</md-option>
<md-option value="11">Beverages</md-option>
<md-option value="12">Snacks/Desserts</md-option>
</md-select>
</md-field>
</div>
</md-card-content>
<md-card-actions>
<md-button type="submit" v-on:click="getData">Search</md-button>
</md-card-actions>
</md-card>
<md-card v-if="showSearchResults" :class="[food.rank.name]">
<md-card-header>
<div :class="['md-title']">{{food.food.name}}</div>
</md-card-header>
<md-card-content>
<p>({{food.food.barcode}})</p>
<p>{{food.category.name}}</p>
<p>{{food.rank.name}}</p>
</md-card-content>
<md-card-actions>
<md-button v-if = "this.particpantId" v-on:click = "addToCart(food)" class="md-icon-button">
<md-icon style="color:#fff;" > add_shopping_cart</md-icon>
</md-button>
</md-card-actions>
</md-card>
<md-empty-state v-if="!searchTerm"
md-icon="search"
md-label="Search for a Food by UPC"
md-description="When you search for a food via UPC, search results will show up here.">
</md-empty-state>
<md-snackbar md-position="center" :md-active.sync="showNotFoundWarning">
<span>Hmm...that food wasn't in SWAP Global. Enter a category to look it up.</span>
</md-snackbar>
<md-snackbar md-position="center" :md-active.sync="showAddedToCartNotice">
<span>Item added to cart!</span>
</md-snackbar>
<md-card v-if = "this.errorMSG" class="md-accent" md-with-hover>
<md-ripple>
<md-card-header>
<div class="md-title">Error!</div>
<p>But you can add it to the cart anyway!</p>
<md-button v-if = "this.particpantId" v-on:click = "addUPCToCart(searchTerm)" class="md-icon-button">
<md-icon style="color:#fff;" > add_shopping_cart</md-icon>
</md-button>
</md-card-header>
<md-card-content>
{{this.errorMSG}}
</md-card-content>
<md-card-actions>
<md-button v-on:click="errorMSG = false">Dismiss</md-button>
</md-card-actions>
</md-ripple>
</md-card>
<md-dialog :md-active.sync="showSettings">
<md-dialog-title>Settings</md-dialog-title>
<md-dialog-content>
<md-field>
<label>Participant ID</label>
<md-input v-model="particpantId"></md-input>
</md-field>
<div>
<label style="text-align:center;"><strong>Empty Cart?</strong></label> <br>
<md-button class="md-accent" @click="cart = []">Empty Cart</md-button>
</div>
</md-dialog-content>
<md-dialog-actions>
<md-button class="md-primary" @click="showSettings = false">Close</md-button>
</md-dialog-actions>
</md-dialog>
<md-dialog :md-active.sync="showCart">
<md-dialog-title>Shopping Cart</md-dialog-title>
<md-dialog-content>
<md-table>
<md-table-row>
<md-table-head>Food</md-table-head>
<md-table-head>Rank</md-table-head>
<md-table-head>Remove</md-table-head>
</md-table-row>
<md-table-row v-for="(purchase, index) in cart" :class = "[purchase.rank]">
<md-table-cell>{{purchase.name}}</md-table-cell>
<md-table-cell>{{purchase.rank}}</md-table-cell>
<md-table-cell>
<md-button v-on:click = "removeItem(index)" class="md-icon-button">
<md-icon>remove_shopping_cart</md-icon>
</md-button>
</md-table-cell>
</md-table-row>
</md-table>
</md-dialog-content>
<md-dialog-actions>
<md-button class="md-primary" @click="showCart = false">Close</md-button>
</md-dialog-actions>
</md-dialog>
</md-app-content>
</md-app>
</div>
</template>
</div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js" type="text/javascript"></script>
<script src="https://cdn.rawgit.com/serratus/quaggaJS/0420d5e0/dist/quagga.min.js"></script>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-material"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
Vue.use(VueMaterial.default);
let app = new Vue({
el: '#app',
data() {
return {
food:{},
searchTerm:null,
notFound: false,
rulesCat:null,
showNotFoundWarning:false,
showAddedToCartNotice:false,
showSettings:false,
showCart:false,
showDialog : false,
particpantId : "",
cart : [],
showSearchResults: false,
errorMSG: null
}
},
directives: {
focus: {
// directive definition
inserted: function (el) {
el.focus()
}
}
},
methods: {
killScan: function() {
this.showDialog = false
Quagga.stop();
},
clearAndFocus() {
this.$refs.searchBox.$el.focus();
this.searchTerm = null;
this.showSearchResults = false;
},
addToCart(food) {
if (this.particpantId) {
let randId = '_' + Math.random().toString(36).substr(2, 9);
let that = this;
let upc = food.food.barcode;
let particpantId = this.particpantId;
this.cart.push({randId: randId, name:food.food.name,rank:food.rank.name});
axios.get('/purchase/add/' + particpantId + "/" + upc + "/" + randId).then((response) => {
}, (error) => {
console.log(error);
});
//this.showCart = true;
this.showAddedToCartNotice = true;
} else {
alert('Please set your Partcipant ID before adding an item to your cart.')
}
},
addUPCToCart(upc){
let dummyFood = {
food: {
name:"Unknown Food",
barcode:upc
},
rank: {
name:"Rank Unknown"
}
};
this.addToCart(dummyFood);
},
removeItem(index){
console.log("should remove " + index);
let food = this.cart[index];
// hit the API to remove a purchase
axios.get('/purchase/remove/' + food.randId).then((response) => {}, (error) => {
console.log(error);
});
this.cart.splice(index, 1);
},
getData: function(event) {
// if we're not looking up a new food
if (!this.notFound) {
axios.get('/food/fromSWAPGlobal/' + this.searchTerm).then((response) => {
if(response.data.status != "notFound") {
this.food = response.data;
this.food.id = response.data.food.id;
this.showSearchResults = true;
}
if (response.data.status == "notFound") {
this.notFound = true;
this.showNotFoundWarning = true;
}
}, (error) => {
this.loading = false;
})
} else { // if we're looking up a new food (not found in swap db)
axios.get('/food/runLookup/' + this.searchTerm + "/" + this.rulesCat).then((response) => {
this.food = response.data;
if(response.data.status != "notFound") {
this.food.id = this.food.food.id;
this.notFound = false;
this.showSearchResults = true;
} else {
this.errorMSG = response.data.msg;
}
}, (error) => {
this.loading = false;
})
}
},
initScanner: () => {
console.log("wut");
this.showDialog = true;
},
theScan: () => {
console.log('ummm');
startScanner();
}
}
})
var _scannerIsRunning = false;
function startScanner() {
Quagga.init({
inputStream: {
name: "Live",
type: "LiveStream",
target: document.querySelector('#scanner-container'),
constraints: {
width: 480,
height: 320,
facingMode: "environment"
},
},
decoder: {
readers: [
'code_128_reader',
'ean_8_reader',
'upc_reader',
'upc_e_reader'
],
halfSample: true,
patchSize: "medium",
debug: {
drawBoundingBox: true,
showFrequency: true,
drawScanline: true,
showPattern: true
},
multiple:false
},
}, function (err) {
if (err) {
console.log(err);
return
}
console.log("Initialization finished. Ready to start");
Quagga.start();
// Set flag to is running
_scannerIsRunning = true;
});
Quagga.onProcessed(function (result) {
var drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay;
if (result) {
if (result.boxes) {
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
result.boxes.filter(function (box) {
return box !== result.box;
}).forEach(function (box) {
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 });
});
}
if (result.box) {
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "#00F", lineWidth: 2 });
}
if (result.codeResult && result.codeResult.code) {
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
}
}
});
Quagga.onDetected(function (result) {
console.log("Barcode detected and processed : [" + result.codeResult.code + "]", result);
Quagga.stop();
app.searchTerm = result.codeResult.code;
app.showDialog = false;
});
}
</script>
</body>
</html>