diff --git a/app/apple-touch-icon.png b/app/apple-touch-icon.png new file mode 100644 index 0000000..7f47529 Binary files /dev/null and b/app/apple-touch-icon.png differ diff --git a/app/favicon.ico b/app/favicon.ico new file mode 100644 index 0000000..2b32e0e Binary files /dev/null and b/app/favicon.ico differ diff --git a/app/img/icons/rr-icon-192.png b/app/img/icons/rr-icon-192.png new file mode 100644 index 0000000..9cb9d0c Binary files /dev/null and b/app/img/icons/rr-icon-192.png differ diff --git a/app/img/icons/rr-icon-512.png b/app/img/icons/rr-icon-512.png new file mode 100644 index 0000000..4331e23 Binary files /dev/null and b/app/img/icons/rr-icon-512.png differ diff --git a/app/index.html b/app/index.html index 2b356f3..32bfff0 100644 --- a/app/index.html +++ b/app/index.html @@ -3,6 +3,8 @@ + + diff --git a/app/manifest.json b/app/manifest.json new file mode 100644 index 0000000..2e041c1 --- /dev/null +++ b/app/manifest.json @@ -0,0 +1,14 @@ +{ + "short_name": "FoodReviews", + "name": "Restaurant Reviews", + "description": "Restaurant Reviews App - Part of the Udacity Mobile Web Soecialist Nano-Degree", + "start_url": "index.html", + "theme_color": "orange", + "background_color": "#252831", + "display": "fullscreen", + "icons": [ + { "src": "img/icons/rr-icon-192.png", "type": "image/png", "sizes": "192x192" }, + { "src": "img/icons/rr-icon-512.png", "type": "image/png", "sizes": "512x512" } + ] + } + \ No newline at end of file diff --git a/app/restaurant.html b/app/restaurant.html index e49e3b4..5ba41ac 100644 --- a/app/restaurant.html +++ b/app/restaurant.html @@ -4,6 +4,8 @@ + + diff --git a/dist/apple-touch-icon.png b/dist/apple-touch-icon.png new file mode 100644 index 0000000..7f47529 Binary files /dev/null and b/dist/apple-touch-icon.png differ diff --git a/dist/favicon.ico b/dist/favicon.ico new file mode 100644 index 0000000..2b32e0e Binary files /dev/null and b/dist/favicon.ico differ diff --git a/dist/img/icons/rr-icon-192.png b/dist/img/icons/rr-icon-192.png new file mode 100644 index 0000000..9cb9d0c Binary files /dev/null and b/dist/img/icons/rr-icon-192.png differ diff --git a/dist/img/icons/rr-icon-512.png b/dist/img/icons/rr-icon-512.png new file mode 100644 index 0000000..4331e23 Binary files /dev/null and b/dist/img/icons/rr-icon-512.png differ diff --git a/dist/index.html b/dist/index.html index 28d9adb..bc6657f 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1 +1 @@ -Restaurant Reviews

Filter Results

\ No newline at end of file +Restaurant Reviews

Filter Results

\ No newline at end of file diff --git a/dist/js/main.js b/dist/js/main.js index f254a84..38843e4 100644 --- a/dist/js/main.js +++ b/dist/js/main.js @@ -1 +1 @@ -let restaurants,neighborhoods,cuisines;var map,markers=[];document.addEventListener("DOMContentLoaded",e=>{fetchNeighborhoods(),fetchCuisines()}),fetchNeighborhoods=(()=>{DBHelper.fetchNeighborhoods((e,t)=>{e?console.error(e):(self.neighborhoods=t,fillNeighborhoodsHTML())})}),fillNeighborhoodsHTML=((e=self.neighborhoods)=>{const t=document.getElementById("neighborhoods-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),fetchCuisines=(()=>{DBHelper.fetchCuisines((e,t)=>{e?console.error(e):(self.cuisines=t,fillCuisinesHTML())})}),fillCuisinesHTML=((e=self.cuisines)=>{const t=document.getElementById("cuisines-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),window.initMap=(()=>{self.map=new google.maps.Map(document.getElementById("map"),{zoom:12,center:{lat:40.722216,lng:-73.987501},scrollwheel:!1}),updateRestaurants()}),updateRestaurants=(()=>{const e=document.getElementById("cuisines-select"),t=document.getElementById("neighborhoods-select"),n=e.selectedIndex,s=t.selectedIndex,r=e[n].value,a=t[s].value;DBHelper.fetchRestaurantByCuisineAndNeighborhood(r,a,(e,t)=>{e?console.error(e):(resetRestaurants(t),fillRestaurantsHTML())})}),resetRestaurants=(e=>{self.restaurants=[],document.getElementById("restaurants-list").innerHTML="",self.markers.forEach(e=>e.setMap(null)),self.markers=[],self.restaurants=e}),fillRestaurantsHTML=((e=self.restaurants)=>{const t=document.getElementById("restaurants-list");e.forEach(e=>{t.append(createRestaurantHTML(e))}),addMarkersToMap()}),createRestaurantHTML=(e=>{const t=document.createElement("li"),n=document.createElement("img");n.className="restaurant-img",n.src=`/img/${e.id}@1x.jpg`,n.srcset=`/img/${e.id}@1x.jpg 300w,\n /img/${e.id}@2x.jpg 600w,\n /img/${e.id}@3x.jpg 900w`,n.alt=`Image of ${e.name} restaurant`,t.append(n);const s=document.createElement("h3");s.innerHTML=e.name,t.append(s);const r=document.createElement("p");r.innerHTML=e.neighborhood,t.append(r);const a=document.createElement("p");a.innerHTML=e.address,t.append(a);const o=document.createElement("a");return o.innerHTML="View Details",o.href=DBHelper.urlForRestaurant(e),t.append(o),t}),addMarkersToMap=((e=self.restaurants)=>{e.forEach(e=>{const t=DBHelper.mapMarkerForRestaurant(e,self.map);google.maps.event.addListener(t,"click",()=>{window.location.href=t.url}),self.markers.push(t)})}); \ No newline at end of file +let restaurants,neighborhoods,cuisines;var map,markers=[];document.addEventListener("DOMContentLoaded",e=>{fetchNeighborhoods(),fetchCuisines()}),fetchNeighborhoods=(()=>{DBHelper.fetchNeighborhoods((e,t)=>{e?console.error(e):(self.neighborhoods=t,fillNeighborhoodsHTML())})}),fillNeighborhoodsHTML=((e=self.neighborhoods)=>{const t=document.getElementById("neighborhoods-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),fetchCuisines=(()=>{DBHelper.fetchCuisines((e,t)=>{e?console.error(e):(self.cuisines=t,fillCuisinesHTML())})}),fillCuisinesHTML=((e=self.cuisines)=>{const t=document.getElementById("cuisines-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),window.initMap=(()=>{self.map=new google.maps.Map(document.getElementById("map"),{zoom:12,center:{lat:40.722216,lng:-73.987501},scrollwheel:!1}),updateRestaurants()}),updateRestaurants=(()=>{const e=document.getElementById("cuisines-select"),t=document.getElementById("neighborhoods-select"),n=e.selectedIndex,s=t.selectedIndex,r=e[n].value,a=t[s].value;DBHelper.fetchRestaurantByCuisineAndNeighborhood(r,a,(e,t)=>{e?console.error(e):(resetRestaurants(t),fillRestaurantsHTML())})}),resetRestaurants=(e=>{self.restaurants=[],document.getElementById("restaurants-list").innerHTML="",self.markers.forEach(e=>e.setMap(null)),self.markers=[],self.restaurants=e}),fillRestaurantsHTML=((e=self.restaurants)=>{const t=document.getElementById("restaurants-list");e.forEach(e=>{t.append(createRestaurantHTML(e))}),addMarkersToMap()}),createRestaurantHTML=(e=>{const t=document.createElement("li"),n=document.createElement("img");n.className="restaurant-img",n.src=`/img/${e.id}@1x.webp`,n.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,n.alt=`Image of ${e.name} restaurant`,t.append(n);const s=document.createElement("h3");s.innerHTML=e.name,t.append(s);const r=document.createElement("p");r.innerHTML=e.neighborhood,t.append(r);const a=document.createElement("p");a.innerHTML=e.address,t.append(a);const o=document.createElement("a");return o.innerHTML="View Details",o.href=DBHelper.urlForRestaurant(e),t.append(o),t}),addMarkersToMap=((e=self.restaurants)=>{e.forEach(e=>{const t=DBHelper.mapMarkerForRestaurant(e,self.map);google.maps.event.addListener(t,"click",()=>{window.location.href=t.url}),self.markers.push(t)})}); \ No newline at end of file diff --git a/dist/js/restaurant_info.js b/dist/js/restaurant_info.js index 4391100..e60d699 100644 --- a/dist/js/restaurant_info.js +++ b/dist/js/restaurant_info.js @@ -1 +1 @@ -let restaurant;var map;window.initMap=(()=>{fetchRestaurantFromURL((e,t)=>{e?console.error(e):(self.map=new google.maps.Map(document.getElementById("map"),{zoom:16,center:t.latlng,scrollwheel:!1}),fillBreadcrumb(),DBHelper.mapMarkerForRestaurant(self.restaurant,self.map))})}),fetchRestaurantFromURL=(e=>{if(self.restaurant)return void e(null,self.restaurant);const t=getParameterByName("id");t?DBHelper.fetchRestaurantById(t,(t,n)=>{self.restaurant=n,n?(fillRestaurantHTML(),e(null,n)):console.error(t)}):(error="No restaurant id in URL",e(error,null))}),fillRestaurantHTML=((e=self.restaurant)=>{document.getElementById("restaurant-name").innerHTML=e.name,document.getElementById("restaurant-address").innerHTML=e.address;const t=document.getElementById("restaurant-img");t.className="restaurant-img",t.src=`/img/${e.id}@1x.jpg`,t.srcset=`/img/${e.id}@1x.jpg 300w,\n /img/${e.id}@2x.jpg 600w,\n /img/${e.id}@3x.jpg 900w`,t.alt=e.alt_text,document.getElementById("restaurant-cuisine").innerHTML=e.cuisine_type,e.operating_hours&&fillRestaurantHoursHTML(),fillReviewsHTML()}),fillRestaurantHoursHTML=((e=self.restaurant.operating_hours)=>{const t=document.getElementById("restaurant-hours");for(let n in e){const r=document.createElement("tr"),a=document.createElement("th");a.innerHTML=n,r.appendChild(a);const l=document.createElement("td");l.innerHTML=e[n],r.appendChild(l),t.appendChild(r)}}),fillReviewsHTML=((e=self.restaurant.reviews)=>{const t=document.getElementById("reviews-container"),n=document.createElement("h3");if(n.innerHTML="Reviews",t.appendChild(n),!e){const e=document.createElement("p");return e.innerHTML="No reviews yet!",void t.appendChild(e)}const r=document.getElementById("reviews-list");e.forEach(e=>{r.appendChild(createReviewHTML(e))}),t.appendChild(r)}),createReviewHTML=(e=>{const t=document.createElement("li"),n=document.createElement("p");n.id="reviewer-name",n.innerHTML=e.name,t.appendChild(n);const r=document.createElement("p");r.innerHTML=e.date,t.appendChild(r);const a=document.createElement("p");a.innerHTML=`Rating: ${e.rating}`,t.appendChild(a);const l=document.createElement("p");var d="";for(i=0;i{const t=document.getElementById("breadcrumb"),n=document.createElement("li");n.setAttribute("aria-current","page"),n.innerHTML=e.name,t.appendChild(n)}),getParameterByName=((e,t)=>{t||(t=window.location.href),e=e.replace(/[\[\]]/g,"\\$&");const n=new RegExp(`[?&]${e}(=([^&#]*)|&|#|$)`).exec(t);return n?n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):"":null}); \ No newline at end of file +let restaurant;var map;window.initMap=(()=>{fetchRestaurantFromURL((e,t)=>{e?console.error(e):(self.map=new google.maps.Map(document.getElementById("map"),{zoom:16,center:t.latlng,scrollwheel:!1}),fillBreadcrumb(),DBHelper.mapMarkerForRestaurant(self.restaurant,self.map))})}),fetchRestaurantFromURL=(e=>{if(self.restaurant)return void e(null,self.restaurant);const t=getParameterByName("id");t?DBHelper.fetchRestaurantById(t,(t,n)=>{self.restaurant=n,n?(fillRestaurantHTML(),e(null,n)):console.error(t)}):(error="No restaurant id in URL",e(error,null))}),fillRestaurantHTML=((e=self.restaurant)=>{document.getElementById("restaurant-name").innerHTML=e.name,document.getElementById("restaurant-address").innerHTML=e.address;const t=document.getElementById("restaurant-img");t.className="restaurant-img",t.src=`/img/${e.id}@1x.webp`,t.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,t.alt=e.alt_text,document.getElementById("restaurant-cuisine").innerHTML=e.cuisine_type,e.operating_hours&&fillRestaurantHoursHTML(),fillReviewsHTML()}),fillRestaurantHoursHTML=((e=self.restaurant.operating_hours)=>{const t=document.getElementById("restaurant-hours");for(let n in e){const r=document.createElement("tr"),a=document.createElement("th");a.innerHTML=n,r.appendChild(a);const l=document.createElement("td");l.innerHTML=e[n],r.appendChild(l),t.appendChild(r)}}),fillReviewsHTML=((e=self.restaurant.reviews)=>{const t=document.getElementById("reviews-container"),n=document.createElement("h3");if(n.innerHTML="Reviews",t.appendChild(n),!e){const e=document.createElement("p");return e.innerHTML="No reviews yet!",void t.appendChild(e)}const r=document.getElementById("reviews-list");e.forEach(e=>{r.appendChild(createReviewHTML(e))}),t.appendChild(r)}),createReviewHTML=(e=>{const t=document.createElement("li"),n=document.createElement("p");n.id="reviewer-name",n.innerHTML=e.name,t.appendChild(n);const r=document.createElement("p");r.innerHTML=e.date,t.appendChild(r);const a=document.createElement("p");a.innerHTML=`Rating: ${e.rating}`,t.appendChild(a);const l=document.createElement("p");var d="";for(i=0;i{const t=document.getElementById("breadcrumb"),n=document.createElement("li");n.setAttribute("aria-current","page"),n.innerHTML=e.name,t.appendChild(n)}),getParameterByName=((e,t)=>{t||(t=window.location.href),e=e.replace(/[\[\]]/g,"\\$&");const n=new RegExp(`[?&]${e}(=([^&#]*)|&|#|$)`).exec(t);return n?n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):"":null}); \ No newline at end of file diff --git a/dist/manifest.json b/dist/manifest.json new file mode 100644 index 0000000..2e041c1 --- /dev/null +++ b/dist/manifest.json @@ -0,0 +1,14 @@ +{ + "short_name": "FoodReviews", + "name": "Restaurant Reviews", + "description": "Restaurant Reviews App - Part of the Udacity Mobile Web Soecialist Nano-Degree", + "start_url": "index.html", + "theme_color": "orange", + "background_color": "#252831", + "display": "fullscreen", + "icons": [ + { "src": "img/icons/rr-icon-192.png", "type": "image/png", "sizes": "192x192" }, + { "src": "img/icons/rr-icon-512.png", "type": "image/png", "sizes": "512x512" } + ] + } + \ No newline at end of file diff --git a/dist/restaurant.html b/dist/restaurant.html index 8ecc665..7e19a1b 100644 --- a/dist/restaurant.html +++ b/dist/restaurant.html @@ -1 +1 @@ -Restaurant Info

    \ No newline at end of file +Restaurant Info

      \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 08e5ca7..86ed64e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -10,24 +10,29 @@ var webp = require('gulp-webp'); var htmlmin = require('gulp-htmlmin'); var cleancss = require('gulp-clean-css'); var browserSync = require('browser-sync').create(); +var del = require('del'); // Watch -gulp.task('watch', function() { +gulp.task('watch', () => { var reload = browserSync.reload // JS - gulp.watch('app/sw.js', ['sw', reload]); - gulp.watch('app/js/*.js', ['scripts', reload]); + gulp.watch('app/sw.js', ['sw', reload]); + gulp.watch('app/js/*.js', ['scripts', reload]); // Images gulp.watch('app/img/*.jpg', ['images', reload]); // HTML - gulp.watch('app/*.html', ['html', reload]); + gulp.watch('app/*.html', ['html', reload]); // CSS gulp.watch('app/css/styles.css', ['css', reload]); - -}) + // Manifest + gulp.watch('app/manifest.json', ['manifest', reload]); + // Icons + gulp.watch(['app/favicon.ico','app/apple-touch-icon.png'], ['icons-main', reload]); + gulp.watch('app/img/icons/*', ['icons-folder', reload]); +}); // Serve -gulp.task('serve', ['build'], function() { +gulp.task('serve', ['build'], () => { browserSync.init({ notify: false, port: 8080, @@ -35,17 +40,16 @@ gulp.task('serve', ['build'], function() { baseDir: ["dist"] } }) -}) - +}); // Minify JS -gulp.task('sw', function() { +gulp.task('sw', () => { return gulp.src('app/sw.js') .pipe(uglify()) .pipe(gulp.dest('dist')); }); -gulp.task('scripts', function() { +gulp.task('scripts', () => { return gulp.src('app/js/*.js') // .pipe(babel()) .pipe(uglify()) @@ -56,7 +60,7 @@ gulp.task('scripts', function() { }); // Optimize images -gulp.task('images', function() { +gulp.task('images', () => { return gulp.src('app/img/*.jpg') .pipe(cache(imagemin( { optimizationLevel: 5, progressive: true, interlaced: true @@ -66,25 +70,60 @@ gulp.task('images', function() { }); // Minify HTML -gulp.task('html', function() { +gulp.task('html', () => { return gulp.src('app/*.html') .pipe(htmlmin( { removeComments: true, collapseWhitespace: true })) .pipe(gulp.dest('dist')); -}) +}); // Clean CSS -gulp.task('css', function() { +gulp.task('css', () => { return gulp.src('app/css/styles.css') .pipe(cleancss()) .pipe(gulp.dest('dist/css')); -}) +}); + +// Move over remaining files to dist +gulp.task('manifest', () => { + return gulp.src('app/manifest.json') + .pipe(gulp.dest('dist')); +}); + +gulp.task('icons-main', () => { + return gulp.src(['app/favicon.ico','app/apple-touch-icon.png']) + .pipe(gulp.dest('dist')); +}); + +gulp.task('icons-folder', () => { + return gulp.src('app/img/icons/*') + .pipe(gulp.dest('dist/img/icons')); +}); // Build - just for building app for dist // *** NEEDS Manifest and icon tasks -gulp.task('build', ['sw', 'scripts', 'images', 'html', 'css']) +gulp.task('build', [ + 'sw', + 'scripts', + 'images', + 'html', + 'css', + 'manifest', + 'icons-main', + 'icons-folder' +]); // Dev task - Builds for dist, spinns up server and actvates watch // for continuous update during dev. -gulp.task('dev', ['serve', 'watch']); \ No newline at end of file +gulp.task('dev', ['serve', 'watch']); + +// Clean out dist folder +gulp.task('clean-dist', () => { + return del.sync('dist'); +}); + +// Clean out image cahce +gulp.task('cache-clear', (callback) => { + return cache.clearAll(callback); +}); \ No newline at end of file diff --git a/lighthouseScore.png b/lighthouseScore.png new file mode 100644 index 0000000..29381e8 Binary files /dev/null and b/lighthouseScore.png differ diff --git a/package-lock.json b/package-lock.json index e6a4d95..86e2dea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2262,6 +2262,28 @@ } } }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -5520,6 +5542,30 @@ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -6725,6 +6771,12 @@ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, "p-pipe": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-1.2.0.tgz", @@ -6846,6 +6898,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", diff --git a/package.json b/package.json index 612f7e4..ccf226c 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "devDependencies": { "babel-core": "^6.26.3", "browser-sync": "^2.24.6", + "del": "^3.0.0", "gulp": "^3.9.1", "gulp-babel": "^7.0.1", "gulp-cache": "^1.0.2",