├── .gitignore ├── README.md ├── app ├── (main-area) │ ├── generateQR │ │ └── page.js │ ├── menuBuilder │ │ └── page.js │ └── services │ │ └── page.js ├── About │ └── page.js ├── Auth │ └── page.js ├── Contact │ └── page.js ├── MenuInterface │ └── [user] │ │ └── page.js ├── api │ ├── Activeuser │ │ └── route.js │ ├── auth │ │ └── [...nextauth] │ │ │ └── route.js │ ├── gemini │ │ └── route.js │ ├── get-ip │ │ └── route.js │ ├── history │ │ └── route.js │ ├── menuItems │ │ └── route.js │ ├── order │ │ ├── cancel │ │ │ └── route.js │ │ ├── done │ │ │ └── route.js │ │ └── route.js │ ├── sections │ │ └── route.js │ └── upload │ │ └── route.js ├── dashboard │ ├── layout.js │ ├── liveorder │ │ └── page.js │ ├── page.js │ ├── salesrevenue │ │ └── page.js │ └── transactionhistory │ │ └── page.js ├── globals.css ├── layout.js ├── lib │ ├── DataBase.js │ ├── model │ │ ├── Menu.js │ │ ├── SectionDB.js │ │ ├── Visitors.js │ │ ├── orderHistory.js │ │ └── orderItem.js │ └── mongodb.js └── page.js ├── components ├── AccountDropdown.js ├── CompanyShow.js ├── GenerateQR.js ├── ServiceCard.js ├── Sessionwrap.js ├── Signout.js ├── TypeWriter.js ├── dashboard │ ├── aside.js │ ├── home.js │ └── orderTracking.js ├── doc │ └── recept.js ├── footer.js ├── homeNavButton.js ├── menuCard.js ├── menuDone.js ├── menuInterface │ ├── AI_interface.js │ ├── Cart.js │ ├── Confirmpage.js │ ├── Footer.js │ ├── Menupopulate.js │ ├── SectionTitle.js │ ├── ai_chat.js │ ├── confirm_pop.js │ ├── itemCard.js │ ├── itemContext.js │ ├── navbar.js │ └── sections.js ├── menuSubmitbtn.js ├── menu_ItemCard_default.js ├── menu_builder_section.js ├── navbar.js └── service-poster.js ├── eslint.config.mjs ├── jsconfig.json ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.mjs ├── public ├── MenuInterface │ ├── Ai.mp4 │ ├── ailogo.mp4 │ ├── b1.jpg │ └── b2.jpg ├── dashboard │ └── b1.jpg ├── file.svg ├── globe.svg ├── homepage │ └── bg.png ├── next.svg ├── notification.mp3 ├── profile.jpg ├── qrbuilder │ ├── default-img.png │ └── download.jpeg ├── serviceTab │ ├── poster-1.jpeg │ ├── poster-2.png │ ├── poster-3.png │ ├── qr.png │ ├── s-1.jpg │ ├── s-2.jpg │ ├── s-3.jpg │ └── s-4.jpg ├── shared │ ├── Softcore.png │ ├── TNE-logo.png │ ├── close-up-hands-holding-smartphones.jpg │ ├── logo.mp4 │ ├── logo.png │ └── profile-icon.jpeg ├── uploads │ ├── 360_F_733954401_TdqG5vccceLm5JuSBIGoImDaBxyoMvOc.jpg │ ├── 564931.jpg │ ├── 708311.jpg │ ├── 7509855.jpg │ ├── Baingan Bharta.jpeg │ ├── Boondi Raita.jpeg │ ├── Butter Naan.jpeg │ ├── Chicken Biryani.jpeg │ ├── Chicken Butter Masala.jpeg │ ├── Chicken Shorba.jpg │ ├── Chicken Tikka.jpeg │ ├── Chicken Tikka.jpg │ ├── Coconut Chutney.jpeg │ ├── Dal Makhani.jpeg │ ├── Fish Amritsari.jpg │ ├── Fish Curry.jpeg │ ├── Gajar Ka Halwa.webp │ ├── Garlic Naan.jpeg │ ├── Gulab Jamun.jpg │ ├── Hyderabadi Biryani.jpeg │ ├── Jalebi (per plate).jpeg │ ├── Jeera Rice.jpeg │ ├── Kachumber Salad.jpeg │ ├── Lachha Paratha.jpg │ ├── Manchow Soup.jpeg │ ├── Mutton Biryani.jpeg │ ├── Mutton Rogan Josh.jpeg │ ├── Mutton Seekh Kebab.jpg │ ├── OIP.jpg │ ├── OnionCucumber Raita.jpeg │ ├── Pakoras (Mix Veg).jpeg │ ├── Pakoras (Mix Veg).jpg │ ├── Palak Paneer.jpeg │ ├── Paneer Butter Masala.jpeg │ ├── Paneer Butter Masala.jpg │ ├── Peas Pulao.jpeg │ ├── Rasgulla.jpeg │ ├── Rasmalai (2 pcs).jpeg │ ├── Roomali Roti.jpg │ ├── Steamed Basmati Rice.jpeg │ ├── Sweet Corn Soup.webp │ ├── Tandoori Roti.jpeg │ ├── Tomato Soup.jpeg │ ├── Veg Biryani.jpeg │ ├── aloo tikki.jpeg │ ├── aura++.gif │ ├── baingan-bharta.jpg │ ├── cholekulche2.jpg │ ├── momos.jpg │ ├── pain-naruto-indigo-5120x2880-10830.png │ ├── paneer-tikka.jpg │ ├── samosa.jpeg │ └── sung-jinwoo-movie-5120x2880-20245.jpg ├── vercel.svg └── window.svg └── tailwind.config.mjs /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🍽️ QR MENU - Digital Menu & Smart Ordering System 2 | 3 | 4 | ## 🚀 Overview 5 | QR MENU is a **Next.js-based** digital restaurant menu and ordering system designed to replace traditional **paper menus**. It allows **restaurant owners** to dynamically update their menus, generate **QR codes for tables**, and track **orders, revenue, and visitor trends** in real-time. 6 | 7 | 🔹 **No More Reprinting Menus** – Update anytime, instantly! 8 | 🔹 **QR Code Table Management** – Unique QR per table for **seamless ordering**. 9 | 🔹️ **🤖 AI-Powered Food Assistant** – Helps customers with **menu suggestions, dietary preferences, and dish recommendations**. 10 | 🔹 **Real-time Orders & Analytics** – Track transactions, revenue, and customer trends. 11 | 🔹 **Secure Owner Login** – Prevents unauthorized menu access using **NextAuth.js**. 12 | 🔹 **Smooth UI & Mobile Responsive** – Powered by **Next.js + Tailwind CSS**. 13 | 14 | --- 15 | 16 | ## 🏗️ Tech Stack 17 | - **Frontend:** Next.js (React) + Tailwind CSS 18 | - **Backend:** Node.js + Express.js 19 | - **Database:** MongoDB 20 | - **Authentication:** NextAuth.js 21 | 22 | --- 23 | 24 | ## 📌 Installation & Setup 25 | ### **1️⃣ Clone the Repository** 26 | ```sh 27 | git clone https://github.com/Softenrj/qr-menu.git 28 | cd qr-menu 29 | ``` 30 | 31 | ### **2️⃣ Install Dependencies** 32 | ```sh 33 | # Install dependencies 34 | npm install 35 | ``` 36 | 37 | ### **3️⃣ Environment Variables** 38 | Create a `.env` file and add the following: 39 | ```sh 40 | NEXTAUTH_URL=your-site-url 41 | MONGODB_URL=your-mongodb-url 42 | NEXTAUTH_SECRET=your-secret-key 43 | //example 44 | GITHUB_ID=key 45 | GITHUB_SECRET=key 46 | GEMINI_URL=key 47 | ``` 48 | 49 | ### **4️⃣ Start the Development Server** 50 | ```sh 51 | npm run dev 52 | ``` 53 | 54 | --- 55 | 56 | ## 🎨 UI & User Experience 57 | ✅ **Modern, responsive design** with **Tailwind CSS**. 58 | ✅ **Smooth animations & intuitive navigation** for a better experience. 59 | ✅ **Mobile-first approach** ensures seamless use across devices. 60 | 61 | ## 🔒 Access the Dashboard without authentication for **testing purposes**. 62 | `Remove This File from 👉 'qr-menu/app/dashboard/page.js'` 63 | ```sh 64 | if (status === "unauthenticated") { 65 | router.push('/'); 66 | } 67 | ``` 68 | 69 | 70 | ## 📜 License 71 | This project is intended for **educational purposes only**. If you wish to use it for commercial or other purposes, please request **permission** 72 | 73 | --- 74 | 75 | ## 🤝 Contributing 76 | Contributions are welcome! Submit issues or pull requests to improve the project. 77 | 78 | --- 79 | 80 | ## 📬 Contact 81 | 📧 Email: rjsharmase@gmail.com 82 | 83 | -------------------------------------------------------------------------------- /app/(main-area)/generateQR/page.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React, { useState, useEffect } from "react"; 3 | import GenerateQR from "@/components/GenerateQR"; 4 | import { Save, Delete, Download } from "@mui/icons-material"; 5 | import { v4 as uuidv4 } from "uuid"; 6 | import Navbar from "@/components/navbar"; 7 | import Footer from "@/components/footer"; 8 | import TypeWriter from "@/components/TypeWriter"; 9 | 10 | const QRGeneratorPage = () => { 11 | const [inputId, setInputId] = useState(""); 12 | const [qrValue, setQrValue] = useState(""); 13 | const [savedQrs, setSavedQrs] = useState([]); 14 | const [date, setDate] = useState(""); 15 | 16 | useEffect(() => { 17 | setDate(Date.now()); 18 | }, []); 19 | 20 | const generateNewQR = () => { 21 | const uniqueId = uuidv4().slice(0, 8); 22 | const newValue = inputId || uniqueId; 23 | setQrValue(newValue); 24 | }; 25 | 26 | const handleSaveQR = () => { 27 | if (qrValue) { 28 | setSavedQrs((prev) => [ 29 | ...prev, 30 | { 31 | id: inputId || `QR-${uuidv4().slice(0, 4)}`, 32 | value: qrValue, 33 | timestamp: Date.now(), 34 | }, 35 | ]); 36 | setInputId(""); 37 | setQrValue(""); 38 | } 39 | }; 40 | 41 | const handleDownload = (id, date) => { 42 | const canvas = document.querySelector(`#${id} canvas`); 43 | if (!canvas) { 44 | console.error("Canvas not found for ID:", id); 45 | return; 46 | } 47 | const link = document.createElement("a"); 48 | link.download = `qr-code-${date}.png`; 49 | link.href = canvas.toDataURL(); 50 | link.click(); 51 | }; 52 | 53 | const handleDelete = (timestamp) => { 54 | setSavedQrs(savedQrs.filter((qr) => qr.timestamp !== timestamp)); 55 | }; 56 | 57 | return ( 58 |
59 | 60 |
61 |

62 | Generate Your 63 | 64 | 65 | 66 |

67 |

68 | 69 |

70 |
71 | 72 |
73 |
74 |
75 |
76 |
77 | 80 | setInputId(e.target.value)} 84 | placeholder="e.g., Table 2" 85 | className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-pink-500 focus:border-pink-500" 86 | /> 87 |
88 | 89 | 95 | 96 | {qrValue && ( 97 | 104 | )} 105 |
106 | 107 | {/* QR Preview */} 108 |
109 | 110 |
111 |
112 |
113 | 114 | {/* Saved QR Codes */} 115 | {savedQrs.length > 0 && ( 116 |
117 |

Saved QR Codes

118 |
119 | {savedQrs.map((qr) => ( 120 |
121 | 122 |

123 | {qr.id} 124 |

125 | 126 |
127 | 133 | 139 |
140 |
141 | ))} 142 |
143 |
144 | )} 145 |
146 |
148 | ); 149 | }; 150 | 151 | export default QRGeneratorPage; 152 | -------------------------------------------------------------------------------- /app/(main-area)/menuBuilder/page.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Navbar from '@/components/navbar'; 3 | import Footer from '@/components/footer'; 4 | import Section from '@/components/menu_builder_section'; 5 | import TypeWriter from '@/components/TypeWriter'; 6 | import Menudone from '@/components/menuDone' 7 | 8 | const Page = () => { 9 | return ( 10 |
11 | 12 |
13 |
14 |

Let Make Your Menu

15 |

16 |
17 |
18 |
19 |
20 | 21 | 22 | 23 | 24 |
25 |
27 | ); 28 | } 29 | 30 | export default Page; 31 | -------------------------------------------------------------------------------- /app/(main-area)/services/page.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Navbar from '@/components/navbar'; 3 | import Footer from '@/components/footer'; 4 | import Poster from '@/components/service-poster'; 5 | import QrCodeIcon from '@mui/icons-material/QrCode'; 6 | import AccessTimeIcon from '@mui/icons-material/AccessTime'; 7 | import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; 8 | import CurrencyRupeeIcon from '@mui/icons-material/CurrencyRupee'; 9 | import ServiceCard from '@/components/ServiceCard'; 10 | import TypeWriter from '@/components/TypeWriter'; 11 | import CompanyShow from '@/components/CompanyShow'; 12 | 13 | export default function Service() { 14 | return ( 15 |
16 | 17 |
18 | 19 |
20 |
21 | 22 |
23 |
24 |

25 | Elevating Your Experience with
26 | 27 | 44 | 45 | 46 | 47 |

48 | 49 |
50 |

51 | QR Menu Generator allows restaurants and dhabas to create digital menus with a scannable QR code. 52 | Customers can easily access the menu by scanning the code, eliminating the need for printed menus. 53 | Our platform offers easy menu customization, real-time updates, and a seamless user experience. 54 |

55 |
56 |

Instant QR generate

57 |

RealTime Information

58 |

Integrated Payment

59 |

Menu Pamphlet

60 |
61 |
62 |
63 | 64 |
65 |
66 | 67 | Available Service 68 | 69 | 70 |
71 |
72 | 73 |
74 |
75 | 76 |
77 |
79 | ); 80 | } 81 | -------------------------------------------------------------------------------- /app/About/page.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useState } from "react"; 4 | import { TextField, Button, Container, Typography, Paper, Grid, Snackbar } from "@mui/material"; 5 | import { FaEnvelope, FaPhone, FaMapMarkerAlt } from "react-icons/fa"; 6 | import Navbar from "@/components/navbar"; 7 | import Footer from "@/components/footer"; 8 | 9 | const Contact = () => { 10 | const [formData, setFormData] = useState({ name: "", email: "", message: "" }); 11 | const [submitted, setSubmitted] = useState(false); 12 | 13 | const handleChange = (e) => { 14 | setFormData({ ...formData, [e.target.name]: e.target.value }); 15 | }; 16 | 17 | const handleSubmit = (e) => { 18 | e.preventDefault(); 19 | setSubmitted(true); 20 | setTimeout(() => setSubmitted(false), 3000); 21 | }; 22 | 23 | return ( 24 |
25 | 26 | 27 | 28 | 29 | 30 | Contact Us 31 | 32 | 33 | Have questions or feedback? Reach out to us! 34 | 35 | 36 | 37 | 38 | 39 | support@freelan.com 40 | 41 | 42 | 43 | +1 (555) 123-4567 44 | 45 | 46 | 47 | 123 Freelan Street, Tech City 48 | 49 | 50 | 51 |
52 | 62 | 73 | 85 | 88 | 89 |
90 | 91 | 97 | 98 |
99 |
101 | ); 102 | }; 103 | 104 | export default Contact; -------------------------------------------------------------------------------- /app/Auth/page.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { useSession, signIn, signOut } from "next-auth/react"; 3 | import React, { useEffect } from "react"; 4 | import Navbar from "@/components/navbar"; 5 | import Footer from "@/components/footer"; 6 | import { GitHub, Google, LinkedIn } from "@mui/icons-material"; 7 | import { useRouter } from "next/navigation"; 8 | 9 | const Page = () => { 10 | 11 | const { data: session } = useSession(); 12 | const router = useRouter(); 13 | 14 | useEffect(() => { 15 | if (session) { 16 | router.push("/"); 17 | } 18 | }, [session,router]); 19 | 20 | if (!session) { 21 | return ( 22 |
23 | 24 |
25 |
26 |
27 | Profile 32 |
33 | 34 |

Login

35 | 36 |
37 | 44 | 45 | 52 | 53 | 60 |
61 |
62 |
63 |
65 | ); 66 | } 67 | 68 | return null; 69 | }; 70 | 71 | export default Page; 72 | -------------------------------------------------------------------------------- /app/Contact/page.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React from "react"; 3 | import { useForm } from "react-hook-form"; 4 | import { Container, TextField, Button, Card, CardContent, Typography, Grid } from "@mui/material"; 5 | import Navbar from "@/components/navbar"; 6 | import Footer from "@/components/footer"; 7 | 8 | const ContactPage = () => { 9 | const { register, handleSubmit, formState: { errors } } = useForm(); 10 | 11 | const onSubmit = (data) => { 12 | console.log(data); 13 | }; 14 | 15 | return ( 16 | <> 17 | 18 | 19 | 20 | Get in Touch 21 | 22 | 23 | Have questions about Qmenu? Want to discuss enterprise solutions? 24 | Our team is ready to help you transform your restaurant management. 25 | 26 | 27 | 28 | {/* Contact Form */} 29 | 30 | 31 | 32 |
33 | 41 | 50 | 60 | 68 | 69 |
70 |
71 |
72 | 73 | {/* Contact Info */} 74 | 75 | 76 | 77 | Contact Information 78 | 📍 123 Restaurant Row, New York, NY 10001 79 | 📞 +1 (555) 123-4567 (Mon-Fri, 9am-5pm EST) 80 | ✉️ support@qmenu.com | sales@qmenu.com 81 | 82 | 83 | 84 | {/* Map Placeholder */} 85 | 86 | 87 | Our Location 88 |
89 | Map Placeholder 90 |
91 |
92 |
93 |
94 |
95 |
96 |