diff --git a/.gitignore b/.gitignore index 972b6d2..c0f0a5d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ # Node modules node_modules -*.zip \ No newline at end of file +*.zip +npm-debug.log \ No newline at end of file diff --git a/SPA/ang.js b/SPA/ang.js new file mode 100644 index 0000000..0d19d2b --- /dev/null +++ b/SPA/ang.js @@ -0,0 +1,90 @@ +var booksApp = angular.module('ionicApp', ['ionic']) + +booksApp.config(function($stateProvider, $urlRouterProvider) { + + $stateProvider + .state('tabs', { + url: "/tab", + abstract: true, + templateUrl: "tabs.html" + }) + .state('tabs.home', { + url: "/home", + views: { + 'home-tab': { + templateUrl: "home.html", + controller: 'HomeTabCtrl' + } + } + }) + .state('tabs.facts', { + url: "/facts/:restId", + views: { + 'home-tab': { + templateUrl: "facts.html", + controller: 'AboutController' + } + } + }) + .state('tabs.facts2', { + url: "/facts2", + views: { + 'home-tab': { + templateUrl: "facts2.html" + } + } + }) + .state('tabs.about', { + url: "/about", + views: { + 'about-tab': { + templateUrl: "about.html", + } + } + }) + .state('tabs.navstack', { + url: "/navstack", + views: { + 'about-tab': { + templateUrl: "nav-stack.html" + } + } + }) + .state('tabs.contact', { + url: "/contact", + views: { + 'contact-tab': { + templateUrl: "contact.html" + } + } + }); + + + $urlRouterProvider.otherwise("/tab/home"); + +}) + +/*controller('HomeTabCtrl', function($scope) { + console.log('HomeTabCtrl'); +});*/ + + // create the controller and inject Angular's $scope +booksApp.controller('HomeTabCtrl', function($scope, $http) { + // create a message to display in our view + $http({method: 'GET', url: 'http://localhost:8003/rest'}). + success(function(data, status, headers, config) { + $scope.messages = data; + }). + error(function(data, status, headers, config) { + }); +}); + +booksApp.controller('AboutController', function($scope,$http,$stateParams) { + $http({method: 'GET', url: 'http://localhost:8003/rest/'+$stateParams.restId}). + success(function(data, status, headers, config) { + $scope.message = data; + console.log(data); + }). + error(function(data, status, headers, config) { + }); +}); \ No newline at end of file diff --git a/SPA/desktop.html b/SPA/desktop.html new file mode 100644 index 0000000..e1fdc04 --- /dev/null +++ b/SPA/desktop.html @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ + + + + \ No newline at end of file diff --git a/SPA/flat-ui.css b/SPA/flat-ui.css new file mode 100644 index 0000000..4b273fb --- /dev/null +++ b/SPA/flat-ui.css @@ -0,0 +1,86 @@ +.books { + list-style: none; + padding:0; +} + +.thumb { + float: left; + margin: -0.5em 1em 1.5em 0; +/* padding-bottom: 1em;*/ + width: 100px; +} + +.books li { + clear: both; + padding:10px; +} + +.breadcrumb { + margin-bottom:10px; +} + +input { + margin-top:15px; +} + +.books span { + color:red; +} + +h3 { + margin:0; +} + +a:hover { + text-decoration: none; +} + +.tooltip { + display: inline; + position: relative; +} + +.tooltip:hover { + color: #c00; + text-decoration: none; +} + +.tooltip:hover:after { + background: #111; + background: rgba(0,0,0,.8); + border-radius: .5em; + bottom: 1.35em; + color: #fff; + content: attr(title); + display: block; + left: 1em; + padding: .3em 1em; + position: absolute; + text-shadow: 0 1px 0 #000; + white-space: nowrap; + max-width:80%; + z-index: 98; +} + +.tooltip:hover:before { + border: solid; + border-color: #111 transparent; + border-color: rgba(0,0,0,.8) transparent; + border-width: .4em .4em 0 .4em; + bottom: 1em; + content: ""; + display: block; + left: 2em; + max-width:80%; + position: absolute; + z-index: 99; +} + +/* this part styles only a paragraph */ + +p { + color: #333; + font: normal .875em "Lucida Grande",Arial,sans-serif; + margin: 1em auto; + width: 75%; +} \ No newline at end of file diff --git a/SPA/index.html b/SPA/index.html index 97ca4cf..b937110 100644 --- a/SPA/index.html +++ b/SPA/index.html @@ -1,48 +1,103 @@ - - - - - - - - - - - - - - - - - - - - - -
- - - -
+ + + + -
- - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SPA/pages/about.html b/SPA/pages/about.html index a1fe271..5a8e901 100644 --- a/SPA/pages/about.html +++ b/SPA/pages/about.html @@ -1,30 +1,11 @@ +
- {{message.name}}
- Best Italian Sellers
-
-
-

{{value.name}}

-

Ingredients: {{value.ingredients}}
- Price: {{value.price}}

-
-
-
- Pizza
-
-
-

{{value.name}}

-

Ingredients: {{value.ingredients}}
- Price: {{value.price}}

-
-
-
- Pasta
-
-
-

{{value.name}}

-

Ingredients: {{value.ingredients}}
- Price: {{value.price}}

-
-
-
+

{{message.name}}

+ + {{message.auth_name}}
+

{{message.auth_description}}

+

{{message.book_description}}

\ No newline at end of file diff --git a/SPA/pages/home.html b/SPA/pages/home.html index 806ac3c..a88779f 100644 --- a/SPA/pages/home.html +++ b/SPA/pages/home.html @@ -1,4 +1,21 @@ -
- Home -
  • {{ message.name }}
    {{ message.author }},{{ message.city }}
    {{ message.phone }}
  • +
    + + + +
    > +
    + + +
      +
    • + +

      {{ message.name }}

      + By: {{ message.auth_name }} {{ message.books.length }} - {{ books }} +

      Description: {{ message.book_description }}

      + pellentesque +
    • +
    + +
    +
    \ No newline at end of file diff --git a/SPA/script.js b/SPA/script.js index 9a06ff1..c718a64 100644 --- a/SPA/script.js +++ b/SPA/script.js @@ -27,7 +27,7 @@ // create the controller and inject Angular's $scope booksApp.controller('mainController', function($scope, $http) { // create a message to display in our view - $http({method: 'GET', url: 'http://localhost:3412/rest'}). + $http({method: 'GET', url: 'http://localhost:8003/rest'}). success(function(data, status, headers, config) { $scope.messages = data; @@ -39,7 +39,7 @@ }); booksApp.controller('aboutController', function($scope,$http,$routeParams) { - $http({method: 'GET', url: 'http://localhost:3412/rest/'+$routeParams.restId}). + $http({method: 'GET', url: 'http://localhost:8003/rest/'+$routeParams.restId}). success(function(data, status, headers, config) { $scope.message = data; @@ -51,7 +51,7 @@ }); booksApp.controller('contactController', function($scope,$http) { - $http({method: 'GET', url: 'http://localhost:3412/rest/1'}). + $http({method: 'GET', url: 'http://localhost:8003/rest/1'}). success(function(data, status, headers, config) { $scope.messages = data; diff --git a/app.js b/app.js index fbc544c..48bf98d 100644 --- a/app.js +++ b/app.js @@ -3,10 +3,8 @@ var app = express(); // Declare variables var fs = require('fs'), - obj - -// Read the file and send to the callback -fs.readFile(__dirname + '/restaurant.json', handleFile) + obj, + auth // Write the callback function function handleFile(err, data) { @@ -14,15 +12,39 @@ function handleFile(err, data) { obj = JSON.parse(data) } +// Write the callback function +function authFile(err, data) { + if (err) throw err + auth = JSON.parse(data) +} + app.use("/SPA", express.static(__dirname + '/SPA')); app.use(express.bodyParser()); -app.get('/', function(req,res) { - res.sendfile('SPA/index.html'); + +app.get('/', checkForMobile, function(req,res) { + res.sendfile('SPA/desktop.html'); + console.log(':)'); + // Read the file and send to the callback + fs.readFile(__dirname + '/books.json', handleFile) + fs.readFile(__dirname + '/authors.json', authFile) }); app.get('/rest', function(req, res) { - res.json(obj); + var scope = []; + var books = []; +for(var i = 0; i < obj.length; i++) { + var initial = obj[i]; + var q = obj[i].author; + var z = auth[q].description; + var c = auth[q].author; + initial.auth_description = z; + initial.auth_name = c; + initial.books = getCount(q); +// json = JSON.stringify(initial); + scope.push(initial); + } + res.send(scope); }); app.get('/rest/random', function(req, res) { @@ -37,8 +59,53 @@ app.get('/rest/:id', function(req, res) { return res.send('Error 404: No book found'); } - var q = obj[req.params.id]; - res.json(q); + var initial = obj[req.params.id]; + var int = obj[req.params.id].author; + var descr = auth[int].description; + var name = auth[int].author; + var img = auth[int].image; + initial.auth_description = descr; + initial.auth_name = name; + initial.auth_image = img; + json = JSON.stringify(initial); + res.send(json); }); -app.listen(process.env.PORT || 3412); \ No newline at end of file +app.listen(process.env.PORT || 8003); + + +// returns true if the caller is a mobile phone (not tablet) +// compares the user agent of the caller against a regex +// This regex comes from http://detectmobilebrowsers.com/ +function isCallerMobile(req) { + var ua = req.headers['user-agent'].toLowerCase(), + isMobile = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(ua) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(ua.substr(0, 4)); + + return !!isMobile; +} + + +// note: the next method param is passed as well +function checkForMobile(req, res, next) { + // check to see if the caller is a mobile device + var isMobile = isCallerMobile(req); + + if (isMobile) { + console.log("Going mobile"); + res.sendfile('SPA/index.html'); +// res.redirect('/mobile'); + } else { + // if we didn't detect mobile, call the next method, which will eventually call the desktop route + return next(); + } +} + +function getCount(x) { + var count = []; + for (var i = 0; i < obj.length; i++) { + if (obj[i].author === x) { + count.push(obj[i].name); + } + } + return count; +} \ No newline at end of file diff --git a/authors.json b/authors.json index e69de29..3e711bc 100644 --- a/authors.json +++ b/authors.json @@ -0,0 +1,20 @@ +[ + { + "id": 0, + "description": "Edward Morgan Forster OM, CH (1 January 1879 – 7 June 1970) was an English novelist, short story writer, essayist and librettist. He is known best for his ironic and well-plotted novels examining class difference and hypocrisy in early 20th-century British society. Forster's humanistic impulse toward understanding and sympathy may be aptly summed up in the epigraph to his 1910 novel Howards End: \"Only connect ... \". His 1908 novel, A Room with a View, is his most optimistic work, while A Passage to India (1924) brought him his greatest success.", + "author": "E.M.Forster", + "image": "http://news.nationalgeographic.com/news/2007/04/images/070412-square-nebula.jpg" + }, + { + "id": 1, + "description": "Nicolas Bouvier (March 6, 1929, Lancy - February 17, 1998) was a 20th-century Swiss traveller, writer, icon painter and photographer.", + "author": "Nicolas Bouvier", + "image": "http://upload.wikimedia.org/wikipedia/commons/f/f7/Missing_square.gif" + }, + { + "id": 2, + "decription": "X Dorsay, despite the fact there are no translated books he is looking for translators", + "author": "X Dorsay", + "image": "http://mathworld.wolfram.com/images/eps-gif/MagicSquareDoublyEven_1000.gif" + } +] \ No newline at end of file diff --git a/books.json b/books.json new file mode 100644 index 0000000..0e78f02 --- /dev/null +++ b/books.json @@ -0,0 +1,23 @@ +[ + { + "id": 0, + "name": "A passage to India", + "author": 0, + "cover": "http://www.sonlight.com/images/products/530-49-l.jpg", + "book_description": "A Passage to India (1924) is a novel by English author E. M. Forster set against the backdrop of the British Raj and the Indian independence movement in the 1920s. It was selected as one of the 100 great works of English literature by the Modern Library and won the 1924 James Tait Black Memorial Prize for fiction. Time magazine included the novel in its \"100 Best English-language Novels from 1923 to 2005\".[1] The novel is based on Forster's experiences in India. E.M. Forster borrowed the book's title from Walt Whitman's poem of the same name in Leaves of Grass." + }, + { + "id": 1, + "name": "The Japanese Chronicles", + "author": 1, + "cover": "http://d.gr-assets.com/books/1387732740l/971901.jpg", + "book_description": "Based on three decades of travel throughout Japan, collects the author's recollections and views on life in the Land of the Rising Sun." + }, + { + "id": 2, + "name": "The Way of the World", + "author": 1, + "cover": "http://assets.nybooks.com/media/img/books/9781590173220_jpg_200x450_q85.jpg", + "book_description": "it’s about a journey in the 1950s from Belgrade to India. They try to go to India in a tiny battered Fiat and it takes them several years, these friends, and it probably describes the attraction of travel better than any book I’ve ever read." + } +] \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..9ea0242 --- /dev/null +++ b/readme.md @@ -0,0 +1,17 @@ +A small mobile detector book list with search + +Angular + NodeJS + Ionic using REST + +### Installation + +`git clone` the repo + +`cd` into the cloned repo and `npm install` + +`npm install nodemon -g` + +`nodemon app.js` + +now browse to [localhost:8003](http://localhost:8003 "localhost") and you should see the listing. + +In the `app.js` you will also find the mobile detector using HTTP header information, then routing to the specified file to ebgin with. \ No newline at end of file diff --git a/restaurant.json b/restaurant.json deleted file mode 100644 index cd2d652..0000000 --- a/restaurant.json +++ /dev/null @@ -1,73 +0,0 @@ -[ - { - "id": 0, - "name": "Book 1", - "author": "Stanislav Grof", - "city": "Port of spain", - "phone": "+40 743 105 932", - "best": [{ - "name":"pizza 1", - "ingredients":"one, two, three", - "price":"9.00 USD" - }, - { - "name":"pizza 2", - "ingredients":" xy x", - "price":"9" - }], - "pizza": [{ - "name":"Pizza Prosciuto", - "ingredients":"one one one", - "price":"10.00 USD" - }], - "pasta": [{ - "name": "Spaghetti All Arabiatello", - "ingredients": "pasta faina", - "price": "8.00 USD" - }] - }, - { - "id": 1, - "name": "Second Book", - "author": "Jean Clemente", - "city": "Port of spain", - "phone": "+40 743 105 932", - "best": [{ - "name":"pizza 1", - "ingredients":"one, two, three", - "price":"9.00 USD" - }], - "pizza": [{ - "name":"Pizza Prosciuto", - "ingredients":"one one one", - "price":"10.00 USD" - }], - "pasta": [{ - "name": "Spaghetti All Arabiatello", - "ingredients": "pasta faina", - "price": "8.00 USD" - }] - }, - { - "id": 2, - "name": "Third Book", - "author": "X Dorsay", - "city": "Port of spain", - "phone": "+40 743 105 932", - "best": [{ - "name":"pizza 1", - "ingredients":"one, two, three", - "price":"9.00 USD" - }], - "pizza": [{ - "name":"Pizza Prosciuto", - "ingredients":"one one one", - "price":"10.00 USD" - }], - "pasta": [{ - "name": "Spaghetti All Arabiatello", - "ingredients": "pasta faina", - "price": "8.00 USD" - }] - } -] \ No newline at end of file