Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lesson 27 #15

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
2 changes: 0 additions & 2 deletions README.md

This file was deleted.

13 changes: 13 additions & 0 deletions css/materialize.min.css

Large diffs are not rendered by default.

75 changes: 75 additions & 0 deletions css/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* colours */
:root{
--primary: #FFE9D2;
--secondary: #FFE1C4;
--title: #FF8816;
}

/* layout styles */
nav{
background: var(--primary);
border-bottom: 10px solid var(--secondary);
}
nav a{
text-transform: uppercase;
color: var(--title);
}
nav a span{
font-weight: bold;
}
nav .sidenav-trigger{
margin: 0;
}

/* recipe styles */
.recipes{
margin-top: 20px;
}
.card-panel.recipe{
border-radius: 8px;
padding: 10px;
box-shadow: 0px 1px 3px rgba(90,90,90,0.1);
display: grid;
grid-template-columns: 2fr 6fr 1fr;
grid-template-areas: "image details delete";
position: relative;
}
.recipe img{
grid-area: image;
max-width: 60px;
}
.recipe-details{
grid-area: details;
margin-top: 6px;
}
.recipe-delete{
grid-area: delete;
position: absolute;
bottom: 0px;
right: 0px;
}
.recipe-delete i{
font-size: 18px;
}
.recipe-title{
font-weight: bold;
}
.recipe-ingredients{
font-size: 0.8em;
}

/* form-styles */
.add-btn{
background: var(--title) !important;
}
input{
box-shadow: none !important;
-webkit-box-shadow: none !important;
}
.side-form button{
background: var(--title);
box-shadow: 1px 1px 3px rgba(90,90,90,0.2);
}
form .input-field{
margin-top: 30px;
}
Binary file added img/dish.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/icons/icon-128x128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/icons/icon-144x144.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/icons/icon-152x152.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/icons/icon-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/icons/icon-384x384.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/icons/icon-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/icons/icon-72x72.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/icons/icon-96x96.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
91 changes: 91 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Food Ninja</title>
<!-- materialize icons, css & js -->
<link type="text/css" href="/css/materialize.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link type="text/css" href="/css/styles.css" rel="stylesheet">
<script type="text/javascript" src="/js/materialize.min.js"></script>
<link rel="manifest" href="/manifest.json">
<!-- ios support -->
<link rel="apple-touch-icon" href="/img/icons/icon-96x96.png">
<meta name="apple-mobile-web-app-status-bar" content="#FFE1C4">
<meta name="theme-color" content="#FFE1C4">
</head>
<body class="grey lighten-4">

<!-- top nav -->
<nav class="z-depth-0">
<div class="nav-wrapper container">
<a href="/">Food<span>Ninja</span></a>
<span class="right grey-text text-darken-1">
<i class="material-icons sidenav-trigger" data-target="side-menu">menu</i>
</span>
</div>
</nav>

<!-- side nav -->
<ul id="side-menu" class="sidenav side-menu">
<li><a class="subheader">FOODNINJA</a></li>
<li><a href="/" class="waves-effect">Home</a></li>
<li><a href="/pages/about.html" class="waves-effect">About</a></li>
<li><div class="divider"></div></li>
<li><a href="/pages/contact.html" class="waves-effect">
<i class="material-icons">mail_outline</i>Contact</a>
</li>
</ul>

<!-- recipes -->
<div class="recipes container grey-text text-darken-1">

</div>

<div class="center">
<a class="btn-floating btn-small btn-large add-btn sidenav-trigger" data-target="side-form">
<i class="material-icons">add</i>
</a>
</div>

<!-- add recipe side nav -->
<div id="side-form" class="sidenav side-form">
<form class="add-recipe container section">
<h6 >New Recipe</h6>
<div class="divider"></div>
<div class="input-field">
<input placeholder="e.g. Ninja soup" id="title" type="text" class="validate">
<label for="title">Recipe Title</label>
</div>
<div class="input-field">
<input placeholder="e.g. Tofu, mushroom, garlic" id="ingredients" type="text" class="validate">
<label for="ingredients">Ingredients</label>
</div>
<div class="input-field center">
<button class="btn-small">Add</button>
</div>
</form>
</div>


<script src="https://www.gstatic.com/firebasejs/5.11.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.11.0/firebase-firestore.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "AIzaSyDuDGcpHGU-Sx1Hla3wYwZvXbjeKpHqPjA",
authDomain: "net-ninja-pwa.firebaseapp.com",
databaseURL: "https://net-ninja-pwa.firebaseio.com",
projectId: "net-ninja-pwa",
storageBucket: "net-ninja-pwa.appspot.com",
messagingSenderId: "1008745109838"
};
firebase.initializeApp(config);
const db = firebase.firestore();
</script>
<script src="/js/app.js"></script>
<script src="/js/db.js"></script>
<script src="/js/ui.js"></script>
</body>
</html>
5 changes: 5 additions & 0 deletions js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
if('serviceWorker' in navigator){
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log('service worker registered'))
.catch(err => console.log('service worker not registered', err));
}
40 changes: 40 additions & 0 deletions js/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// enable offline data
db.enablePersistence()
.catch(function(err) {
if (err.code == 'failed-precondition') {
// probably multible tabs open at once
console.log('persistance failed');
} else if (err.code == 'unimplemented') {
// lack of browser support for the feature
console.log('persistance not available');
}
});

// real-time listener
db.collection('recipes').onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
if(change.type === 'added'){
renderRecipe(change.doc.data(), change.doc.id);
}
if(change.type === 'removed'){
// remove the document data from the web page
}
});
});

// add new recipe
const form = document.querySelector('form');
form.addEventListener('submit', evt => {
evt.preventDefault();

const recipe = {
name: form.title.value,
ingredients: form.ingredients.value
};

db.collection('recipes').add(recipe)
.catch(err => console.log(err));

form.title.value = '';
form.ingredients.value = '';
});
6 changes: 6 additions & 0 deletions js/materialize.min.js

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions js/ui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const recipes = document.querySelector('.recipes');

document.addEventListener('DOMContentLoaded', function() {
// nav menu
const menus = document.querySelectorAll('.side-menu');
M.Sidenav.init(menus, {edge: 'right'});
// add recipe form
const forms = document.querySelectorAll('.side-form');
M.Sidenav.init(forms, {edge: 'left'});
});

// render recipe data
const renderRecipe = (data, id) => {

const html = `
<div class="card-panel recipe white row" data-id="${id}">
<img src="/img/dish.png" alt="recipe thumb">
<div class="recipe-details">
<div class="recipe-title">${data.name}</div>
<div class="recipe-ingredients">${data.ingredients}</div>
</div>
<div class="recipe-delete">
<i class="material-icons" data-id="${id}">delete_outline</i>
</div>
</div>
`;
recipes.innerHTML += html;

};
51 changes: 51 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "Food Ninja",
"short_name": "FoodNinja",
"start_url": "/index.html",
"display": "standalone",
"background_color": "#FFE9D2",
"theme_color": "#FFE1C4",
"orientation": "portrait-primary",
"icons": [
{
"src": "/img/icons/icon-72x72.png",
"type": "image/png",
"sizes": "72x72"
},
{
"src": "/img/icons/icon-96x96.png",
"type": "image/png",
"sizes": "96x96"
},
{
"src": "/img/icons/icon-128x128.png",
"type": "image/png",
"sizes": "128x128"
},
{
"src": "/img/icons/icon-144x144.png",
"type": "image/png",
"sizes": "144x144"
},
{
"src": "/img/icons/icon-152x152.png",
"type": "image/png",
"sizes": "152x152"
},
{
"src": "/img/icons/icon-192x192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "/img/icons/icon-384x384.png",
"type": "image/png",
"sizes": "384x384"
},
{
"src": "/img/icons/icon-512x512.png",
"type": "image/png",
"sizes": "512x512"
}
]
}
50 changes: 50 additions & 0 deletions pages/about.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Food Ninja</title>
<!-- materialize icons, css & js -->
<link type="text/css" href="/css/materialize.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link type="text/css" href="/css/styles.css" rel="stylesheet">
<script type="text/javascript" src="/js/materialize.min.js"></script>
<link rel="manifest" href="/manifest.json">
<link rel="apple-touch-icon" href="/img/icons/icon-96x96.png">
<meta name="apple-mobile-web-app-status-bar" content="#FFE1C4">
<meta name="theme-color" content="#FFE1C4">
</head>
<body class="grey lighten-4">

<!-- top nav -->
<nav class="z-depth-0">
<div class="nav-wrapper container">
<a href="/">Food<span>Ninja</span></a>
<span class="right grey-text text-darken-1">
<i class="material-icons sidenav-trigger" data-target="side-menu">menu</i>
</span>
</div>
</nav>

<!-- side nav -->
<ul id="side-menu" class="sidenav side-menu">
<li><a class="subheader">FOODNINJA</a></li>
<li><a href="/" class="waves-effect">Home</a></li>
<li><a href="/pages/about.html" class="waves-effect">About</a></li>
<li><div class="divider"></div></li>
<li><a href="/pages/contact.html" class="waves-effect">
<i class="material-icons">mail_outline</i>Contact</a>
</li>
</ul>

<!-- content -->
<div class="container grey-text">
<h5 class="center">About Food Ninja</h5>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Ducimus, porro voluptatum illum veniam eaque sunt sit labore provident eligendi! Voluptate amet suscipit inventore unde maxime atque impedit officia nobis laboriosam!</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam voluptatibus omnis, ea doloremque exercitationem id necessitatibus. Voluptatem officiis cupiditate commodi totam, hic laborum est ducimus amet iure, non dignissimos illo.</p>
</div>

<script src="/js/app.js"></script>
<script src="/js/ui.js"></script>
</body>
</html>
Loading