├── .vscode
└── settings.json
├── googleIcon.png
├── images
└── logo.png
├── forgate.css
├── js
├── dashboard.js
├── logout.js
├── firebase.js
├── forgate.js
├── restaurant.js
├── registration.js
├── add-dishes.js
├── order.js
└── dishes.js
├── registration.css
├── index.html
├── app.js
├── style.css
├── register.html
├── forgate.html
├── login.html
├── dashboard.html
├── orders.html
├── restaurants.html
├── add-dishes.html
└── dishes.html
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "liveServer.settings.port": 5501
3 | }
--------------------------------------------------------------------------------
/googleIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Alirazaramejo/smit-batch-10-food-delivery-app/HEAD/googleIcon.png
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Alirazaramejo/smit-batch-10-food-delivery-app/HEAD/images/logo.png
--------------------------------------------------------------------------------
/forgate.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | main {
7 | display: flex;
8 | align-items: center;
9 | padding-top: 40px;
10 | padding-bottom: 40px;
11 | background-color: #f5f5f5;
12 | height: 100%;
13 | }
14 |
15 | .form-signin {
16 | max-width: 410px;
17 | padding: 15px;
18 | }
19 |
--------------------------------------------------------------------------------
/js/dashboard.js:
--------------------------------------------------------------------------------
1 | import { auth, onAuthStateChanged } from "./firebase.js"
2 |
3 | onAuthStateChanged(auth, (user) => {
4 | if (user) {
5 | console.log(user.email)
6 | if (user.email !== "admin@gmail.com") {
7 | location.href = "login.html"
8 | }
9 |
10 | } else {
11 | location.href = "login.html"
12 | }
13 | });
--------------------------------------------------------------------------------
/js/logout.js:
--------------------------------------------------------------------------------
1 |
2 | import {signOut,auth} from "./firebase.js"
3 | export async function logOut() {
4 | await signOut(auth).then(() => {
5 | Swal.fire({
6 | icon: 'success',
7 | title: 'Logout Successfully'
8 | })
9 | location.href = "../login.html"
10 | }).catch((error) => {
11 | Swal.fire({
12 | icon: 'error',
13 | title: 'Oops...',
14 | text: error
15 | })
16 | });
17 | }
18 | document.getElementById('logoutbtn').addEventListener("click", logOut);
--------------------------------------------------------------------------------
/js/firebase.js:
--------------------------------------------------------------------------------
1 | import { initializeApp } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-app.js";
2 | import {
3 | getAuth,
4 | signInWithEmailAndPassword,
5 | onAuthStateChanged,
6 | createUserWithEmailAndPassword,
7 | sendPasswordResetEmail,
8 | GoogleAuthProvider,
9 | signInWithPopup,
10 | signOut
11 | } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-auth.js";
12 | import {
13 | getStorage,
14 | ref,
15 | uploadBytesResumable,
16 | getDownloadURL,
17 | } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-storage.js";
18 | import {
19 | getFirestore,
20 | collection,
21 | addDoc,
22 | query,
23 | where,
24 | getDocs,
25 | getDoc,
26 | doc,
27 | setDoc,
28 | serverTimestamp,
29 | updateDoc,
30 | } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-firestore.js";
31 |
32 | const firebaseConfig = {
33 | apiKey: "AIzaSyDG6-ZhFAuf2xkIVjieFKPzYXylqsASeXU",
34 | authDomain: "smit-batch-10.firebaseapp.com",
35 | projectId: "smit-batch-10",
36 | storageBucket: "smit-batch-10.appspot.com",
37 | messagingSenderId: "333213670128",
38 | appId: "1:333213670128:web:b7d83af5afed979bafc035",
39 | };
40 |
41 | const app = initializeApp(firebaseConfig);
42 | const auth = getAuth(app);
43 | const storage = getStorage(app);
44 | const db = getFirestore(app);
45 | const provider = new GoogleAuthProvider();
46 | export {
47 | provider,
48 | auth,
49 | signInWithEmailAndPassword,
50 | onAuthStateChanged,
51 | storage,
52 | ref,
53 | uploadBytesResumable,
54 | getDownloadURL,
55 | db,
56 | collection,
57 | addDoc,
58 | query,
59 | where,
60 | getDocs,
61 | doc,
62 | getDoc,
63 | serverTimestamp,
64 | updateDoc,
65 | setDoc,
66 | createUserWithEmailAndPassword,
67 | GoogleAuthProvider,
68 | signInWithPopup,
69 | sendPasswordResetEmail,
70 | signOut
71 | };
72 |
--------------------------------------------------------------------------------
/js/forgate.js:
--------------------------------------------------------------------------------
1 | import {auth,onAuthStateChanged,sendPasswordResetEmail} from "./firebase.js"
2 |
3 | const usr_email = document.getElementById('user_email');
4 | const usr_passwd = document.getElementById('user_passwd');
5 |
6 | export function validEmail() {
7 | var uemail = document.getElementById('user_email');
8 | var emailerr = document.getElementById('email_err');
9 | if (uemail.value == "" || uemail.value == null) {
10 | uemail.classList.remove("is-valid");
11 | uemail.classList.add("is-invalid");
12 | emailerr.innerHTML = "E-mail Address is required";
13 | return false;
14 | } else {
15 | uemail.classList.remove("is-invalid");
16 | uemail.classList.add("is-valid");
17 | emailerr.innerHTML = "";
18 | return true;
19 | }
20 | }
21 |
22 | export async function checkBeforeAuth() {
23 | await onAuthStateChanged(auth, (user) => {
24 | if (user) {
25 | location.href = "dashboard.html";
26 | }
27 | });
28 | }
29 | export async function resetPassword() {
30 | await sendPasswordResetEmail(auth, usr_email.value)
31 | .then(() => {
32 | Swal.fire({
33 | icon: 'success',
34 | title: 'Password Reset Email Sent Successfully',
35 | showDenyButton: false,
36 | showCancelButton: false,
37 | confirmButtonText: 'ok',
38 | }).then((result) => {
39 | if (result.isConfirmed) {
40 | location.href = "index.html";
41 | }
42 | })
43 | })
44 | .catch((error) => {
45 | const errorCode = error.code;
46 | Swal.fire({
47 | icon: 'error',
48 | title: 'Oops...',
49 | text: errorCode
50 | })
51 | });
52 | }
--------------------------------------------------------------------------------
/registration.css:
--------------------------------------------------------------------------------
1 | body {
2 | display: flex;
3 | justify-content: center;
4 | align-items: center;
5 | height: 100vh;
6 | background-color: #4070f4;
7 | }
8 |
9 | .containerDiv {
10 | background-color: white;
11 | border-radius: 10px;
12 | padding: 40px 20px;
13 | width: 400px;
14 | }
15 |
16 | button {
17 | width: 100%;
18 | background-color: #ff2806 !important;
19 | }
20 | .form-label span {
21 | color: red;
22 | }
23 | #errorPara {
24 | color: red;
25 | }
26 |
27 | #alreadyAccountPara {
28 | text-align: center;
29 | }
30 |
31 | .hr-text {
32 | line-height: 1em;
33 | position: relative;
34 | outline: 0;
35 | border: 0;
36 | color: black;
37 | text-align: center;
38 | height: 1.5em;
39 | opacity: 0.5;
40 |
41 | &:before {
42 | content: "";
43 | /* // use the linear-gradient for the fading effect
44 | // use a solid background color for a solid bar */
45 | background: linear-gradient(to right, transparent, #000000, transparent);
46 | position: absolute;
47 | left: 0;
48 | top: 50%;
49 | width: 100%;
50 | height: 1px;
51 | }
52 |
53 | &:after {
54 | content: attr(data-content);
55 | position: relative;
56 | display: inline-block;
57 | color: black;
58 |
59 | padding: 0 0.5em;
60 | line-height: 1.5em;
61 | /* // this is really the only tricky part, you need to specify the background color of the container element... */
62 | color: #818078;
63 | background-color: #fcfcfa;
64 | }
65 | }
66 |
67 | #googleSignInBtn {
68 | background: transparent !important;
69 | border: none;
70 | display: flex;
71 | align-items: center;
72 | justify-content: center;
73 | gap: 20px;
74 | border: 1px solid #cdcbcb;
75 | padding: 5px 0;
76 | }
77 |
78 | #googleSignInBtn img {
79 | width: 35px;
80 | }
81 |
82 | @media (max-width: 330px) {
83 | body {
84 | padding: 20px;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Foodara
8 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
38 |
39 |
40 |
41 | Loading...
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | import {
2 | auth,
3 | signInWithEmailAndPassword,
4 | db,
5 | collection,
6 | getDocs,
7 | onAuthStateChanged,
8 | } from "./js/firebase.js";
9 |
10 | const login = () => {
11 | const email = document.getElementById("email");
12 | const password = document.getElementById("password");
13 | signInWithEmailAndPassword(auth, email.value, password.value)
14 | .then((userCredential) => {
15 | const user = userCredential.user;
16 | console.log(user);
17 | if (user.email === "admin@gmail.com") {
18 | location.href = "dashboard.html";
19 | } else {
20 | }
21 | })
22 | .catch((error) => {
23 | const errorCode = error.code;
24 | const errorMessage = error.message;
25 | console.log("err->", errorMessage);
26 | });
27 | };
28 |
29 | const loginBtn = document.getElementById("loginBtn");
30 |
31 | loginBtn && loginBtn.addEventListener("click", login);
32 |
33 | const pageSpinner = document.getElementById("page-spinner");
34 |
35 | const getAllRestaurants = async () => {
36 | const resList = document.getElementById("res-list");
37 | resList.innerHTML = "";
38 | const q = collection(db, "restaurants");
39 | const querySnapshot = await getDocs(q);
40 | let index = 0;
41 | pageSpinner.style.display = "none";
42 | querySnapshot.forEach((doc) => {
43 | console.log(doc.id, " => ", doc.data());
44 | resList.innerHTML += `
45 |
46 |
47 |
.image})
49 |
50 |
${doc.data().name}
51 |
All variety are available
52 |
53 |
54 | Biryani
55 | Karahi
56 | Drinks
57 |
58 |
View all dishes
60 |
61 |
62 |
63 | `;
64 | });
65 | };
66 |
67 | onAuthStateChanged(auth, (user) => {
68 | if (
69 | (user && location.pathname.indexOf("restaurants") !== -1) ||
70 | location.pathname === "/"
71 | ) {
72 | getAllRestaurants();
73 | }
74 | });
75 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | .navbar {
2 | background-color: #fff;
3 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, .12), inset 0 -1px 0 0 #dadce0;
4 | height: 70px;
5 | }
6 |
7 | .btn-primary {
8 | background-color: #ff2806;
9 | border-color: #ff2806;
10 | }
11 |
12 |
13 | .btn-primary:hover {
14 | background-color: #ff2806;
15 | border-color: #ff2806;
16 | }
17 |
18 |
19 | .btn-primary:active {
20 | background-color: #ff2806;
21 | border-color: #ff2806;
22 | opacity: 0.5;
23 | }
24 |
25 | .btn-outline-primary {
26 | border-color: #00ff00;
27 | color: #00ff00;
28 | }
29 |
30 | .btn-outline-primary:hover {
31 | background-color: #fff;
32 | border-color: #00ff00;
33 | color: #00ff00;
34 | }
35 |
36 | .btn-outline-primary:active {
37 | background-color: #fff;
38 | border-color: #00ff00;
39 | color: #00ff00;
40 | opacity: 0.5;
41 | }
42 |
43 | .text-bg-primary {
44 | background-color: #fbe50a !important;
45 | color: #000 !important;
46 | }
47 |
48 | .dish-image {
49 | width: 100px;
50 | height: 100px;
51 | object-fit: cover;
52 | border-radius: 10px;
53 | }
54 |
55 |
56 | .dish-card>div>div>div>div>.card-title {
57 | font-size: 14px;
58 | }
59 |
60 | .dish-card>div>div>div>div>p {
61 | font-size: 12px;
62 | }
63 |
64 | .dish-card>div>div>div>a {
65 | font-size: 12px;
66 | height: fit-content;
67 | }
68 |
69 | .qty-btn {
70 | background-color: #fff;
71 | border: 1px solid #ff2806;
72 | height: 30px;
73 | width: 30px;
74 | border-radius: 15px;
75 | display: flex;
76 | justify-content: center;
77 | align-items: center;
78 | font-size: 12px;
79 | font-weight: bold;
80 | }
81 |
82 | .socail-icons>i {
83 | font-size: 28px;
84 | color: #ff2806;
85 | }
86 |
87 | .fit-height {
88 | height: fit-content;
89 | }
90 |
91 | .slected-logo {
92 | display: none;
93 | }
94 |
95 | .spinner-border {
96 | width: 20px;
97 | height: 20px;
98 | font-size: 10px;
99 | }
100 |
101 | #submit-restaurant,
102 | #addDish {
103 | display: flex;
104 | align-items: center;
105 | gap: 4px;
106 | }
107 |
108 | #restaurant-spinner,
109 | #dish-spinner {
110 | display: none;
111 | }
112 |
113 | .res-logo-image,
114 | .dish-image {
115 | width: 30px;
116 | height: 30px;
117 | border-radius: 15px;
118 | }
119 |
120 | .card-img-top {
121 | width: 100%;
122 | height: 200px;
123 | object-fit: cover;
124 | }
125 |
126 | .page-spinner {
127 | width: 200px;
128 | height: 200px;
129 | }
--------------------------------------------------------------------------------
/register.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Signup
10 |
11 |
12 |
13 |
14 |
15 |
52 |
53 |
54 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/forgate.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Forgot Password | Firebase Auth Using JavaScript
8 |
10 |
11 |
12 |
13 |
14 |
15 |
43 |
44 |
45 |
69 |
70 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/js/restaurant.js:
--------------------------------------------------------------------------------
1 | import { storage, ref, uploadBytesResumable, getDownloadURL, db, collection, addDoc, getDocs } from "./firebase.js"
2 |
3 | const logo = document.getElementById("restaurant-logo");
4 | const selectedLogo = document.getElementById("selected-logo");
5 | let file;
6 |
7 | logo && logo.addEventListener("change", (e) => {
8 | file = e.target.files[0];
9 | selectedLogo.style.display = "flex";
10 | selectedLogo.src = URL.createObjectURL(e.target.files[0])
11 | })
12 |
13 |
14 | let uploadFile = (file, name) => {
15 | return new Promise((resolve, reject) => {
16 | const storageRef = ref(storage, `images/${name.split(" ").join("-")}`);
17 | const uploadTask = uploadBytesResumable(storageRef, file);
18 | uploadTask.on('state_changed',
19 | (snapshot) => {
20 | const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
21 | console.log('Upload is ' + progress + '% done');
22 | switch (snapshot.state) {
23 | case 'paused':
24 | console.log('Upload is paused');
25 | break;
26 | case 'running':
27 | console.log('Upload is running');
28 | break;
29 | }
30 | },
31 | (error) => {
32 | reject(error)
33 | },
34 | () => {
35 |
36 | getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
37 | console.log('File available at', downloadURL);
38 | resolve(downloadURL)
39 | });
40 | }
41 | );
42 | })
43 | }
44 |
45 | const getAllRestaurants = async () => {
46 | const resList = document.getElementById("res-list");
47 | resList.innerHTML = "";
48 | const q = collection(db, "restaurants");
49 | const querySnapshot = await getDocs(q);
50 | let index = 0;
51 | querySnapshot.forEach((doc) => {
52 | console.log(doc.id, " => ", doc.data());
53 | index++
54 | resList.innerHTML += `
55 |
56 | | ${index} |
57 | .image}) |
58 | ${doc.data().name} |
59 | ${doc.data().address} |
60 |
61 | `
62 | });
63 | }
64 |
65 | getAllRestaurants()
66 |
67 |
68 | const submitRestaurant = document.getElementById("submit-restaurant");
69 |
70 |
71 | submitRestaurant && submitRestaurant.addEventListener('click', async () => {
72 | const closeBtn = document.getElementById("close-btn")
73 | const spinner = document.getElementById("restaurant-spinner");
74 | const name = document.getElementById("restaurant-name");
75 | const address = document.getElementById("restaurant-address");
76 | spinner.style.display = "block"
77 | const image = await uploadFile(file, name.value)
78 | const docRef = await addDoc(collection(db, "restaurants"), {
79 | name: name.value,
80 | address: address.value,
81 | image
82 | });
83 | spinner.style.display = "none"
84 | name.value = "";
85 | address.value = "";
86 | logo.value = "";
87 | selectedLogo.style.display = "none";
88 | console.log("Document written with ID: ", docRef.id);
89 | getAllRestaurants();
90 | closeBtn.click()
91 | })
92 |
93 | export { uploadFile };
--------------------------------------------------------------------------------
/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
We'll never share your email with anyone else.
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
61 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/js/registration.js:
--------------------------------------------------------------------------------
1 |
2 | import {auth,createUserWithEmailAndPassword,provider,onAuthStateChanged,signInWithPopup,db,doc,setDoc} from './firebase.js';
3 |
4 |
5 |
6 | let sbtn = document.querySelector("#sbtn"); // get signin btn
7 | let errorPara = document.querySelector("#errorPara"); // get error paragraph
8 |
9 | sbtn.addEventListener("click", () => {
10 | let Email = document.querySelector("#semail"); // get email to signin user
11 | let password = document.querySelector("#spassword"); // get password to signin user
12 | let name = document.querySelector("#sname"); // get name of a user
13 | let phoneNumber = document.querySelector("#pNumber"); // get name of a user
14 | let Address = document.querySelector("#Address"); // get name of a user
15 |
16 | if (name.value == "") {
17 | errorPara.innerText = "Please fill name field!";
18 | setTimeout(() => {
19 | errorPara.innerHTML = "";
20 | }, 3000);
21 | } else {
22 | // storing data in a array
23 | let userData = {
24 | fullName: name.value,//s mean save
25 | Email: Email.value,
26 | password: password.value,
27 | phoneNumber : phoneNumber.value,
28 | Address:Address.value
29 | };
30 | // creating user with eamil and password
31 | createUserWithEmailAndPassword(auth, userData.Email, userData.password)
32 | // email value , password value
33 | .then(async (userCredential) => {
34 | const user = userCredential.user; // getting user from firebase
35 | await setDoc(doc(db, "users", user.uid), {
36 | // collection name, unique id of user
37 | ...userData, // setting array in a database
38 | userId: user.uid, // also user id in the database
39 | });
40 | location.href = "../login.html";
41 | })
42 | .catch((error) => {
43 | const errorCode = error.code;
44 | const errorMessage = errorCode.slice(5).toUpperCase();
45 | const errMessage = errorMessage.replace(/-/g, " ");
46 | errorPara.innerText = errMessage;
47 | setTimeout(() => {
48 | errorPara.innerHTML = "";
49 | }, 3000);
50 | });
51 | }
52 | });
53 |
54 | password.addEventListener("keypress", (e) => {
55 | if (e.key == "Enter") {
56 | sbtn.click();
57 | }
58 | });
59 |
60 | const googleSignInBtn = document.getElementById("googleSignInBtn");
61 |
62 | googleSignInBtn.addEventListener("click", () => {
63 | signInWithPopup(auth, provider)
64 | .then(async (result) => {
65 | const credential = GoogleAuthProvider.credentialFromResult(result);
66 | const token = credential.accessToken;
67 |
68 | const user = result.user;
69 |
70 | let userData = {
71 | name: user.displayName,
72 | Email: user.email,
73 | };
74 |
75 | await setDoc(doc(db, "users", user.uid), {
76 | // collection name, unique id of user
77 | ...userData, // setting array in a database
78 | userId: user.uid, // also user id in the database
79 | });
80 |
81 | localStorage.setItem("userUid", user.uid);
82 |
83 | location.href = "../index.html";
84 | })
85 | .catch((error) => {
86 | // Handle Errors here.
87 | const errorCode = error.code;
88 | const errorMessage = error.message;
89 | // The email of the user's account used.
90 | const email = error.customData.email;
91 | // The AuthCredential type that was used.
92 | const credential = GoogleAuthProvider.credentialFromError(error);
93 |
94 | if (email) {
95 | errorPara.innerText = email;
96 | setTimeout(() => {
97 | errorPara.innerHTML = "";
98 | }, 3000);
99 | }
100 | });
101 | });
102 |
103 | onAuthStateChanged(auth, (user) => {
104 | if (user) {
105 | const userUid = user.uid;
106 | } else {
107 | localStorage.removeItem("userUid");
108 | }
109 | });
110 |
111 | if (localStorage.getItem("userUid")) {
112 | location.href = "../index.html";
113 | }
114 |
--------------------------------------------------------------------------------
/dashboard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
52 |
53 |
54 |
55 |
56 |
57 |
Total restaurants
58 | 500
59 |
60 |
61 |
62 |
63 |
64 |
65 |
Total dishes
66 | 3000
67 |
68 |
69 |
70 |
71 |
72 |
73 |
Total orders
74 | 10000
75 |
76 |
77 |
78 |
79 |
80 |
81 |
Total users
82 | 10
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/js/add-dishes.js:
--------------------------------------------------------------------------------
1 | import { storage, ref, uploadBytesResumable, getDownloadURL, db, collection, addDoc, getDocs } from "./firebase.js"
2 |
3 | let uploadFile = (file, name) => {
4 | return new Promise((resolve, reject) => {
5 | const storageRef = ref(storage, `images/${name.split(" ").join("-")}`);
6 | const uploadTask = uploadBytesResumable(storageRef, file);
7 | uploadTask.on('state_changed',
8 | (snapshot) => {
9 | const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
10 | console.log('Upload is ' + progress + '% done');
11 | switch (snapshot.state) {
12 | case 'paused':
13 | console.log('Upload is paused');
14 | break;
15 | case 'running':
16 | console.log('Upload is running');
17 | break;
18 | }
19 | },
20 | (error) => {
21 | reject(error)
22 | },
23 | () => {
24 |
25 | getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
26 | console.log('File available at', downloadURL);
27 | resolve(downloadURL)
28 | });
29 | }
30 | );
31 | })
32 | }
33 |
34 | const getAllRestaurants = async () => {
35 | try {
36 | const q = collection(db, "restaurants");
37 | const querySnapshot = await getDocs(q);
38 | const resSelect = document.getElementById("restaurant-name");
39 | let index = 0;
40 | let restaurants = [];
41 | resSelect.innerHTML = ``
42 | querySnapshot.forEach((doc) => {
43 | restaurants.push({ ...doc.data(), id: doc.id })
44 | index++
45 | resSelect.innerHTML += `
46 |
47 | `
48 | });
49 | return new Promise((resolve, reject) => {
50 | resolve(restaurants)
51 | })
52 | } catch (err) {
53 | console.log("err", err)
54 | }
55 | }
56 |
57 | getAllRestaurants()
58 |
59 | const getAllDishes = async () => {
60 | const restaurants = await getAllRestaurants();
61 | const allDishes = document.getElementById("all-dishes");
62 | const q = collection(db, "dishes");
63 | const querySnapshot = await getDocs(q);
64 | let index = 0;
65 | let restaurantNames = {};
66 | for (var i = 0; i < restaurants.length; i++) {
67 | restaurantNames[restaurants[i].id] = restaurants[i].name
68 | }
69 | console.log("restaurantNames", restaurantNames)
70 | allDishes.innerHTML = ``
71 | querySnapshot.forEach((doc) => {
72 | index++;
73 | allDishes.innerHTML += `
74 |
75 | | 1 |
76 | .image}) |
77 | ${doc.data().name} |
78 | ${doc.data().price} |
79 | ${doc.data().serving} |
80 | ${restaurantNames[doc.data().restaurant]} |
81 |
82 | `
83 | });
84 | }
85 |
86 | getAllDishes();
87 |
88 | const addDish = document.getElementById("addDish");
89 |
90 | addDish.addEventListener('click', async () => {
91 | const closeBtn = document.getElementById("close-btn")
92 | const spinner = document.getElementById("dish-spinner");
93 | const resName = document.getElementById("restaurant-name");
94 | const dishName = document.getElementById("dish-name");
95 | const dishPrice = document.getElementById("dish-price");
96 | const dishServing = document.getElementById("dish-serving");
97 | const dishImage = document.getElementById("dish-image");
98 | spinner.style.display = "block"
99 | const image = await uploadFile(dishImage.files[0], dishName.value)
100 | const dishDetail = {
101 | restaurant: resName.value,
102 | name: dishName.value,
103 | price: dishPrice.value,
104 | serving: dishServing.value,
105 | image
106 | }
107 | const docRef = await addDoc(collection(db, "dishes"), dishDetail);
108 | resName.value = "";
109 | dishName.value = "";
110 | dishPrice.value = "";
111 | dishServing.value = "";
112 | dishImage.value = "";
113 | spinner.style.display = "none"
114 | closeBtn.click()
115 | getAllDishes()
116 | console.log(docRef)
117 | })
--------------------------------------------------------------------------------
/orders.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
13 |
14 |
15 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
79 |
80 |
81 |
82 | Loading...
83 |
84 |
85 |
86 |
87 |
88 |
Orders
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | | # |
97 | Customer name |
98 | Customer contact |
99 | Customer address |
100 | Status |
101 | Total |
102 | Order |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
116 |
117 |
118 |
130 |
131 |
132 |
133 |
142 |
143 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/js/order.js:
--------------------------------------------------------------------------------
1 | import {
2 | storage,
3 | ref,
4 | uploadBytesResumable,
5 | getDownloadURL,
6 | db,
7 | collection,
8 | addDoc,
9 | getDocs,
10 | serverTimestamp,
11 | doc,
12 | getDoc,
13 | updateDoc,
14 | } from "./firebase.js";
15 | const placeOrder = document.getElementById("placeOrder");
16 |
17 | placeOrder &&
18 | placeOrder.addEventListener("click", async () => {
19 | const cartDiv = document.getElementById("cart");
20 | const customerName = document.getElementById("customerName");
21 | const customerContact = document.getElementById("customerContact");
22 | const customerAddress = document.getElementById("customerAddress");
23 | const cart = JSON.parse(localStorage.getItem("cart"));
24 | const sum = cart.reduce((a, b) => a + Number(b.price) * b.qty, 0);
25 | const totalAmount = document.getElementById("totalAmount");
26 | const closeBtn = document.getElementById("closeBtn");
27 |
28 | const orderDetails = {
29 | customerName: customerName.value,
30 | customerContact: customerContact.value,
31 | customerAddress: customerAddress.value,
32 | status: "pending",
33 | cart,
34 | timestamp: serverTimestamp(),
35 | orderAmount: sum,
36 | deliveryCharges: 100,
37 | totalAmount: sum + 100,
38 | };
39 | await addDoc(collection(db, "orders"), orderDetails);
40 | Swal.fire({
41 | position: "center-center",
42 | icon: "success",
43 | title: "Your order has been placed",
44 | showConfirmButton: false,
45 | timer: 1500,
46 | });
47 | customerName.value = "";
48 | customerContact.value = "";
49 | customerAddress.value = "";
50 | localStorage.removeItem("cart");
51 | cartDiv.innerHTML = "";
52 | totalAmount.innerHTML = "";
53 | closeBtn.click();
54 | });
55 |
56 | const getAllOrders = async () => {
57 | const pageSpinner = document.getElementById("page-spinner");
58 | const mainContent = document.getElementById("main-content");
59 | const allOrders = document.getElementById("all-orders");
60 | const q = collection(db, "orders");
61 | const querySnapshot = await getDocs(q);
62 | let index = 0;
63 | querySnapshot.forEach((doc) => {
64 | index++;
65 | console.log("order", doc.data());
66 | let status = doc.data().status;
67 | let statusColor = "";
68 | if (status === "pending") {
69 | statusColor = "text-bg-warning";
70 | }
71 | if (status === "delivered") {
72 | statusColor = "text-bg-success";
73 | }
74 | allOrders.innerHTML += `
75 |
76 | | ${index} |
77 | ${doc.data().customerName} |
78 | ${doc.data().customerContact} |
79 | ${doc.data().customerAddress} |
80 | ${status}
81 | |
82 | ${doc.data().totalAmount} |
83 |
84 |
89 | |
90 |
91 | `;
92 | });
93 | pageSpinner.style.display = "none";
94 | mainContent.style.display = "block";
95 | };
96 |
97 | getAllOrders();
98 |
99 | let updateOrderId;
100 |
101 | const viewOrderDetail = async (id) => {
102 | updateOrderId = id;
103 | const cart = document.getElementById("cart");
104 | const orderStatus = document.getElementById("orderStatus");
105 | const docRef = doc(db, "orders", id);
106 | const docSnap = await getDoc(docRef);
107 | const cartItems = docSnap.data().cart;
108 | orderStatus.value = docSnap.data().status;
109 | cart.innerHTML = "";
110 | for (var i = 0; i < cartItems.length; i++) {
111 | cart.innerHTML += `
112 |
113 |
114 |
115 |
116 |

120 |
121 |
${
122 | cartItems[i].name
123 | }
124 |
Rs: ${
125 | cartItems[i].price
126 | } /- x ${
127 | cartItems[i].qty
128 | } = ${cartItems[i].price * cartItems[i].qty}
129 |
Serves ${
130 | cartItems[i].serving
131 | }
132 |
133 |
134 |
135 |
136 |
137 |
138 | `;
139 | }
140 | };
141 |
142 | const updateOrder = document.getElementById("updateOrder");
143 |
144 | updateOrder.addEventListener("click", async () => {
145 | const closeBtn = document.getElementById("close-btn");
146 | const orderStatus = document.getElementById("orderStatus");
147 | const docRef = doc(db, "orders", updateOrderId);
148 | await updateDoc(docRef, {
149 | status: orderStatus.value,
150 | });
151 | closeBtn.click();
152 | getAllOrders();
153 | });
154 |
155 | window.viewOrderDetail = viewOrderDetail;
156 |
--------------------------------------------------------------------------------
/js/dishes.js:
--------------------------------------------------------------------------------
1 | import {
2 | collection,
3 | getDocs,
4 | db,
5 | where,
6 | query,
7 | doc,
8 | getDoc,
9 | } from "./firebase.js";
10 |
11 | var urlParams = new URLSearchParams(window.location.search);
12 | let pageSpinner = document.getElementById("page-spinner");
13 | let mainContent = document.getElementById("main-content");
14 |
15 | const getRestaurantDetail = async () => {
16 | const resName = document.getElementById("res-name");
17 | const resAddress = document.getElementById("res-address");
18 | const resImage = document.getElementById("res-image");
19 | const docRef = doc(db, "restaurants", urlParams.get("restaurant"));
20 | const docSnap = await getDoc(docRef);
21 | if (docSnap.exists()) {
22 | resName.innerHTML = docSnap.data().name;
23 | resAddress.innerHTML = docSnap.data().address;
24 | resImage.src = docSnap.data().image;
25 | console.log("Document data:", docSnap.data());
26 | } else {
27 | // docSnap.data() will be undefined in this case
28 | console.log("No such document!");
29 | }
30 | };
31 |
32 | getRestaurantDetail();
33 |
34 | let dishes = [];
35 |
36 | const getAllDishes = async () => {
37 | const allDishes = document.getElementById("all-dishes");
38 | const q = query(
39 | collection(db, "dishes"),
40 | where("restaurant", "==", urlParams.get("restaurant"))
41 | );
42 | const querySnapshot = await getDocs(q);
43 | pageSpinner.style.display = "none";
44 | mainContent.style.display = "block";
45 | allDishes.innerHTML = ``;
46 | querySnapshot.forEach((doc) => {
47 | dishes.push({ ...doc.data(), id: doc.id });
48 | allDishes.innerHTML += `
49 |
50 |
51 |
52 |
53 |
.image})
55 |
56 |
${doc.data().name}
57 |
Rs: ${doc.data().price} /-
58 |
Serves ${doc.data().serving}
59 |
60 |
61 |
62 |
75 |
76 |
77 |
78 | `;
79 | });
80 | };
81 |
82 | getAllDishes();
83 |
84 | const updateQty = (type, id) => {
85 | const qty = document.getElementById(id);
86 | if (Number(qty.innerHTML) < 2 && type === "-") {
87 | return;
88 | }
89 | if (type === "+") {
90 | qty.innerHTML = Number(qty.innerHTML) + 1;
91 | } else {
92 | qty.innerHTML = Number(qty.innerHTML) - 1;
93 | }
94 | };
95 |
96 | const addToCart = (id) => {
97 | const cartItems = localStorage.getItem("cart");
98 | const cart = cartItems ? JSON.parse(cartItems) : [];
99 | const qty = document.getElementById(id);
100 | const dish = dishes.filter((v) => v.id === id);
101 | cart.push({ ...dish[0], qty: Number(qty.innerHTML) });
102 | localStorage.setItem("cart", JSON.stringify(cart));
103 | console.log("cart", cart);
104 | const totalAmount = document.getElementById("totalAmount");
105 | const sum = cart.reduce((a, b) => a + Number(b.price) * b.qty, 0);
106 | totalAmount.innerHTML = `Rs ${sum + 100} /-`;
107 | getCartItems();
108 | };
109 |
110 | const deleteCartItem = (i) => {
111 | const cartItems = JSON.parse(localStorage.getItem("cart"));
112 | cartItems.splice(Number(i), 1);
113 | localStorage.setItem("cart", JSON.stringify(cartItems));
114 | const totalAmount = document.getElementById("totalAmount");
115 | const sum = cartItems.reduce((a, b) => a + Number(b.price) * b.qty, 0);
116 | totalAmount.innerHTML = `Rs ${sum + 100} /-`;
117 | getCartItems();
118 | };
119 |
120 | const getCartItems = () => {
121 | const cartItems = JSON.parse(localStorage.getItem("cart"));
122 | const cart = document.getElementById("cart");
123 | cart.innerHTML = "";
124 | if (cartItems) {
125 | for (var i = 0; i < cartItems.length; i++) {
126 | console.log(cartItems[i]);
127 | cart.innerHTML += `
128 |
129 |
130 |
131 |
132 |

134 |
135 |
${
136 | cartItems[i].name
137 | }
138 |
Rs: ${
139 | cartItems[i].price
140 | } /- x ${cartItems[i].qty} = ${
141 | cartItems[i].price * cartItems[i].qty
142 | }
143 |
Serves ${
144 | cartItems[i].serving
145 | }
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 | `;
154 | }
155 | }
156 | };
157 |
158 | getCartItems();
159 |
160 | window.updateQty = updateQty;
161 | window.addToCart = addToCart;
162 | window.deleteCartItem = deleteCartItem;
163 |
--------------------------------------------------------------------------------
/restaurants.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
52 |
53 |
54 |
55 |
Restaurants
56 |
57 |
58 |
61 |
63 |
64 |
65 |
70 |
71 |
72 |
73 |
75 |
76 |
77 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
![]()
88 |
89 |
90 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 | | # |
111 | Restaurant image |
112 | Restaurant name |
113 | Address |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/add-dishes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
52 |
53 |
54 |
55 |
Dishes
56 |
57 |
60 |
62 |
63 |
64 |
69 |
70 |
71 |
72 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
![]()
103 |
104 |
105 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | | # |
127 | Dish image |
128 | Dish name |
129 | Price |
130 | Serving |
131 | Restaurant |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/dishes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
13 |
14 |
15 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
60 |
61 |
62 |
63 | Loading...
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

81 |
82 |
Saylani Foods
83 |
84 |
Biryani
87 |
Biryani
90 |
Biryani
93 |
Biryani
96 |
Biryani
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
118 |
119 |
127 |
128 |
135 |
136 |
137 |
148 |
149 |
150 |
153 |
159 |
160 |
161 |
164 |
170 |
171 |
172 |
175 |
180 |
181 |
182 | Delivery charges:
183 | Rs 100 /-
184 |
185 |
186 | Total amount:
187 | Rs 343
188 |
189 |
190 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
--------------------------------------------------------------------------------