Skip to content

Instantly share code, notes, and snippets.

@johnoscott
Created October 3, 2012 10:28
Show Gist options
  • Save johnoscott/3826273 to your computer and use it in GitHub Desktop.
Save johnoscott/3826273 to your computer and use it in GitHub Desktop.
test
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
<title>Pizza.com.au</title>
<!-- CSS -->
<!-- from view-source:http://twitter.github.com/bootstrap/examples/starter-template.html -->
<!-- Le styles -->
<link href="css/bootstrap.css" rel="stylesheet">
<style>
body {
padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
}
</style>
<link href="css/bootstrap-responsive.css" rel="stylesheet">
<link href="css/docs.css" rel="stylesheet">
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- Le fav and touch icons -->
<link rel="shortcut icon" href="../assets/ico/favicon.ico">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="../assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="../assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="../assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="../assets/ico/apple-touch-icon-57-precomposed.png">
<!------------------------------------------------------------------------------------------------
-- SCRIPTS -->
<!-- JQuery is NOT USED -->
<!--
<script src="lib/jquery-1.7.2.min.js"></script>
<script src="lib/jquery.mobile-1.1.1.min.js"></script>
<script src="lib/jquery-mobile-angular-adapter-1.1.0-min.js"></script>
-->
<!-- Angular -->
<script src="lib/angular.min.js"></script>
<script src="lib/angular-resource.min.js"></script>
<!-- Google Maps -->
<script src="http://maps.googleapis.com/maps/api/js?sensor=true&libraries=places"></script>
<!-- PhoneGap -->
<script src="lib/cordova-2.0.0.js"></script>
<!-- Application Scripts -->
<script src="js/map.js"></script>
</head>
<!-- TEMPLATE BODY
This is the master page template
The ng-view element is where Angular switches the views for us
-->
<body ng-controller="MainCtrl" id="MainCtrl">
<div class="navbar navbar-fixed-top" ng-cloak ng-show="!page.headerHidden()">
<div class="navbar-inner">
<div class="container">
<p class="brand">{{page.title()}}</p>
<ul class="nav pull-right">
<li class="active"><a href="#/home"><i class="icon-home"></i></a></li>
</ul>
<!--<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">-->
<!--<span class="icon-bar"></span>-->
<!--<span class="icon-bar"></span>-->
<!--<span class="icon-bar"></span>-->
<!--</a>-->
<!--<div class="nav-collapse collapse">-->
<!--<ul class="nav">-->
<!--<li class="active"><a href="#/home">Home</a></li>-->
<!--<li><a href="#/debug">Debug</a></li>-->
<!--</ul>-->
<!--</div>-->
<!--/.nav-collapse -->
</div>
</div>
</div>
<!-- Angular routed view -->
<ng-view>
</ng-view>
<!--<div ng-view id="panel" class="container" >-->
<!--Loading...-->
<!--</div>-->
<!--
<div class="footer" selected="true">
<p><a ng-click="showHide=!showHide;page.setHeaderVisibility(showHide);">Toggle State: {{showHide}}</a></p>
<span ng-show="showHide">Show</span>
<span ng-hide="showHide">Hide</span>
<p>headerVisible: {{page.headerVisible()}}</p>
</div>
-->
<!-- Inline Views -->
<!-- TEMPLATE Home -->
<script type=text/ng-template id=home.html>
<div id="panelHome" class="container" >
<ul class="thumbnails">
<li class="span2">
<img src="img/pizza-logo-home-med.png" >
</li>
</ul>
<h1>{{user.name}} Start Your Order</h1>
<ul ng-show="!isLoggedIn()" class="nav nav-list bs-docs-sidenav">
<li><a href="#/register"><i class="icon-chevron-right"></i>Register as a new Customer</a></li>
<li><a href="#/login"><i class="icon-chevron-right"></i>Login </a></li>
</ul>
<ul ng-show="isLoggedIn()" class="nav nav-list bs-docs-sidenav">
<li><a href="#/shops/delivery" ><i class="icon-chevron-right"></i>Delivery</a></li>
<li><a href="#/shops/pickup"><i class="icon-chevron-right"></i>Pickup</a></li>
</ul>
<!--<a class="greenButton" href="#/login" ng-show="!isLoggedIn()">Login / Register</a>-->
<ul ng-show="isLoggedIn()" class="nav nav-list bs-docs-sidenav">
<li><a href="#/orders"><i class="icon-chevron-right"></i>Your Orders</a></li>
<li><a href="#/account"><i class="icon-chevron-right"></i>Account Settings</a></li>
</ul>
<a class="btn btn-large btn-block btn-primary" ng-click="doLogout()" ng-show="isLoggedIn()">Logout</a>
<blockquote>
<p>v8
| <a href="#/debug-command/fake" >Login as Test User</a>
</p>
</blockquote>
</div>
</script>
<!-- TEMPLATE Register -->
<script type=text/ng-template id=register.html>
<div id="registerHome" class="container" >
<form name="registrationForm" class="form-horizontal" ng-submit="submit()">
<div class="control-group">
<label class="control-label">First Name</label>
<div class="controls controls-row">
<input type="text" name="userName" class="input-large" ng-model="user.name" required>
<span class="help-inline" ng-show="registrationForm.userName.$error.required">Required!</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Last name</label>
<div class="controls controls-row">
<input type="text" name="lastName" class="input-large" ng-model="user.last" ng-minlength="3" ng-maxlength="50" required>
<span class="help-inline" ng-show="registrationForm.lastName.$error.required">Required!</span>
<span class="help-inline" ng-show="registrationForm.lastName.$error.minlength">Too short!</span>
<span class="help-inline" ng-show="registrationForm.lastName.$error.maxlength">Too long!</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Mobile</label>
<div class="controls controls-row">
<div class="input-prepend">
<span class="add-on"><i class="icon-signal"></i></span>
<input name="mobile" type="tel" class="mobile input-medium" ng-model="user.mobile"
ng-minlength="10" ng-maxlength="10" placeholder="04..." required>
</div>
<span class="help-inline" ng-show="registrationForm.mobile.$error.required">10 digits</span>
<span class="help-inline" ng-show="registrationForm.mobile.$error.tel"> numbers only</span>
<span class="help-inline" ng-show="registrationForm.mobile.$error.minlength">Too short!</span>
<span class="help-inline" ng-show="registrationForm.mobile.$error.maxlength">Too long!</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Email</label>
<div class="controls controls-row">
<div class="input-prepend">
<span class="add-on"><i class="icon-envelope"></i></span>
<input name="email" type="email" class="input-medium" ng-model="user.email" required>
</div>
<span class="help-inline" ng-show="registrationForm.email.$error.required">Required!</span>
<span class="help-inline" ng-show="registrationForm.email.$error.email" >Not valid email!</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Create a PIN</label>
<div class="controls controls-row">
<div class="input-prepend">
<span class="add-on"><i class="icon-th"></i></span>
<input name="pin" type="tel" class="pin input-mini" id="registrationPin" ng-model="user.pin" ng-minlength="4" ng-maxlength="4" required>
</div>
<span class="help-inline" ng-show="registrationForm.pin.$error.required">4 digits</span>
<span class="help-inline" ng-show="registrationForm.pin.$error.minlength">Too short!</span>
<span class="help-inline" ng-show="registrationForm.mobile.$error.tel"> numbers only</span>
<span class="help-inline" ng-show="registrationForm.pin.$error.maxlength">Too long!</span>
</div>
</div>
<div class="form-actions">
<span class="error" ng-show="!registrationForm.$valid">Complete all fields</span>
<button class="btn btn-large btn-block"
type=submit
ng-model="button"
ng-class="{'btn-success':registrationForm.$valid}"
ng-disabled="!registrationForm.$valid"
>Register</button>
</div>
<!--<code>{{pin}}</code>-->
<!--<code>registrationForm.$valid = {{registrationForm.$valid}}</code><br/>-->
<!--<code>registrationForm.$error.valid = {{registrationForm.$error.valid}}</code><br/>-->
<!--<code>registrationForm.$error.required = {{!!registrationForm.$error.required}}</code><br/>-->
<!--<p>Fields</p>-->
<!--<code>!!registrationForm.$error.required = {{!!registrationForm.$error.required}}</code><br/>-->
<!--<code>!!registrationForm.email.$error = {{!!registrationForm.email.$error}}</code><br/>-->
<!--<code>registrationForm.email.$error = {{registrationForm.email.$error}}</code><br/>-->
<!--<code>registrationForm.pin.$error = {{registrationForm.pin.$error}}</code><br/>-->
<!--<code>registrationForm.pin = {{registrationForm.pin}}</code><br/>-->
<!--<code>registrationForm.mobile.$error = {{registrationForm.mobile.$error}}</code><br/>-->
</form>
</div>
</script>
<!-- TEMPLATE Login -->
<script type=text/ng-template id=login.html>
<div id="loginHome" class="container" >
<form name="loginForm" class="form-horizontal" ng-submit="submit()">
<div class="control-group">
<label class="control-label">Mobile</label>
<span class="error" ng-show="loginForm.mobile.$error.required">10 digits</span>
<div class="controls controls-row">
<div class="input-prepend">
<span class="add-on"><i class="icon-signal"></i></span>
<input name="mobile" type="tel" class="mobile input-medium" ng-model="user.mobile"
ng-minlength="10" ng-maxlength="10" placeholder="04..." required>
</div>
<span class="help-inline" ng-show="loginForm.mobile.$error.tel">numbers only</span>
<span class="help-inline" ng-show="loginForm.mobile.$error.minlength">Too short!</span>
<span class="help-inline" ng-show="loginForm.mobile.$error.maxlength">Too long!</span>
</div>
</div>
<div class="control-group">
<label class="control-label">PIN</label>
<div class="controls controls-row">
<div class="input-prepend">
<span class="add-on"><i class="icon-th"></i></span>
<input name="pin" type="tel" class="pin input-mini" id="loginPin" ng-model="user.pin" ng-minlength="4" ng-maxlength="4" required>
</div>
<span class="help-inline" ng-show="registrationForm.pin.$error.required">4 digits</span>
<span class="help-inline" ng-show="registrationForm.pin.$error.minlength">Too short!</span>
<span class="help-inline" ng-show="registrationForm.mobile.$error.tel"> numbers only</span>
<span class="help-inline" ng-show="registrationForm.pin.$error.maxlength">Too long!</span>
</div>
</div>
<div class="form-actions">
<span class="error" ng-show="!loginForm.$valid">Complete all fields</span>
<button class="btn btn-large btn-block"
type=submit
ng-model="button"
ng-class="{'btn-success':loginForm.$valid}"
ng-disabled="!loginForm.$valid"
>Login</button>
</div>
<!--<code>{{pin}}</code>-->
<!--<code>loginForm.$valid = {{loginForm.$valid}}</code><br/>-->
<!--<code>loginForm.$error.valid = {{loginForm.$error.valid}}</code><br/>-->
<!--<code>loginForm.$error.required = {{!!loginForm.$error.required}}</code><br/>-->
<!--<p>Fields</p>-->
<!--<code>!!loginForm.$error.required = {{!!loginForm.$error.required}}</code><br/>-->
<!--<code>!!loginForm.email.$error = {{!!loginForm.email.$error}}</code><br/>-->
<!--<code>loginForm.email.$error = {{loginForm.email.$error}}</code><br/>-->
<!--<code>loginForm.pin.$error = {{loginForm.pin.$error}}</code><br/>-->
<!--<code>loginForm.pin = {{loginForm.pin}}</code><br/>-->
<!--<code>loginForm.mobile.$error = {{loginForm.mobile.$error}}</code><br/>-->
</form>
</div>
</script>
<!-- TEMPLATE Account -->
<script type=text/ng-template id=account.html>
<div id="profileHome" class="container" >
<h2>Personal</h2>
<table class="table table-bordered table-striped">
<tr><td>Name:</td><td> {{user.name}} {{user.last}}</td>
<tr><td>Mobile:</td><td> {{user.mobile}}</td>
<tr><td>Email:</td><td>{{user.email}}</td>
<tr><td colspan="2"><a class="btn btn-large btn-block" href="#/account/edit">Edit</a></td>
</table>
<h2>Delivery Address</h2>
<ul class="nav nav-list bs-docs-sidenav">
<li ng-repeat="address in addresses">
<a href="#/address/{{address._id}}"><i class="icon-chevron-right"></i>{{address.street}} {{address.suburb}}</a>
</li>
<li><a class="btn btn-large btn-block" href="#/address/add" >Add a Delivery Address</a></li>
</ul>
<h2>Payment Methods</h2>
<ul class="nav nav-list bs-docs-sidenav">
<li ng-repeat="paymentMethod in paymentMethods">
<a href="#/paymentMethod/{{paymentMethod._id}}">
<i class="icon-chevron-right"></i>
<img src="img/{{paymentMethod.cardType}}.png">
Expires: {{paymentMethod.expiry}}
</a>
</li>
<li><a class="btn btn-large btn-block" href="#/paymentMethod/add" >Add a Payment Method</a></li>
</ul>
<h2>Order History</h2>
<ul class="nav nav-list bs-docs-sidenav">
<li><a href="#/orders"><i class="icon-chevron-right"></i>Your Orders</a></li>
</ul>
</div>
</script>
<!-- TEMPLATE Account Edit -->
<script type=text/ng-template id=account-edit.html>
<div id="accountEdit" class="container" >
<div class="alert alert-success" ng-show="result=='success'">
Updated OK
</div>
<form name="accountForm" class="form-horizontal" ng-submit="submit()">
<div class="control-group">
<label class="control-label">First Name</label>
<div class="controls controls-row">
<input type="text" name="userName" class="input-large" ng-model="user.name" required>
<span class="help-inline" ng-show="accountForm.userName.$error.required">Required!</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Last name</label>
<div class="controls controls-row">
<input type="text" name="lastName" class="input-large" ng-model="user.last" ng-minlength="3" ng-maxlength="50" required>
<span class="help-inline" ng-show="accountForm.lastName.$error.required">Required!</span>
<span class="help-inline" ng-show="accountForm.lastName.$error.minlength">Too short!</span>
<span class="help-inline" ng-show="accountForm.lastName.$error.maxlength">Too long!</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Mobile</label>
<div class="controls controls-row">
<div class="input-prepend">
<span class="add-on"><i class="icon-signal"></i></span>
<input name="mobile" type="tel" class="mobile input-medium" ng-model="user.mobile"
ng-minlength="10" ng-maxlength="10" placeholder="04..." required>
</div>
<span class="help-inline" ng-show="accountForm.mobile.$error.required">10 digits</span>
<span class="help-inline" ng-show="accountForm.mobile.$error.tel"> numbers only</span>
<span class="help-inline" ng-show="accountForm.mobile.$error.minlength">Too short!</span>
<span class="help-inline" ng-show="accountForm.mobile.$error.maxlength">Too long!</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Email</label>
<div class="controls controls-row">
<div class="input-prepend">
<span class="add-on"><i class="icon-envelope"></i></span>
<input name="email" type="email" class="input-medium" ng-model="user.email" required>
</div>
<span class="help-inline" ng-show="accountForm.email.$error.required">Required!</span>
<span class="help-inline" ng-show="accountForm.email.$error.email" >Not valid email!</span>
</div>
</div>
<div class="control-group">
<label class="control-label">Change Your PIN</label>
<div class="controls controls-row">
<div class="input-prepend">
<span class="add-on"><i class="icon-th"></i></span>
<input name="pin" type="tel" class="pin input-mini" id="accountPin" ng-model="user.pin" ng-minlength="4" ng-maxlength="4" required>
</div>
<span class="help-inline" ng-show="accountForm.pin.$error.required">4 digits</span>
<span class="help-inline" ng-show="accountForm.pin.$error.minlength">Too short!</span>
<span class="help-inline" ng-show="accountForm.mobile.$error.tel"> numbers only</span>
<span class="help-inline" ng-show="accountForm.pin.$error.maxlength">Too long!</span>
</div>
</div>
<div class="form-actions">
<span class="error" ng-show="!accountForm.$valid">Complete all fields</span>
<button class="btn btn-large btn-block"
type=submit
ng-model="button"
ng-class="{'btn-success':accountForm.$dirty && accountForm.$valid}"
ng-disabled="!accountForm.$valid || accountForm.$pristine || submitting"
>Update</button>
</div>
<code>_id={{user._id}}</code>
<!--<code>{{pin}}</code>-->
<!--<code>accountForm.$valid = {{accountForm.$valid}}</code><br/>-->
<!--<code>accountForm.$error.valid = {{accountForm.$error.valid}}</code><br/>-->
<!--<code>accountForm.$error.required = {{!!accountForm.$error.required}}</code><br/>-->
<!--<p>Fields</p>-->
<!--<code>!!accountForm.$error.required = {{!!accountForm.$error.required}}</code><br/>-->
<!--<code>!!accountForm.email.$error = {{!!accountForm.email.$error}}</code><br/>-->
<!--<code>accountForm.email.$error = {{accountForm.email.$error}}</code><br/>-->
<!--<code>accountForm.pin.$error = {{accountForm.pin.$error}}</code><br/>-->
<!--<code>accountForm.pin = {{accountForm.pin}}</code><br/>-->
<!--<code>accountForm.mobile.$error = {{accountForm.mobile.$error}}</code><br/>-->
</form>
</div>
</script>
<!-- TEMPLATE Shops -->
<script type=text/ng-template id=shops.html>
<div id="panelShops" class="container" >
<ul class="nav nav-list bs-docs-sidenav">
<li ng-repeat="shop in shops">
<!-- href="#/shop/{{shop._id}}/menu" -->
<a ng-click="goMenu(shop)"><i class="icon-chevron-right"></i>
{{shop.name}}
<small>, {{shop.suburb}}</small>
</a>
<!--<br><span style="font-size: smaller; font-weight: normal;">{{shop.suburb}}</span>-->
</li>
</ul>
</div>
<div class="toolbar fixed-bottom">
<a class="btn btn-large btn-block btn-primary" href="#/map">Show on Map</a>
</div>
</script>
<!-- TEMPLATE Map -->
<script type=text/ng-template id=map.html>
<!-- TODO Map is not visble -->
<div id="container" >
<div id="map_canvas"></div>
</div>
<div class="toolbar fixed-bottom">
<a class="btn btn-large btn-block btn-primary" href="#/shops/pickup">Show as List</a>
</div>
</script>
<style>
#mapContainer {
position: absolute;
/*border: 3px solid #971111;*/
top: 45px;
right: 0;
bottom: 0;
left: 0;
background-color: #DDD;
}
#mapContainer.headerHide {
top:0;
}
#map_canvas {
/*width: 100%;*/
height: 100%;
/*top: 28px;*/
left: 0;
/*border: 1px solid grey;*/
/*background-color: #E5E3DF;*/
overflow: hidden;
}
#rating {
font-size: 24px;
font-family: Arial Unicode MS;
}
.iw_table_row {
height: 18px;
}
.iw_attribute_name {
font-weight: bold;
text-align: right;
}
</style>
<!-- TEMPLATE MENU + CART-->
<script type=text/ng-template id=menu.html>
<div id="menu" class="container" >
<fieldset ng-repeat="category in menuItems" class="menu-cat menu-items">
<!--<li>-->
<!--<span class="menu-item-heading" ng-click=>&nbsp;</span>-->
<!--<span class="menu-item-SMALL" ng-click="">&nbsp; </span>-->
<!--<span class="menu-item-MED" ng-click="">&nbsp; </span>-->
<!--<span class="menu-item-LAR" ng-click="">&nbsp; </span>-->
<!--<span class="menu-item-FAMILY" ng-click="">&nbsp; </span>-->
<!--</li>-->
<ul class="menu-items">
<li class="menu-cat-heading">
{{category.name}}
<span ng-repeat="choice in category.choices" class="menu-item-heading">
{{choice}}
</span>
</li>
<li ng-repeat="item in category.items">
<b>{{item.name}}</b>
<!--<span class="menu-item-picker" ng-class="{itemPicked:item.picked}">-->
<!--<input type="checkbox" ng-model="item.picked" >-->
<!--{{item.picked}}-->
<!--</span>-->
<span ng-repeat="variation in item.variations"
class="menu-item-{{variation.code}}"
ng-class="{variationPicked:variation.picked}"
ng-click="addItem(item, variation); variation.picked=true">
<span class=dollar>$</span>
{{variation.price | dollar}}
<!--<input type="checkbox" ng-model="variation.picked" >-->
</span>
<br>{{item.description}}
<!--<input type="checkbox" ng-model="item.picked" >-->
</li>
</ul>
</fieldset>
<!--<div class="menu-bottom">-->
<!--&nbsp;-->
<!--</div>-->
<!--<div class="navbar navbar-inverse navbar-fixed-bottom">-->
<!--<div class="navbar-inner">-->
<!--<div class="container">-->
<!--<a class="btn btn-large btn-success" href="#/checkout/{{shop._id}}">-->
<!--<i class="icon-shopping-cart icon-white"></i>-->
<!--{{cart.total()|currency}}-->
<!--Checkout</a>-->
<!--</div>-->
<!--</div>-->
<!--</div>-->
</div>
<div class="cartSummary">
<div ng-repeat="variation in cart.items()" class=cartItem>
<span class=cartItemPrice>
{{cart.subTotal(variation)|currency}}
</span>
<span class=cartItemRemove>
<a class="btnRemove" ng-click="removeVariation(variation)"></a>
</span>
<span class=cartItemQty>
<select ng-model="variation.qty" ng-options="n for n in quantityOptions" class="input-mini">
</select>
</span>
<span class=cartItemName>{{variation.description}} {{variation.item.name}}</span>
</div>
<!-- TODO Disable button when cart is empty -->
<a class="btn btn-block btn-large btn-success" href="#/checkout/{{shop._id}}">
<i class="icon-shopping-cart icon-white"></i>
{{cart.total()|currency}}
Checkout
</a>
</div>
</script>
<style>
.menu-bottom {
/*background: #ffb6c1;*/
padding-bottom: 200px;
}
.menu-cat {
background: white;
margin: 10px 0px;
}
.menu-cat-heading {
background-color: #d9d9d9;
font-size: 1.2em;
/*border: thin solid #666;*/
}
.menu-items > li {
/*background-color: #FF0;*/
margin-left: 0px;
border-bottom-style: solid;
border-bottom-width: 1px;
border-bottom-color: #CCC;
}
ul.menu-items {
list-style-type: none;
margin: 0 auto;
padding-left: 0px;
padding: 0;
}
ul.menu-items > li
{
/*border:1px solid #c96000;*/
/*width:300px;*/
/*float:left;*/
padding: 10px 0px;
clear: both;
}
ul.menu-items > li > span
{
float:right;
width:54px;
height:46px;
/*border:1px solid #e5e5e5;*/
padding: 0px 0px 0px 0px;
margin: 0px 0px 0px 5px;
text-align: center;
line-height:3em;
;
}
span.dollar {
font-size: small;
color: #404040;
/*vertical-align: super;*/
}
ul.menu-items > li > span.menu-item-heading {
height:20px;
/*border:1px solid #e5e5e5;*/
line-height:2em;
font-weight: bold;
}
.itemPicked {
background: #fffa16;
}
ul.menu-items > li > span.variationPicked {
/*border:1px solid #c96000;*/
}
ul.menu-items > li > span.variationPicked.menu-item-MED {
background: #ffe6cf;
background: url("img/pizza-medium-picked.png") no-repeat center center;
}
ul.menu-items > li > span.variationPicked.menu-item-LAR {
background: #ffe6cf;
background: url("img/pizza-large-picked.png") no-repeat center center;
}
ul.menu-items > li > span.variationPicked.menu-item-FAM {
background: #ffe6cf;
background: url("img/pizza-family-picked.png") no-repeat center center;
}
ul.menu-items > li > span.variationPicked.menu-item-SRV {
background: #ffe6cf;
background: url("img/serve-picked.png") no-repeat center center;
}
ul.menu-items > li > span.menu-item-picker {
width:40px;
}
ul.menu-items > li > span.menu-item-heading {
width:50px;
font-size: x-small;
}
.menu-item-LAR {
background: url("img/pizza-large.png") no-repeat center center;
}
.menu-item-MED {
background: url("img/pizza-medium.png") no-repeat center center;
}
.menu-item-SMALL {
background: url("img/pizza-small.png") no-repeat center center;
}
.menu-item-FAM {
background: url("img/pizza-family.png") no-repeat center center;
}
.menu-item-SRV {
background: url("img/serve.png") no-repeat center center;
}
div.cartSummary {
position:fixed;
bottom:0px;
background-color: #626262;
width:100%;
margin-bottom: 0px;
margin-left: -20px;
margin-right: -20px;
margin-top: 20px;
padding:0;
text-align:center;
color: white;
font-size: small;
max-height: 50%;
}
.cartSummary > p {
list-style: none;
margin:2px;
padding:0;
}
.cartSummary > div {
height:40px;
margin:2px;
padding:0;
clear: both;
}
.cartSummary > div > span
{
height:46px;
/*border:1px solid #e5e5e5;*/
padding: 0px 0px 0px 0px;
margin: 0px 0px 0px 5px;
text-align: center;
line-height:3em;
}
.cartSummary > div > span.cartItemName
{
float:left;
/*width:200px;*/
}
.cartSummary > div > span.cartItemPrice
{
float:right;
width:60px;
}
.cartSummary > div > span.cartItemQty
{
float:left;
}
.cartSummary > div > span.cartItemRemove
{
float:right;
width:24px;
}
.btnRemove {
position: absolute;
background: url("img/remove.png") no-repeat center center;
overflow: hidden;
margin-top: 12px;
/*padding: 0 0px;*/
width: 24px;
height: 24px;
/*border:1px solid #fffa16;*/
}
</style>
<!-- TEMPLATE CHECKOUT -->
<script type=text/ng-template id=checkout.html>
<div id="panelCheckout" class="container" >
<h2>{{shop.name}}</h2>
<h5>{{shop.suburb}}</h5>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Your {{method}} Order</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="variation in cart.items()">
<td>
{{variation.qty}} x {{variation.description}} {{variation.item.name}}
</td>
<td>
${{variation.price}}
</td>
</tr>
<tr>
<td>
<b>Total</b>
</td>
<td>
<b>${{cart.total()}}</b>
</td>
</tr>
</tbody>
</table>
<form name="submitOrderForm" class="form-horizontal" ng-submit="submitOrder()">
<div class="control-group" ng-show="method=='delivery'">
<label class="control-label">Deliver To</label>
<div class="controls controls-row">
<select ng-model="selectedAddress"
ng-options="n.street + ' ' + n.suburb for n in addresses"
class="input-large"
ng-show="addresses.length>0"
ng-required="method=='delivery'">
</select>
<a class="btn" href="#/address/add" >Add a Delivery Address</a>
</div>
</div>
<div class="control-group">
<label class="control-label">Payment Method <img src="img/{{selectedPaymentMethod.cardType}}.png"></label>
<div class="controls controls-row">
<select ng-model="selectedPaymentMethod"
ng-options="n.cardType + ' Expires: ' + n.expiry for n in paymentMethods"
class="input-large"
ng-show="paymentMethods.length>0"
required>
</select>
<a class="btn" href="#/paymentMethod/add" >Add a Payment Method</a>
</div>
</div>
<div class="control-group">
<label class="control-label">Enter your 4-digit PIN</label>
<div class="controls controls-row">
<div class="input-prepend">
<span class="add-on"><i class="icon-th"></i></span>
<input name="pin" type="tel" class="pin input-mini"
id="submitOrderPin" ng-model="user.pin" ng-minlength="4" ng-maxlength="4" required>
</div>
</div>
</div>
<div class="form-actions">
<button class="btn btn-large btn-block"
type=submit
ng-model="button"
ng-class="{'btn-success':submitOrderForm.$valid}"
ng-disabled="!submitOrderForm.$valid"
>Pay Now</button>
</div>
</form>
</div>
</script>
<!-- TEMPLATE SENDING ORDER -->
<script type=text/ng-template id=submit.html>
<div id="panelSubmit" class="container" >
<fieldset>
<div class="body-above-footer">
<h1>Sending Order...</h1>
<div class="center-wrapper">
<img src="img/pizza-anim-strip.gif" width="400" height="112">
</div>
</div>
</fieldset>
</div>
</script>
<!-- TEMPLATE CONFIRMED ORDER -->
<script type=text/ng-template id=confirmed.html>
<div id="panelConfirmed" class="container" >
<fieldset>
<div class="body-above-footer">
<h1>Order #{{order.number}} Confirmed</h1>
<p>Thanks for your order.</p>
<h2>{{order.shop.name}}</h2>
<p>{{order.shop.address}} {{order.shop.suburb}}</p>
<p>If you need to follow up on your order please call the shop direct.</p>
<p>Phone: {{order.shop.phone}}</p>
<h2>Your {{order.method}} Order
{{order.deliverTo.streetAddress}}
{{order.deliverTo.suburb}}</h2>
<ul style="font-size: smaller; font-weight: normal;">
<li ng-repeat="item in order.items">
{{item.qty}}x {{item.variation}} {{item.name}} {{item.category}}<br>
</li>
</ul>
</div>
</fieldset>
</div>
<div class="toolbar fixed-bottom" >
<a class="btn btn-large btn-block btn-primary" href="#/home"> Home</a>
</div>
</script>
<!-- TEMPLATE ORDERS -->
<script type=text/ng-template id=orders.html>
<div id="panelOrders" class="container" >
<h1>{{user.name}}'s Orders</h1>
<ul class="nav nav-list bs-docs-sidenav">
<li ng-repeat="order in orders">
<!-- href="#/shop/{{shop.id}}/menu" -->
<a href="#/order/{{order._id}}">
<i class="icon-chevron-right"></i>
{{order.shop.name}} <br>
<span style="font-size: smaller; font-weight: normal;">
A {{order.method}} order placed at {{order.time}} on {{order.date}}<br>
<!--<span ng-repeat="item in order.items">-->
<!--{{item.qty}}x {{item.variation}} {{item.name}} {{item.category}}<br>-->
<!--</span>-->
</span>
</a>
</li>
</ul>
</div>
</script>
<!-- TEMPLATE VIEW ORDER -->
<script type=text/ng-template id=viewOrder.html>
<div id="panelViewOrder" class="container" >
<h1>{{order.shop.name}}</h1>
<table class="table table-bordered table-striped">
<tr>
<td>Order Num</td>
<td>{{order.number}}</td>
</tr>
<tr>
<td>Placed at</td>
<td>{{order.time}} on {{order.date}}</td>
</tr>
<tr>
<td>Method</td>
<td>{{order.method}}</br>
{{order.deliverTo.streetAddress}}
{{order.deliverTo.suburb}}</td>
</tr>
</table>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Your Order</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in order.items">
<td>
{{item.qty}}x {{item.variation}} {{item.name}} {{item.category}}
</td>
</tr>
<tr>
<td>
<a class="btn btn-large btn-block btn-primary" ng-click="doReorder()" >Re-Order</a>
</td>
</tr>
</tbody>
</table>
<h2>Shop Contact</h2>
<p>{{order.shop.name}}</p>
<p>{{order.shop.address}} {{order.shop.suburb}}</p>
<a class="btn btn-large" >
<i class="icon-bullhorn"></i>
{{order.shop.phone}}
</a>
</div>
</script>
<!-- TEMPLATE Address Add / Edit -->
<script type=text/ng-template id=address.html>
<div id="addressAddEdit" class="container" >
<div class="alert alert-success" ng-show="result=='success'">
Updated OK
</div>
<form name="addressForm" class="form-horizontal" ng-submit="submit()">
<div class="control-group">
<label class="control-label">Street (Unit / Number Street)</label>
<div class="controls controls-row">
<input type="text" name="street" class="input-large" ng-model="address.street"
ng-minlength="3" ng-maxlength="50" required>
</div>
</div>
<div class="control-group">
<label class="control-label">Suburb</label>
<div class="controls controls-row">
<input type="text" name="suburb" class="input-large" ng-model="address.suburb"
ng-minlength="3" ng-maxlength="50" required>
</div>
</div>
<div class="control-group">
<label class="control-label">Postcode</label>
<div class="controls controls-row">
<input type="text" name="suburb" class="input-mini" ng-model="address.postcode"
ng-minlength="3" ng-maxlength="4" required>
</div>
</div>
<div class="form-actions">
<span class="error" ng-show="!addressForm.$valid">Complete all fields</span>
<button class="btn btn-large btn-block"
type=submit
ng-model="button"
ng-class="{'btn-success':addressForm.$dirty && addressForm.$valid}"
ng-disabled="!addressForm.$valid || addressForm.$pristine || busy"
>{{buttonLabel}}</button>
</div>
<code ng-show="address._id">_id={{address._id}}</code>
<!--<code>{{pin}}</code>-->
<!--<code>addressForm.$valid = {{addressForm.$valid}}</code><br/>-->
</form>
</div>
</script>
<!-- TEMPLATE PaymentMethod Add / Edit -->
<script type=text/ng-template id="payment-method.html">
<div id="paymentMethodAddEdit" class="container" >
<div class="alert alert-success" ng-show="result=='success'">
Updated OK
</div>
<form name="paymentMethodForm" class="form-horizontal" ng-submit="submit()">
<div class="control-group">
<label class="radio inline">
<input type="radio" name="cardType" id="visaRadio" value="visa"
ng-model="paymentMethod.cardType">
<img src="img/visa.png">
</label>
<label class="radio inline">
<input type="radio" name="cardType" id="mastercardRadio" value="mastercard"
ng-model="paymentMethod.cardType">
<img src="img/mastercard.png">
</label>
</div>
<div class="control-group">
<label class="control-label">Card Number</label>
<div class="controls controls-row">
<input type="text" name="street" class="input-large" ng-model="paymentMethod.cardNumber"
ng-minlength="3" ng-maxlength="50" required>
</div>
</div>
<div class="control-group">
<label class="control-label">Expiry</label>
<div class="controls controls-row">
<input type="text" name="suburb" class="input-large" ng-model="paymentMethod.expiry"
ng-minlength="3" ng-maxlength="50" required>
</div>
</div>
<div class="control-group">
<label class="control-label">CID</label>
<div class="controls controls-row">
<input type="text" name="suburb" class="input-mini" ng-model="paymentMethod.cid"
ng-minlength="3" ng-maxlength="4" required>
</div>
</div>
<div class="form-actions">
<span class="error" ng-show="!paymentMethodForm.$valid">Complete all fields</span>
<button class="btn btn-large btn-block"
type=submit
ng-model="button"
ng-class="{'btn-success':paymentMethodForm.$dirty && paymentMethodForm.$valid}"
ng-disabled="!paymentMethodForm.$valid || paymentMethodForm.$pristine || busy"
>{{buttonLabel}}</button>
</div>
<code ng-show="paymentMethod._id">_id={{paymentMethod._id}}</code>
<!--<code>{{pin}}</code>-->
<!--<code>paymentMethodForm.$valid = {{paymentMethodForm.$valid}}</code><br/>-->
</form>
</div>
</script>
<!-- DebugCommand -->
<script type=text/ng-template id=debug-command.html>
<!-- TEMPLATE DebugCommand -->
<div id="panelDebugCommand" class="container" >
<h1>Command : <i>{{action}}</i></h1>
</div>
</script>
<!-- Debug -->
<script type=text/ng-template id=debug.html>
<!-- TEMPLATE Debug -->
<div id="panelDebug" class="container" >
<h2>{{orders.length}} Orders</h2>
<ul>
<li ng-repeat="order in orders">
<!-- href="#/shop/{{shop._id}}/menu" -->
<a ng-click="viewOrder(order)">{{order.customer.name}} <br>
<ul style="font-size: smaller; font-weight: normal;">
<li ng-repeat="item in order.items">
{{item.variation}} {{item.name}} {{item.category}}
</li>
</ul>
</a>
</li>
</ul>
</div>
</script>
<script>
// Utilities
var StringUtil = {
// Repeat
// http://stackoverflow.com/questions/4549894/how-can-i-repeat-strings-in-javascript
// Usage: ar s = StringUtilities.repeat("&nbsp;", 3);
repeat: function(str, times) {
return (new Array(times + 1)).join(str);
}
//other related string functions...
};
</script>
<script>
'use strict';
// preferences
var Prefs = {
alwaysShowNav : true
};
Prefs.resource = {
baseURL:"http://pizza.com.au",
useRemote : false
// TODO - Set BASE URL Automatically
}
Prefs.getResourceBaseUrl = function() {
var u = "";
if (Prefs.resource.useRemote) {
u = Prefs.resource.baseURL;
}
return u
}
console.log("resourceBaseUrl = " + Prefs.getResourceBaseUrl())
/* App Module */
angular.module('app', ['ngResource'])
.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
// console.log("app.config");
// $locationProvider.jqmCompatMode(false);
// SERVICE ~ ROUTES
$routeProvider.
when('/home', {templateUrl: 'home.html', controller: HomeController}).
when('/login', {templateUrl: 'login.html', controller: LoginController}).
when('/register', {templateUrl: 'register.html', controller: RegisterController}).
when('/account', {templateUrl: 'account.html', controller: AccountController}).
when('/account/edit', {templateUrl: 'account-edit.html', controller: AccountEditController}).
when('/shops/:mode', {templateUrl: 'shops.html', controller: ShopController}).
when('/map', {templateUrl: 'map.html', controller: MapController}).
when('/shop/:shopId/menu', {templateUrl: 'menu.html', controller: MenuController}).
when('/checkout/:shopId', {templateUrl: 'checkout.html', controller: CheckoutController}).
when('/submit', {templateUrl: 'submit.html', controller: SubmitOrderController}).
when('/confirmed/:orderId', {templateUrl: 'confirmed.html', controller: ConfirmedController}).
when('/orders', {templateUrl: 'orders.html', controller: OrdersController}).
when('/order/:orderId', {templateUrl: 'viewOrder.html', controller: ViewOrderController}).
when('/address/add', {templateUrl: 'address.html', controller: AddressController}).
when('/address/:addressId', {templateUrl: 'address.html', controller: AddressController}).
when('/paymentMethod/add', {templateUrl: 'payment-method.html', controller: PaymentMethodController}).
when('/paymentMethod/:paymentMethodId', {templateUrl: 'payment-method.html', controller: PaymentMethodController}).
when('/debug', {templateUrl: 'debug.html', controller: DebugController}).
when('/debug-command/:action', {templateUrl: 'debug-command.html', controller: DebugCommandController}).
otherwise({redirectTo: '/home'});
}])
// .factory('Order', ['$resource', '$http',
// function($resource, $http) {
// return $resource(Prefs.getResourceBaseUrl() + '/api/orders/:_id', {}, {
// });
// }
// ])
// SERVICE CustomerOrder
.factory('CustomerOrder', ['$resource', '$http',
function($resource, $http) {
return $resource(Prefs.getResourceBaseUrl() + '/api/customer/:customerId/order/:orderId', {}, {
});
}
])
// SERVICE CustomerOrderMgr
.factory('CustomerOrderMgr', ['CustomerOrder',
function(){
var thing = "Untitled";
console.log('CustomerOrderMgr Service init');
return {
title:function(){
return thing;
}
}
}])
// SERVICE DebugOrder
.factory('DebugOrder', ['$resource', '$http',
function($resource, $http) {
return $resource(Prefs.getResourceBaseUrl() + '/api/orders/:_id', {}, {
'count': {method:'PUT', params:{_id: 'count'}},
'distinct': {method:'PUT', params:{_id: 'distinct'}},
'find': {method:'PUT', params:{_id: 'find'}, isArray:true},
'group': {method:'PUT', params:{_id: 'group'}, isArray:true},
'mapReduce': {method:'PUT', params:{_id: 'mapReduce'}, isArray:true} ,
'aggregate': {method:'PUT', params:{_id: 'aggregate'}, isArray:true}
});
}
])
// SERVICE Page
.factory('Page', function(){
var pageTitle = "Untitled";
var isHeaderVisible = true;
console.log('Page Service init');
return {
title:function(){
return pageTitle;
},
getFooterButtonTitle:function(){
return footerButtonTitle;
},
headerHidden:function(){
return !isHeaderVisible;
},
setTitle:function(newTitle){
pageTitle = newTitle;
},
showHeader:function(){
isHeaderVisible = true;
console.log('Page service: showHeader');
},
hideHeader:function(){
isHeaderVisible = false;
console.log('Page service: hideHeader');
},
setHeaderVisibility:function(v){
isHeaderVisible = v;
console.log("Page service: setHeaderVisibility:" + isHeaderVisible);
}
}
})
// SERVICE Shop
.factory('Shop', function($resource){
return $resource('data/:shopId.json', {}, {
query: {method:'GET', params:{shopId:'shops'}, isArray:true}
})
})
// SERVICE ShopMgr
.factory('ShopMgr', function() {
// Private
var user = null;
// Init
console.log('ShopMgr Service init');
// Public Methods
return {
getShopIdentity : function (shop) {
var s = {
"_id": shop._id,
"name": shop.name,
"address": shop.address,
"suburb": shop.suburb,
"postcode": shop.postcode,
"phone" : shop.phone,
"fax" : shop.fax
};
return s;
}
}
})
.filter('dollar', function() {
return function(input) {
var out = '';
if (input % 1) { // modulus 1 of a whole number is zero
out = input.toFixed(2);
} else {
out = input.toString();
}
return out;
}
})
.filter('reverse', function() {
return function(input, uppercase) {
var out = "";
for (var i = 0; i < input.length; i++) {
out = input.charAt(i) + out;
}
// conditional based on optional argument
if (uppercase) {
out = out.toUpperCase();
}
return out;
}
})
// http://goodfil.ms/blog/posts/2012/08/13/angularjs-and-the-goodfilms-mobile-site-part-1/
.directive('pizzaTap', function() {
return function(scope, element, attrs) {
var tapping;
tapping = false;
element.bind('touchstart', function() {
return tapping = true;
});
element.bind('touchmove', function() {
return tapping = false;
});
return element.bind('touchend', function() {
if (tapping) {
return scope.$apply(attrs.pizzaTap);
}
});
};
})
/* SERVICE User
usage: User.save({}, $scope.user, function (res) { if (res.ok === 1) { $location.path("/remote");}})
{
"_id": "1111111111"
"name": "James",
"last": "Demo",
"mobile": "0411111111",
"email": "local@demo.com",
"pin": "1111",
lastAddress : 1,
addresses:[
{_id:1, street:"26 Diamond Rd", suburb:"Mosman", postcode:"2256"},
{_id:2, street:"101 Main Rd", suburb:"Mosman", postcode:"2256"},
]
paymentMethods:[
]
}
*/
.factory('User', ['$resource', '$http',
function($resource, $http) {
return $resource(Prefs.getResourceBaseUrl() + '/api/users/:_id', {}, {
'update' : {method:'PUT'}
// 'count': {method:'PUT', params:{_id: 'count'}},
// query: {method:'GET', params:{phoneId:'phones'}, isArray:true}
});
}
])
// SERVICE Customer
.factory('Customer', ['User',
function(User) {
// Private
var user = null
// Init
console.log('Customer Service init');
return {
setUser : function (u) {
user = u;
},
clearUser : function () {
user = null;
},
getUser : function () {
return user;
},
hasUser : function () {
var h = (user != null);
return (h)
},
login : function (u, callback) {
var that = this;
User.get({_id: u._id}, function (result) {
if (result._id) that.setUser(result);
callback(result);
})
},
logout : function () {
// TODO Call this Logout function
},
getAddresses : function () {
if (user.addresses) {
return user.addresses
}
// return [
// {_id:1, street:"26 Diamond Rd", suburb:"Mosman", postcode:"2256"},
// {_id:2, street:"101 Main Rd", suburb:"Mosman", postcode:"2256"}
// ]
},
getAddress : function (addressId) {
var address, i, addresses = user.addresses;
for (i in addresses) {
address = addresses[i];
if (address._id == addressId) {
return address;
}
}
},
addAddress : function (a, callback) {
if (!user.addresses) user.addresses = []; // create if none exist
a._id = user.addresses.length + 1;
user.addresses.push(a);
// TODO Update leaf (not whole document)
User.update({}, user, callback);
},
updateAddress : function(a, callback) {
// TODO Update leaf (not whole document)
User.update({}, user, callback);
},
getPaymentMethods : function () {
if (user.paymentMethods) {
return user.paymentMethods
}
},
getPaymentMethod : function (methodId) {
var pm, i, paymentMethods = user.paymentMethods;
for (i in paymentMethods) {
pm = paymentMethods[i];
if (pm._id == methodId) {
return pm;
}
}
},
addPaymentMethod : function (pm, callback) {
if (!user.paymentMethods) user.paymentMethods = []; // create if none exist
pm._id = user.paymentMethods.length + 1;
user.paymentMethods.push(pm);
// TODO Update leaf (not whole document)
User.update({}, user, callback);
},
updatePaymentMethod : function(pm, callback) {
// TODO Update leaf (not whole document)
User.update({}, user, callback);
}
}
}
])
// SERVICE Cart
.factory('Cart', function(){
/*
example items = {
"12345-med": {sku:1234, name:"Meatlovers", description:"Large", price:18, qty:1}
"12345-sm": {sku:1234, name:"Meatlovers", description:"Large", price:12, qty:2});
}
cart.add("12345-med", {sku:1234, name:"Meatlovers", description:"Large", price:18, qty:1});
cart.add("12345-sm", {sku:1234, name:"Meatlovers", description:"Large", price:12, qty:1});
cart.add("12345-lar", {sku:1233, name:"Meatlovers", description:"Large", price:20, qty:1});
cart.remove("12345-lar");
*/
console.log('Cart Service init');
// shop
var shop = null;
var method = null;
var methods = ['pickup','delivery']
// var states = {
// 0:"init",
// 1:"building",
// 2:"readyToSend",
// 3:"sending",
// 4:"sent",
// 5:"receivedByShop"
// }
// var state = ''
// cart items closure
var cart = function () {
var len = 0;
var items = {};
var that = this;
return {
add: function(key, value) {
items[key] = value;
len++;
},
remove: function (key) {
if (items.hasOwnProperty(key)) {
delete items[key]; len--; }
},
count: function () {return len;},
clear: function () {items = {}},
total: function () {
var tot = 0;
// var item;
for (var sku in items) {
// item = items[sku];
// tot += eval(item.price) * eval(item.qty);
tot += this.subTotal(sku);
};
console.log("cart.total: " + tot);
return tot;
},
subTotal: function(sku) {
var variation = items[sku];
return eval(variation.price) * eval(variation.qty);
},
get: function (sku) {
return items[sku];
},
all: function () {
// return as an array
var a = [];
for (var sku in items) {
a.push(items[sku]);
};
return a;
}
}
}();
// cart.add("12345-med", {sku:1234, name:"Meatlovers", description:"Large", price:18, qty:1});
// cart.add("12345-sm", {sku:1234, name:"Meatlovers", description:"Large", price:12, qty:1});
// cart.add("12345-lar", {sku:1233, name:"Meatlovers", description:"Large", price:20, qty:1});
// cart.remove("12345-lar");
console.log('Cart Service : cart.count() = ' + cart.count() + ': cart.total() = ' + cart.total());
return {
total:function(){
return cart.total();
},
subTotal:function(i){
return cart.subTotal(i.sku);
},
count:function(){
return cart.count();
},
items:function(){
return cart.all();
},
empty:function(){
cart.clear();
shop = null;
// method = null;
},
add : function (i) {
/*
* {sku:1234, name:"Meatlovers", variation:"Large", price:12.5, qty:1}
*/
var existingItem = cart.get([i.sku]);
if (existingItem) {
existingItem.qty += 1; // increment
} else {
i.qty = 1;
cart.add(i.sku, i);
}
},
subtract : function (i) {
var existingItem = cart.get([i.sku]);
if (existingItem) {
if (existingItem.qty > 1) {
existingItem.qty --; // decrement
} else {
cart.remove(i.sku);
}
}
},
remove : function (i) {
cart.remove(i.sku);
},
getShop : function () {
return shop;
},
setShop : function (s) {
shop = s;
},
// Cart state
setState : function (s) {
// state = s;
},
getState : function() {
return state;
},
setMethod : function(m) {
// pickup or delivery
method = m;
},
getMethod : function() {
return method;
}
}
});
/* Controllers */
// CONTROLLER MainController
function MainCtrl($scope, $window, Page, Cart) {
/* this scope is inherited by any child controllers so is used as a common data model that they can share */
$scope.page = Page; // gets set by each child controller
$scope.cart = Cart;
console.log('MainCtrl init');
// $scope.cart.add({sku:"12345-med", name:"Meatlovers", variation:"Medium", price:18, qty:1});
// $scope.cart.add({sku:"12345-sm", name:"Meatlovers", variation:"Small", price:12, qty:1});
// $scope.cart.add({sku:"12345-lar", name:"Meatlovers", variation:"Large", price:20, qty:1});
// $scope.cart.remove("12345-lar");
console.log('MainCtrl: Cart.count()=' + $scope.cart.count() + " Cart.total()= " + $scope.cart.total() );
// set the header visibility based on the URL's protocol :
// file:// assume we are running within a mobile container like PhoneGap
// http:// assume we are a mobile web app so show the header
console.log("window.location.protocol:" + $window.location.protocol);
if ($window.location.protocol == "file:") {
if (!Prefs.alwaysShowNav) {
console.log('Hiding header because as a file:// URL we assume PhoneGap is running');
Page.hideHeader();
} else {
Page.showHeader();
console.log('Prefs.alwaysShowNav = true forcing header as visble even though we are running file:// URL we assume PhoneGap is running');
}
console.log('Setting Prefs.resource.useRemote = true because we are on a file:// URL we assume PhoneGap is running');
Prefs.resource.useRemote = true;
} else {
Page.showHeader();
}
// If Cordova is running then assume there is a native header and hide ours
// DOMContentLoaded deviceready
$window.document.addEventListener("deviceready", function(){
console.log('Event: deviceready. Hey we are running inside PhoneGap !!');
// Alternative method for hiding toolbar (we actually us file: protocol detection above
// $scope.$apply(function() {
// $scope.hideToolbarHeader();
// });
}, false);
$scope.setToolbarVisibility = function(vis) {
console.log("MainCtrl:setToolbarVisibility: " + vis);
Page.setHeaderVisibility(vis);
}
}
/* View Controllers */
// CONTROLLER HomeController
function HomeController($scope, Page, Customer) {
Page.setTitle("Home");
$scope.user = Customer.getUser();
$scope.isLoggedIn = function() {
var h = true;
h = Customer.hasUser();
return h;
}
$scope.doLogout = function() {
Customer.clearUser();
$scope.user = Customer.getUser();
}
}
// CONTROLLER LoginController
function LoginController($scope, $window, $location, Page, User, Customer) {
Page.setTitle("Login");
$scope.showChoices = false;
$scope.showLogin = true;
// clear the current login
Customer.clearUser();
$scope.doShowLogin = function() {
$scope.showChoices = false;
$scope.showLogin = true;
}
$scope.submit = function() {
var userDebug = JSON.stringify(this.user);
var user = this.user;
console.log("LoginController:submit: " + userDebug);
// user._id is mobile number (for now)
user._id = user.mobile;
Customer.login(user, function (result) {
if (result._id) {
$location.path("/home");
} else {
$window.alert("Error: Could not Login");
}
})
}
}
// CONTROLLER RegisterController
function RegisterController($scope, $location, $window, Page, User, Customer) {
Page.setTitle("Register");
// default form values
// $scope.user = {mobile: '', email: 'user@domain.com'};
$scope.submit = function() {
var userDebug = JSON.stringify(this.user);
var user = this.user;
console.log("RegisterController:submit: " + userDebug);
// mobile : replace the leading zero that was dropped by the number field validation
var mobileStr = user.mobile.toString();
var missingZeroCount = 10 - mobileStr.length;
if (missingZeroCount > 0) {
mobileStr = StringUtil.repeat('0', missingZeroCount) + mobileStr;
}
user.mobile = mobileStr;
// PIN : make a string
var pinStr = user.pin.toString();
missingZeroCount = 4 - pinStr.length;
if (missingZeroCount > 0) {
pinStr = StringUtil.repeat('0', missingZeroCount) + pinStr;
}
user.pin = pinStr;
// user._id is mobile number (for now)
user._id = user.mobile;
var userFixed = JSON.stringify(this.user);
console.log("RegisterController:userFixed: " + userFixed);
User.save({}, user, function (result) {
if (result.ok === 1) {
Customer.setUser(user);
$location.path("/home");
} else {
$window.alert("Error: Could not Register");
}
})
}
}
// CONTROLLER AccountController
function AccountController($scope, $location, $window, Page, Customer) {
Page.setTitle("Account");
if (Customer.hasUser()) {
var user = Customer.getUser();
$scope.user = user;
$scope.addresses = Customer.getAddresses();
$scope.paymentMethods = Customer.getPaymentMethods();
} else {
$location.path("/home");
}
}
// CONTROLLER AccountEditController
function AccountEditController($scope, $location, $timeout, Page, User, Customer) {
Page.setTitle("Account > Edit");
if (Customer.hasUser()) {
var user = Customer.getUser();
$scope.user = user;
} else {
$location.path("/home");
}
$scope.result = '';
$scope.submitting = false;
$scope.submit = function() {
var userDebug = JSON.stringify(this.user);
var user = this.user;
console.log("AccountEditController:submit: " + userDebug);
// disable the form while we submit the update
$scope.submitting = true;
User.update({}, user, function (result) {
if (result.ok === 1) {
Customer.setUser(user);
$scope.result = 'success';
$timeout(function(){$location.path("/account")}, 1000);
} else {
$window.alert("Error: Could not Update");
}
})
}
}
// CONTROLLER ShopController
function ShopController($scope, $routeParams, Shop, Page, Cart, $location) {
var mode = $routeParams.mode;
$scope.mode = mode;
Cart.setMethod(mode); // set the delivery mode of the Cart
$scope.shops = Shop.query();
// $http.get('data/shops.json').success(function(data) {
// $scope.shops = data;
// });
$scope.orderProp = 'name';
Page.setTitle("Shops");
// Cart.empty();
$scope.menu = function(id) {
// alert('Menu for shop: ' + id);
console.log("menu " + id);
$location.path('/shop/' + id + '/menu');
}
$scope.goMenu = function(shop) {
console.log("goMenu " + shop._id);
$location.path('/shop/' + shop._id + '/menu');
}
}
// CONTROLLER MapController
function MapController($scope, $routeParams, Shop, Page, $location) {
Page.setTitle("Shops on Map");
mapInitialize();
// controller methods
$scope.menu = function(id) {
// alert('Menu for shop: ' + id);
console.log("menu " + id);
$location.path('/shop/' + id + '/menu');
}
}
// CONTROLLER MenuController
function MenuController($scope, $routeParams, $location, Shop, ShopMgr, Page, Cart) {
// $scope.shopId = $routeParams.id;
// $scope.shops = Shop.query();
$scope.cart = Cart;
// clear the cart if the shop has changed
var previousCartShop = Cart.getShop();
var shouldSetCartShop = true;
if (previousCartShop) {
if (previousCartShop._id != $routeParams.shopId) {
console.log("MenuController.init: Shop has changed. Clearing cart.");
Cart.empty();
} else {
console.log("MenuController.init: Resuming existing Cart for same shop.");
shouldSetCartShop = false;
}
}
$scope.shop = Shop.get({shopId: $routeParams.shopId}, function(shop) {
$scope.menuItems = shop.menuItems;
console.log("MenuController: call back for Shop.get: [" + shop._id + "] " + shop.name );
// $scope.mainImageUrl = phone.images[0];
// Set the shop for this Cart
if (shouldSetCartShop) {
console.log("Setting Cart shop:" + shop._id);
Cart.setShop(ShopMgr.getShopIdentity(shop))
}
Page.setTitle(shop.name);
});
// zero will not show up unless it is a string ['0','1','2','3','4','5'];
$scope.quantityOptions = [1,2,3,4,5];
// Controller Methods
$scope.choose = function(id) {
// alert('Menu for shop: ' + id);
console.log("menu item " + id);
// $location.path('/home');
}
$scope.count = function() {
return $scope.itemCount;
}
/*
$scope.total = function() {
var total = 0;
var itemCount = 0;
// return Math.floor(Math.random()*11);
// for (var category in $scope.menuItems) {
// for (var item in category.items) {
// for (var variation in item.variations) {
// total += variation.picked ? eval(variation.price) : 0;
// }
// }
// }
angular.forEach($scope.menuItems, function(category) {
angular.forEach(category.items, function(item) {
angular.forEach(item.variations, function(variation) {
if (variation.picked) {
total += eval(variation.price);
itemCount++;
}
// total += variation.picked ? eval(variation.price) : 0;
});
});
});
console.log("MenuController->total: " + itemCount + " item(s) = $" + total);
$scope.itemCount = itemCount;
return total;
}
*/
$scope.addItem = function(item, variation) {
// alert('Menu for shop: ' + id);
console.log("MenuController->addItem: " + variation.sku,
+ " " + item.name
+ " " + variation.description
+ " " + variation.code);
// $location.path('/shop/' + id + '/menu');
variation.item = item;
$scope.cart.add(variation);
}
$scope.removeVariation = function(variation) {
// alert('Menu for shop: ' + id);
console.log("MenuController->removeVariation: " + variation.sku);
$scope.cart.remove(variation);
$scope.unpick(variation);
}
$scope.unpick= function(variation) {
variation.picked = false;
}
$scope.itemCountStr = function() {
var s = "";
if ($scope.itemCount) {
s = $scope.itemCount + " item";
s += $scope.itemCount > 1 ? 's' :'';
}
return s;
}
}
// CONTROLLER CheckoutController
function CheckoutController($scope, $routeParams, $location, Customer, Shop, Page, Cart) {
Page.setTitle("Checkout");
$scope.cart = Cart;
$scope.method = Cart.getMethod();
// TODO Remember Last Delivery Address
// Delivery Address Choices
var addresses = Customer.getAddresses();
if (addresses && addresses.length) $scope.selectedAddress = addresses[0]; // first option
$scope.addresses = addresses;
// TODO Remember Last Payment Method
// Payment Options
var paymentMethods = Customer.getPaymentMethods();
if (paymentMethods && paymentMethods.length) $scope.selectedPaymentMethod = paymentMethods[0]; // first option
$scope.paymentMethods = paymentMethods;
$scope.submitOrder = function(item) {
console.log("CheckoutController:submit: ");
$location.path("/submit");
}
}
// CONTROLLER SubmitOrderController
function SubmitOrderController($scope, $routeParams, $location, $window, Shop, Page, Cart, CustomerOrder, Customer) {
Page.setTitle("Sending Order");
$scope.cart = Cart;
var cart = $scope.cart;
var cartItems = cart.items();
var shop = cart.getShop();
var method = Cart.getMethod();
// var deliveryAddress =
// TODO validate Cart
// check for items in cart (ie not empty)
// check that pre-confirm has happened
// TEMP - just check for a shop and non-empty cart for now
if (!shop || !cartItems.length) {
console.log("SubmitOrderController: Abandoned order submission because Cart shop or items are null" );
$location.path("/home");
return;
}
console.log("SubmitOrderController: Creating order for %s with %d items", shop._id, cartItems.length );
// build the Order
$scope.order = new CustomerOrder();
var order = $scope.order;
var user = Customer.getUser();
// order._id
// http://stackoverflow.com/questions/6312993/javascript-seconds-to-time-with-format-hhmmss
// multiply by 1000 because Date() requires miliseconds
var date = new Date();
var h = date.getHours();
var mm = date.getMinutes();
var ss = date.getSeconds();
var dd = date.getDate();
var mm = date.getMonth();
var yyyy = date.getFullYear();
var ap = "";
// This line gives you 12-hour (not 24) time
var h24 = h; // h24 is 24 hour time
if (h > 12) {
h = h - 12;
ap = 'p';
} else ap = 'a';
// These lines ensure you have two-digits
var hh = h;
if (hh < 10) {hh = "0"+hh;}
if (mm < 10) {mm = "0"+mm;}
if (ss < 10) {ss = "0"+ss;}
// This formats your string to HH:MM:SS
// var t = h+''+mm+''+ss;
// TODO order._id should be generated server-side
order._id = shop._id+'-'+yyyy+mm+dd+'-'+h24+mm+ss+'-'+user.last;
order.number = h+''+mm+'-'+ss;
order.time = hh+'.'+mm+ap;
order.date = date.toDateString();
// order.shop
order.shopId = shop._id;
order.shop = shop;
// order.customer
order.customerId = user._id;
order.customer = {
"_id" : user._id,
"name": user.name + " " + user.last,
"phone": user.mobile
};
order.method = Cart.getMethod();
order.deliverTo = {
"streetAddress" : "21 Hampden Lane",
"suburb":"Mosman"
};
order.items = [];
var variation;
for (variation in cartItems) {
var v = cartItems[variation];
var item = {};
item.name = v.item.name;
item.qty = v.qty;
item.variation = v.description;
item.category = "Pizza";
item.sku = v.sku;
order.items.push(item);
}
console.log("Submit Order : " + JSON.stringify(order) );
// TODO Persist the order with a CustomerOrderManager
// empty the cart just before sending the order
// TODO recover Cart if order fails
// - emptying the cart here will annoy the customer who will have to build the cart again
Cart.empty();
// send the order
CustomerOrder.save({customerId:user._id}, order, function (res) {
if (res.ok === 1) {
$location.path('/confirmed/' + order._id);
} else {
$window.alert("Error sending order");
$location.path("/home");
}
})
}
// CONTROLLER ConfirmedController
function ConfirmedController($scope, $routeParams, $location, Shop, Page, CustomerOrder, Customer) {
// TODO ConfirmedController : show order and orderID
Page.setTitle("Confirmed");
if (Customer.hasUser()) {
var user = Customer.getUser();
$scope.user = user;
$scope.order = CustomerOrder.get({customerId:user._id, orderId: $routeParams.orderId});
} else {
$location.path("/home");
}
}
/* OrdersController
"_id": "Local Demo02-39-06",
{
"customer": {
"_id": "1111111111",
"name": "Local Demo",
"phone": "1111111111"
},
"time": "02.39p",
"method": "delivery",
"deliverTo": {
"streetAddress": "21 Hampden Lane",
"suburb": "Mosman"
},
"items": [
{
"name": "Margherita",
"qty": 1,
"variation": "Family",
"category": "Pizza",
"sku": "1-F"
}
]
},
*/
// CONTROLLER OrdersController
function OrdersController($scope, $location, Page, CustomerOrder, Customer) {
Page.setTitle("Recent Orders");
if (Customer.hasUser()) {
var user = Customer.getUser();
$scope.user = user;
$scope.orders = CustomerOrder.query({customerId:user._id});
} else {
$location.path("/home");
}
}
// CONTROLLER ViewOrderController
function ViewOrderController($scope, $location, $routeParams, Page, CustomerOrder, Customer) {
Page.setTitle("Order Detail");
if (Customer.hasUser()) {
var user = Customer.getUser();
$scope.user = user;
$scope.order = CustomerOrder.get({customerId:user._id, orderId: $routeParams.orderId});
} else {
$location.path("/home");
}
}
// CONTROLLER AddressController
function AddressController($scope, $window, $location, $routeParams, $timeout, Page, Customer) {
Page.setTitle("Delivery Address");
if (Customer.hasUser()) {
var user = Customer.getUser();
$scope.user = user;
$scope.busy = false;
$scope.result = '';
if ($routeParams.addressId) {
$scope.address = Customer.getAddress($routeParams.addressId);
$scope.buttonLabel = "Update";
$scope.mode = "edit"
} else {
$scope.buttonLabel = "Add";
$scope.mode = "add"
}
} else {
$location.path("/home");
}
$scope.submit = function() {
var address = this.address;
console.log("AddressController:submit:");
// disable the form while we submit the update
$scope.busy = true;
var callback = function (result) {
if (result.ok === 1) {
$scope.result = 'success';
// $timeout(function(){$location.path("/account")}, 1000);
$timeout(function(){$window.history.back()}, 1000);
} else {
$window.alert("Error: Could not Update");
}
}
switch ($scope.mode) {
case "add" :
Customer.addAddress(address, callback);
break;
case "edit" :
Customer.updateAddress(address, callback);
}
}
}
// CONTROLLER PaymentMethodController
function PaymentMethodController($scope, $window, $location, $routeParams, $timeout, Page, Customer) {
Page.setTitle("Payment Method");
if (Customer.hasUser()) {
var user = Customer.getUser();
$scope.user = user;
$scope.busy = false;
$scope.result = '';
if ($routeParams.paymentMethodId) {
$scope.paymentMethod = Customer.getPaymentMethod($routeParams.paymentMethodId);
$scope.buttonLabel = "Update";
$scope.mode = "edit"
} else {
$scope.buttonLabel = "Add";
$scope.mode = "add"
}
} else {
$location.path("/home");
}
$scope.submit = function() {
var paymentMethod = this.paymentMethod;
console.log("PaymentMethodController:submit:");
// disable the form while we submit the update
$scope.busy = true;
var callback = function (result) {
if (result.ok === 1) {
$scope.result = 'success';
$timeout(function(){$window.history.back()}, 1000);
} else {
$window.alert("Error: Could not Update");
}
}
switch ($scope.mode) {
case "add" :
Customer.addPaymentMethod(paymentMethod, callback);
break;
case "edit" :
Customer.updatePaymentMethod(paymentMethod, callback);
}
}
}
// CONTROLLER DebugCommandController
function DebugCommandController($scope, $routeParams, $location, User, Customer) {
var action = $routeParams.action;
$scope.action = action;
switch (action) {
case "login" : // login as a set user
Customer.clearUser();
var user = {_id: '1111111111'};
console.log("DebugCommandController:Login: " + user._id);
User.get({_id: user._id}, function (result) {
if (result._id) {
Customer.setUser(result);
$location.path("/home");
} else {
$window.alert("Error: Could not Login");
}
})
break;
case "fake" : // Fake login as a set user
Customer.clearUser();
var user = {
"name": "Local",
"last": "Demo",
"mobile": "1111111111",
"email": "local@demo.com",
"pin": "1111",
"_id": "1111111111"
}
console.log("DebugCommandController:Fake: " + user._id);
Customer.setUser(user);
$location.path("/home");
break;
} // switch
}
// CONTROLLER DebugController
function DebugController($scope) {
}
</script>
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
// document.addEventListener("deviceready", onDeviceReady, false);
// document.addEventListener("DOMContentLoaded", hideHeader, false);
// Cordova is ready
function onDeviceReady() {
// var element = document.getElementById('deviceProperties');
navigator.notification.vibrate(200);
hideHeader();
}
function hideHeader() {
console.log("hideHeader()");
// var pageService = angular.module('app').service('Page');
// pageService.setHeaderVisible(false);
}
</script>
<script type="text/javascript" charset="utf-8">
// debug
var debug = {
hello : function() {
console.log('Debug: Hello !');
},
hideHeader : function () {
console.log('Debug: Hiding Header');
var e = document.getElementById('MainCtrl');
var scope = angular.element(e).scope();
// update the model with a wrap in $apply(fn) which will refresh the view for us
scope.$apply(function(){
scope.setHeaderVisibility(false);
});
}
}
debug.hello();
// TODO [END]
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment