├── .gitignore ├── README.md ├── jsconfig.json ├── next.config.mjs ├── package-lock.json ├── package.json ├── public ├── next.svg └── vercel.svg └── src └── app ├── DeliveryHeader.js ├── _components ├── AddFoodItem.js ├── CustomerHeader.js ├── FoodItemList.js ├── Footer.js ├── RestaurantHeader.js ├── UserLogin.js ├── UserSignUp.js ├── restaurantLogin.js └── restaurantSignUp.js ├── api ├── customer │ ├── [id] │ │ └── route.js │ ├── locations │ │ └── route.js │ └── route.js ├── deliverypartners │ ├── [city] │ │ └── route.js │ ├── login │ │ └── route.js │ ├── orders │ │ └── [id] │ │ │ └── route.js │ └── signup │ │ └── route.js ├── order │ └── route.js ├── restaurant │ ├── foods │ │ ├── [id] │ │ │ └── route.js │ │ ├── edit │ │ │ └── [id] │ │ │ │ └── route.js │ │ └── route.js │ └── route.js └── user │ ├── login │ └── route.js │ └── route.js ├── cart └── page.js ├── deliverydashboard └── page.js ├── deliverypartner └── page.js ├── explore └── [name] │ └── page.js ├── favicon.ico ├── globals.css ├── layout.js ├── lib ├── constant.js ├── db.js ├── deliverypartnersMode.js ├── foodsModel.js ├── ordersMode.js ├── restaurantsModel.js └── userModel.js ├── myprofile └── page.js ├── order └── page.js ├── page.js ├── page.module.css ├── restaurant ├── dashboard │ ├── [id] │ │ └── page.js │ └── page.js ├── page.js └── style.css └── user-auth └── page.js /.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.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | # or 12 | pnpm dev 13 | # or 14 | bun dev 15 | ``` 16 | 17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 18 | 19 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. 20 | 21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 22 | 23 | ## Learn More 24 | 25 | To learn more about Next.js, take a look at the following resources: 26 | 27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 29 | 30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 31 | 32 | ## Deploy on Vercel 33 | 34 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 35 | 36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 37 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "resto-app", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "resto-app", 9 | "version": "0.1.0", 10 | "dependencies": { 11 | "mongoose": "^8.2.0", 12 | "next": "14.1.0", 13 | "react": "^18", 14 | "react-dom": "^18" 15 | } 16 | }, 17 | "node_modules/@mongodb-js/saslprep": { 18 | "version": "1.1.4", 19 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", 20 | "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", 21 | "dependencies": { 22 | "sparse-bitfield": "^3.0.3" 23 | } 24 | }, 25 | "node_modules/@next/env": { 26 | "version": "14.1.0", 27 | "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz", 28 | "integrity": "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw==" 29 | }, 30 | "node_modules/@next/swc-darwin-arm64": { 31 | "version": "14.1.0", 32 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz", 33 | "integrity": "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ==", 34 | "cpu": [ 35 | "arm64" 36 | ], 37 | "optional": true, 38 | "os": [ 39 | "darwin" 40 | ], 41 | "engines": { 42 | "node": ">= 10" 43 | } 44 | }, 45 | "node_modules/@next/swc-darwin-x64": { 46 | "version": "14.1.0", 47 | "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz", 48 | "integrity": "sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g==", 49 | "cpu": [ 50 | "x64" 51 | ], 52 | "optional": true, 53 | "os": [ 54 | "darwin" 55 | ], 56 | "engines": { 57 | "node": ">= 10" 58 | } 59 | }, 60 | "node_modules/@next/swc-linux-arm64-gnu": { 61 | "version": "14.1.0", 62 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz", 63 | "integrity": "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ==", 64 | "cpu": [ 65 | "arm64" 66 | ], 67 | "optional": true, 68 | "os": [ 69 | "linux" 70 | ], 71 | "engines": { 72 | "node": ">= 10" 73 | } 74 | }, 75 | "node_modules/@next/swc-linux-arm64-musl": { 76 | "version": "14.1.0", 77 | "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz", 78 | "integrity": "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g==", 79 | "cpu": [ 80 | "arm64" 81 | ], 82 | "optional": true, 83 | "os": [ 84 | "linux" 85 | ], 86 | "engines": { 87 | "node": ">= 10" 88 | } 89 | }, 90 | "node_modules/@next/swc-linux-x64-gnu": { 91 | "version": "14.1.0", 92 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz", 93 | "integrity": "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ==", 94 | "cpu": [ 95 | "x64" 96 | ], 97 | "optional": true, 98 | "os": [ 99 | "linux" 100 | ], 101 | "engines": { 102 | "node": ">= 10" 103 | } 104 | }, 105 | "node_modules/@next/swc-linux-x64-musl": { 106 | "version": "14.1.0", 107 | "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz", 108 | "integrity": "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg==", 109 | "cpu": [ 110 | "x64" 111 | ], 112 | "optional": true, 113 | "os": [ 114 | "linux" 115 | ], 116 | "engines": { 117 | "node": ">= 10" 118 | } 119 | }, 120 | "node_modules/@next/swc-win32-arm64-msvc": { 121 | "version": "14.1.0", 122 | "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz", 123 | "integrity": "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ==", 124 | "cpu": [ 125 | "arm64" 126 | ], 127 | "optional": true, 128 | "os": [ 129 | "win32" 130 | ], 131 | "engines": { 132 | "node": ">= 10" 133 | } 134 | }, 135 | "node_modules/@next/swc-win32-ia32-msvc": { 136 | "version": "14.1.0", 137 | "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz", 138 | "integrity": "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw==", 139 | "cpu": [ 140 | "ia32" 141 | ], 142 | "optional": true, 143 | "os": [ 144 | "win32" 145 | ], 146 | "engines": { 147 | "node": ">= 10" 148 | } 149 | }, 150 | "node_modules/@next/swc-win32-x64-msvc": { 151 | "version": "14.1.0", 152 | "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz", 153 | "integrity": "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg==", 154 | "cpu": [ 155 | "x64" 156 | ], 157 | "optional": true, 158 | "os": [ 159 | "win32" 160 | ], 161 | "engines": { 162 | "node": ">= 10" 163 | } 164 | }, 165 | "node_modules/@swc/helpers": { 166 | "version": "0.5.2", 167 | "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", 168 | "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", 169 | "dependencies": { 170 | "tslib": "^2.4.0" 171 | } 172 | }, 173 | "node_modules/@types/webidl-conversions": { 174 | "version": "7.0.3", 175 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", 176 | "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" 177 | }, 178 | "node_modules/@types/whatwg-url": { 179 | "version": "11.0.4", 180 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.4.tgz", 181 | "integrity": "sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==", 182 | "dependencies": { 183 | "@types/webidl-conversions": "*" 184 | } 185 | }, 186 | "node_modules/bson": { 187 | "version": "6.3.0", 188 | "resolved": "https://registry.npmjs.org/bson/-/bson-6.3.0.tgz", 189 | "integrity": "sha512-balJfqwwTBddxfnidJZagCBPP/f48zj9Sdp3OJswREOgsJzHiQSaOIAtApSgDQFYgHqAvFkp53AFSqjMDZoTFw==", 190 | "engines": { 191 | "node": ">=16.20.1" 192 | } 193 | }, 194 | "node_modules/busboy": { 195 | "version": "1.6.0", 196 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", 197 | "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", 198 | "dependencies": { 199 | "streamsearch": "^1.1.0" 200 | }, 201 | "engines": { 202 | "node": ">=10.16.0" 203 | } 204 | }, 205 | "node_modules/caniuse-lite": { 206 | "version": "1.0.30001587", 207 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", 208 | "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", 209 | "funding": [ 210 | { 211 | "type": "opencollective", 212 | "url": "https://opencollective.com/browserslist" 213 | }, 214 | { 215 | "type": "tidelift", 216 | "url": "https://tidelift.com/funding/github/npm/caniuse-lite" 217 | }, 218 | { 219 | "type": "github", 220 | "url": "https://github.com/sponsors/ai" 221 | } 222 | ] 223 | }, 224 | "node_modules/client-only": { 225 | "version": "0.0.1", 226 | "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", 227 | "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" 228 | }, 229 | "node_modules/debug": { 230 | "version": "4.3.4", 231 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 232 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 233 | "dependencies": { 234 | "ms": "2.1.2" 235 | }, 236 | "engines": { 237 | "node": ">=6.0" 238 | }, 239 | "peerDependenciesMeta": { 240 | "supports-color": { 241 | "optional": true 242 | } 243 | } 244 | }, 245 | "node_modules/debug/node_modules/ms": { 246 | "version": "2.1.2", 247 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 248 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 249 | }, 250 | "node_modules/graceful-fs": { 251 | "version": "4.2.11", 252 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 253 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" 254 | }, 255 | "node_modules/js-tokens": { 256 | "version": "4.0.0", 257 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 258 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 259 | }, 260 | "node_modules/kareem": { 261 | "version": "2.5.1", 262 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", 263 | "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", 264 | "engines": { 265 | "node": ">=12.0.0" 266 | } 267 | }, 268 | "node_modules/loose-envify": { 269 | "version": "1.4.0", 270 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", 271 | "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", 272 | "dependencies": { 273 | "js-tokens": "^3.0.0 || ^4.0.0" 274 | }, 275 | "bin": { 276 | "loose-envify": "cli.js" 277 | } 278 | }, 279 | "node_modules/memory-pager": { 280 | "version": "1.5.0", 281 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 282 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" 283 | }, 284 | "node_modules/mongodb": { 285 | "version": "6.3.0", 286 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", 287 | "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", 288 | "dependencies": { 289 | "@mongodb-js/saslprep": "^1.1.0", 290 | "bson": "^6.2.0", 291 | "mongodb-connection-string-url": "^3.0.0" 292 | }, 293 | "engines": { 294 | "node": ">=16.20.1" 295 | }, 296 | "peerDependencies": { 297 | "@aws-sdk/credential-providers": "^3.188.0", 298 | "@mongodb-js/zstd": "^1.1.0", 299 | "gcp-metadata": "^5.2.0", 300 | "kerberos": "^2.0.1", 301 | "mongodb-client-encryption": ">=6.0.0 <7", 302 | "snappy": "^7.2.2", 303 | "socks": "^2.7.1" 304 | }, 305 | "peerDependenciesMeta": { 306 | "@aws-sdk/credential-providers": { 307 | "optional": true 308 | }, 309 | "@mongodb-js/zstd": { 310 | "optional": true 311 | }, 312 | "gcp-metadata": { 313 | "optional": true 314 | }, 315 | "kerberos": { 316 | "optional": true 317 | }, 318 | "mongodb-client-encryption": { 319 | "optional": true 320 | }, 321 | "snappy": { 322 | "optional": true 323 | }, 324 | "socks": { 325 | "optional": true 326 | } 327 | } 328 | }, 329 | "node_modules/mongodb-connection-string-url": { 330 | "version": "3.0.0", 331 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", 332 | "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", 333 | "dependencies": { 334 | "@types/whatwg-url": "^11.0.2", 335 | "whatwg-url": "^13.0.0" 336 | } 337 | }, 338 | "node_modules/mongoose": { 339 | "version": "8.2.0", 340 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.2.0.tgz", 341 | "integrity": "sha512-la93n6zCYRbPS+c5N9oTDAktvREy5OT9OCljp1Tah0y3+p8UPMTAoabWaLZMdzYruOtF9/9GRf6MasaZjiZP1A==", 342 | "dependencies": { 343 | "bson": "^6.2.0", 344 | "kareem": "2.5.1", 345 | "mongodb": "6.3.0", 346 | "mpath": "0.9.0", 347 | "mquery": "5.0.0", 348 | "ms": "2.1.3", 349 | "sift": "16.0.1" 350 | }, 351 | "engines": { 352 | "node": ">=16.20.1" 353 | }, 354 | "funding": { 355 | "type": "opencollective", 356 | "url": "https://opencollective.com/mongoose" 357 | } 358 | }, 359 | "node_modules/mpath": { 360 | "version": "0.9.0", 361 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", 362 | "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", 363 | "engines": { 364 | "node": ">=4.0.0" 365 | } 366 | }, 367 | "node_modules/mquery": { 368 | "version": "5.0.0", 369 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", 370 | "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", 371 | "dependencies": { 372 | "debug": "4.x" 373 | }, 374 | "engines": { 375 | "node": ">=14.0.0" 376 | } 377 | }, 378 | "node_modules/ms": { 379 | "version": "2.1.3", 380 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 381 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 382 | }, 383 | "node_modules/nanoid": { 384 | "version": "3.3.7", 385 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 386 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 387 | "funding": [ 388 | { 389 | "type": "github", 390 | "url": "https://github.com/sponsors/ai" 391 | } 392 | ], 393 | "bin": { 394 | "nanoid": "bin/nanoid.cjs" 395 | }, 396 | "engines": { 397 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 398 | } 399 | }, 400 | "node_modules/next": { 401 | "version": "14.1.0", 402 | "resolved": "https://registry.npmjs.org/next/-/next-14.1.0.tgz", 403 | "integrity": "sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q==", 404 | "dependencies": { 405 | "@next/env": "14.1.0", 406 | "@swc/helpers": "0.5.2", 407 | "busboy": "1.6.0", 408 | "caniuse-lite": "^1.0.30001579", 409 | "graceful-fs": "^4.2.11", 410 | "postcss": "8.4.31", 411 | "styled-jsx": "5.1.1" 412 | }, 413 | "bin": { 414 | "next": "dist/bin/next" 415 | }, 416 | "engines": { 417 | "node": ">=18.17.0" 418 | }, 419 | "optionalDependencies": { 420 | "@next/swc-darwin-arm64": "14.1.0", 421 | "@next/swc-darwin-x64": "14.1.0", 422 | "@next/swc-linux-arm64-gnu": "14.1.0", 423 | "@next/swc-linux-arm64-musl": "14.1.0", 424 | "@next/swc-linux-x64-gnu": "14.1.0", 425 | "@next/swc-linux-x64-musl": "14.1.0", 426 | "@next/swc-win32-arm64-msvc": "14.1.0", 427 | "@next/swc-win32-ia32-msvc": "14.1.0", 428 | "@next/swc-win32-x64-msvc": "14.1.0" 429 | }, 430 | "peerDependencies": { 431 | "@opentelemetry/api": "^1.1.0", 432 | "react": "^18.2.0", 433 | "react-dom": "^18.2.0", 434 | "sass": "^1.3.0" 435 | }, 436 | "peerDependenciesMeta": { 437 | "@opentelemetry/api": { 438 | "optional": true 439 | }, 440 | "sass": { 441 | "optional": true 442 | } 443 | } 444 | }, 445 | "node_modules/picocolors": { 446 | "version": "1.0.0", 447 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 448 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" 449 | }, 450 | "node_modules/postcss": { 451 | "version": "8.4.31", 452 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", 453 | "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", 454 | "funding": [ 455 | { 456 | "type": "opencollective", 457 | "url": "https://opencollective.com/postcss/" 458 | }, 459 | { 460 | "type": "tidelift", 461 | "url": "https://tidelift.com/funding/github/npm/postcss" 462 | }, 463 | { 464 | "type": "github", 465 | "url": "https://github.com/sponsors/ai" 466 | } 467 | ], 468 | "dependencies": { 469 | "nanoid": "^3.3.6", 470 | "picocolors": "^1.0.0", 471 | "source-map-js": "^1.0.2" 472 | }, 473 | "engines": { 474 | "node": "^10 || ^12 || >=14" 475 | } 476 | }, 477 | "node_modules/punycode": { 478 | "version": "2.3.1", 479 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 480 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 481 | "engines": { 482 | "node": ">=6" 483 | } 484 | }, 485 | "node_modules/react": { 486 | "version": "18.2.0", 487 | "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", 488 | "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", 489 | "dependencies": { 490 | "loose-envify": "^1.1.0" 491 | }, 492 | "engines": { 493 | "node": ">=0.10.0" 494 | } 495 | }, 496 | "node_modules/react-dom": { 497 | "version": "18.2.0", 498 | "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", 499 | "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", 500 | "dependencies": { 501 | "loose-envify": "^1.1.0", 502 | "scheduler": "^0.23.0" 503 | }, 504 | "peerDependencies": { 505 | "react": "^18.2.0" 506 | } 507 | }, 508 | "node_modules/scheduler": { 509 | "version": "0.23.0", 510 | "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", 511 | "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", 512 | "dependencies": { 513 | "loose-envify": "^1.1.0" 514 | } 515 | }, 516 | "node_modules/sift": { 517 | "version": "16.0.1", 518 | "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", 519 | "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" 520 | }, 521 | "node_modules/source-map-js": { 522 | "version": "1.0.2", 523 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", 524 | "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", 525 | "engines": { 526 | "node": ">=0.10.0" 527 | } 528 | }, 529 | "node_modules/sparse-bitfield": { 530 | "version": "3.0.3", 531 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 532 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", 533 | "dependencies": { 534 | "memory-pager": "^1.0.2" 535 | } 536 | }, 537 | "node_modules/streamsearch": { 538 | "version": "1.1.0", 539 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", 540 | "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", 541 | "engines": { 542 | "node": ">=10.0.0" 543 | } 544 | }, 545 | "node_modules/styled-jsx": { 546 | "version": "5.1.1", 547 | "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", 548 | "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", 549 | "dependencies": { 550 | "client-only": "0.0.1" 551 | }, 552 | "engines": { 553 | "node": ">= 12.0.0" 554 | }, 555 | "peerDependencies": { 556 | "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" 557 | }, 558 | "peerDependenciesMeta": { 559 | "@babel/core": { 560 | "optional": true 561 | }, 562 | "babel-plugin-macros": { 563 | "optional": true 564 | } 565 | } 566 | }, 567 | "node_modules/tr46": { 568 | "version": "4.1.1", 569 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", 570 | "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", 571 | "dependencies": { 572 | "punycode": "^2.3.0" 573 | }, 574 | "engines": { 575 | "node": ">=14" 576 | } 577 | }, 578 | "node_modules/tslib": { 579 | "version": "2.6.2", 580 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", 581 | "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" 582 | }, 583 | "node_modules/webidl-conversions": { 584 | "version": "7.0.0", 585 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 586 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 587 | "engines": { 588 | "node": ">=12" 589 | } 590 | }, 591 | "node_modules/whatwg-url": { 592 | "version": "13.0.0", 593 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", 594 | "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", 595 | "dependencies": { 596 | "tr46": "^4.1.1", 597 | "webidl-conversions": "^7.0.0" 598 | }, 599 | "engines": { 600 | "node": ">=16" 601 | } 602 | } 603 | } 604 | } 605 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "resto-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "mongoose": "^8.2.0", 13 | "next": "14.1.0", 14 | "react": "^18", 15 | "react-dom": "^18" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/DeliveryHeader.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import Link from "next/link" 3 | import { useRouter } from "next/navigation"; 4 | import { useEffect, useState } from "react"; 5 | 6 | const DeliveryHeader = (props) => { 7 | 8 | 9 | return ( 10 |
11 |
12 | 13 |
14 | 20 |
21 | ) 22 | } 23 | 24 | export default DeliveryHeader -------------------------------------------------------------------------------- /src/app/_components/AddFoodItem.js: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | const AddFoodItems = (props) => { 4 | const [name, setName] = useState(""); 5 | const [price, setPrice] = useState(""); 6 | const [path, setPath] = useState(""); 7 | const [description, setDescription] = useState(""); 8 | const [error,setError]=useState(false) 9 | 10 | const handleAddFoodItem = async () => { 11 | console.log(name, price, path, description); 12 | if(!name || !path || !price || !description){ 13 | setError(true); 14 | return false 15 | }else{ 16 | setError(false) 17 | } 18 | let resto_id; 19 | const restaurantData = JSON.parse(localStorage.getItem("restaurantUser")); 20 | if (restaurantData) { 21 | resto_id = restaurantData._id 22 | } 23 | let response = await fetch("http://localhost:3000/api/restaurant/foods", { 24 | method: "POST", 25 | body: JSON.stringify({ name, price, img_path: path, description, resto_id }) 26 | }); 27 | response = await response.json(); 28 | if (response.success) { 29 | alert("Food item added") 30 | props.setAddItem(false) 31 | }else{ 32 | alert("Food item not added") 33 | } 34 | 35 | } 36 | 37 | return (
38 |

Add New Food Item

39 |
40 | setName(e.target.value)} 42 | /> 43 | {error && !name && Please enter valid name} 44 |
45 |
46 | setPrice(e.target.value)} 48 | /> 49 | {error && !price && Please enter valid price} 50 | 51 |
52 |
53 | setPath(e.target.value)} 55 | /> 56 | {error && !path && Please enter valid path} 57 | 58 |
59 |
60 | setDescription(e.target.value)} 62 | /> 63 | {error && !description && Please enter valid description} 64 | 65 |
66 |
67 | 68 |
69 |
) 70 | } 71 | 72 | export default AddFoodItems; -------------------------------------------------------------------------------- /src/app/_components/CustomerHeader.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import Link from "next/link" 3 | import { useRouter } from "next/navigation"; 4 | import { useEffect, useState } from "react"; 5 | 6 | const CustomerHeader = (props) => { 7 | 8 | const userStorage = localStorage.getItem('user') && JSON.parse(localStorage.getItem('user')); 9 | const cartStorage = localStorage.getItem('cart') && JSON.parse(localStorage.getItem('cart')); 10 | const [user, setUser] = useState(userStorage ? userStorage : undefined) 11 | const [cartNumber, setCartNumber] = useState(cartStorage?.length) 12 | const [cartItem, setCartItem] = useState(cartStorage); 13 | const router =useRouter(); 14 | console.log(userStorage); 15 | 16 | 17 | useEffect(() => { 18 | 19 | if (props.cartData) { 20 | console.log(props); 21 | if (cartNumber) { 22 | if (cartItem[0].resto_id != props.cartData.resto_id) { 23 | localStorage.removeItem('cart'); 24 | setCartNumber(1); 25 | setCartItem([props.cartData]) 26 | localStorage.setItem('cart', JSON.stringify([props.cartData])) 27 | 28 | } else { 29 | let localCartItem = cartItem; 30 | localCartItem.push(JSON.parse(JSON.stringify(props.cartData))) 31 | setCartItem(localCartItem); 32 | setCartNumber(cartNumber + 1) 33 | localStorage.setItem('cart', JSON.stringify(localCartItem)) 34 | 35 | } 36 | 37 | } else { 38 | setCartNumber(1) 39 | setCartItem([props.cartData]) 40 | localStorage.setItem('cart', JSON.stringify([props.cartData])) 41 | 42 | } 43 | } 44 | 45 | }, [props.cartData]) 46 | 47 | useEffect(() => { 48 | if (props.removeCartData) { 49 | let localCartItem = cartItem.filter((item) => { 50 | return item._id != props.removeCartData 51 | }); 52 | setCartItem(localCartItem); 53 | setCartNumber(cartNumber - 1); 54 | localStorage.setItem('cart', JSON.stringify(localCartItem)) 55 | if (localCartItem.length == 0) { 56 | localStorage.removeItem('cart') 57 | } 58 | } 59 | }, [props.removeCartData]) 60 | 61 | useEffect(()=>{ 62 | 63 | if(props.removeCartData){ 64 | setCartItem([]) 65 | setCartNumber(0); 66 | localStorage.removeItem('cart'); 67 | } 68 | 69 | },[props.removeCartData]) 70 | 71 | const logout=()=>{ 72 | localStorage.removeItem('user'); 73 | router.push('/user-auth') 74 | 75 | } 76 | 77 | return ( 78 |
79 |
80 | 81 |
82 | 113 |
114 | ) 115 | } 116 | 117 | export default CustomerHeader -------------------------------------------------------------------------------- /src/app/_components/FoodItemList.js: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/navigation"; 2 | import { useEffect, useState } from "react"; 3 | 4 | const FoodItemList = () => { 5 | const [foodItems, setFoodItems] = useState(); 6 | const router=useRouter() 7 | 8 | useEffect(() => { 9 | loadFoodItems(); 10 | }, []); 11 | 12 | const loadFoodItems = async () => { 13 | const restaurantData= JSON.parse(localStorage.getItem('restaurantUser')); 14 | const resto_id= restaurantData._id; 15 | let response = await fetch("http://localhost:3000/api/restaurant/foods/"+resto_id); 16 | response = await response.json(); 17 | if (response.success) { 18 | setFoodItems(response.result) 19 | } else { 20 | alert("food item list not loading") 21 | } 22 | 23 | } 24 | 25 | const deleteFoodItem=async(id)=>{ 26 | let response = await fetch('http://localhost:3000/api/restaurant/foods/'+id,{ 27 | method:'delete' 28 | }); 29 | response = await response.json(); 30 | if(response.success){ 31 | loadFoodItems(); 32 | }else{ 33 | alert("food item not deleted") 34 | } 35 | } 36 | 37 | 38 | return (
39 |

Food Items

40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | { 53 | foodItems && foodItems.map((item,key)=>( 54 | 55 | 56 | 57 | 58 | 59 | 60 | 62 | 63 | 64 | )) 65 | } 66 | 67 | 68 |
S.NNamePriceDescriptionImageOperations
{key+1}{item.name}{item.price}{item.description} 61 |
69 | 70 |
) 71 | } 72 | 73 | export default FoodItemList; -------------------------------------------------------------------------------- /src/app/_components/Footer.js: -------------------------------------------------------------------------------- 1 | const Footer=()=>{ 2 | return( 3 |
4 |

All rights reserved by Resto app

5 |
6 | ) 7 | } 8 | 9 | export default Footer -------------------------------------------------------------------------------- /src/app/_components/RestaurantHeader.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import Link from 'next/link' 3 | import { usePathname,useRouter } from 'next/navigation'; 4 | 5 | import { useEffect, useState } from 'react'; 6 | const RestaurantHeader=()=>{ 7 | const [details,setDetails]=useState(); 8 | const pathName=usePathname(); 9 | const router=useRouter(); 10 | useEffect(()=>{ 11 | const data = localStorage.getItem("restaurantUser"); 12 | if(!data && pathName=="/restaurant/dashboard") 13 | { 14 | router.push("/restaurant") 15 | } 16 | else if(data && pathName=="/restaurant") 17 | { 18 | router.push("/restaurant/dashboard") 19 | } 20 | 21 | if(data){ 22 | setDetails(JSON.parse(data)); 23 | 24 | } 25 | },[]) 26 | 27 | const logout=()=>{ 28 | localStorage.removeItem("restaurantUser"); 29 | router.push("/restaurant") 30 | } 31 | return( 32 |
33 |
34 | 35 |
36 | 54 |
55 | ) 56 | } 57 | 58 | export default RestaurantHeader; -------------------------------------------------------------------------------- /src/app/_components/UserLogin.js: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/navigation"; 2 | import { useState } from "react" 3 | 4 | const UserLogin=(props)=>{ 5 | const [email,setEmail]=useState(''); 6 | const [password,setPassword]=useState(''); 7 | const router= useRouter(); 8 | 9 | console.log("login",props); 10 | 11 | const loginHandle=async()=>{ 12 | let response = await fetch('http://localhost:3000/api/user/login', { 13 | method: 'post', 14 | body: JSON.stringify({email, password}) 15 | }) 16 | response = await response.json(); 17 | if (response.success) { 18 | const {result}=response; 19 | delete result.password; 20 | localStorage.setItem('user',JSON.stringify(result)); 21 | if(props?.redirect?.order){ 22 | console.log("login if"); 23 | router.push('/order') 24 | }else{ 25 | console.log("login else"); 26 | 27 | router.push('/') 28 | } 29 | 30 | } else { 31 | alert("failed to login. Please try again with valid email and password") 32 | } 33 | } 34 | return( 35 |
36 |
37 | setEmail(event.target.value)} className="input-field" /> 38 |
39 |
40 | setPassword(event.target.value)} className="input-field" /> 41 |
42 |
43 | 44 |
45 | 46 |
47 | ) 48 | } 49 | 50 | export default UserLogin -------------------------------------------------------------------------------- /src/app/_components/UserSignUp.js: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/navigation"; 2 | import { useState } from "react" 3 | 4 | const UserSignUp = (props) => { 5 | 6 | const [name, setName] = useState(''); 7 | const [email, setEmail] = useState(''); 8 | const [password, setPassword] = useState(''); 9 | const [confirmPassword, setConfirmPassword] = useState(''); 10 | const [city, setCity] = useState(''); 11 | const [address, setAddress] = useState(''); 12 | const [mobile, setMobile] = useState(''); 13 | const router =useRouter(); 14 | 15 | const handleSignUp = async () => { 16 | console.log(name, email, password, confirmPassword, city, address, mobile); 17 | let response = await fetch('http://localhost:3000/api/user', { 18 | method: 'post', 19 | body: JSON.stringify({ name, email, password, city, address, mobile }) 20 | }) 21 | response = await response.json(); 22 | if (response.success) { 23 | const {result}=response; 24 | delete result.password; 25 | localStorage.setItem('user',JSON.stringify(result)); 26 | if(props?.redirect?.order){ 27 | router.push('/order') 28 | }else{ 29 | router.push('/') 30 | } 31 | 32 | } else { 33 | alert("failed") 34 | } 35 | } 36 | 37 | return ( 38 |
39 |
40 | setName(event.target.value)} placeholder="Enter name" /> 41 |
42 |
43 | setEmail(event.target.value)} placeholder="Enter email" /> 44 |
45 |
46 | setPassword(event.target.value)} placeholder="Enter password" /> 47 |
48 |
49 | setConfirmPassword(event.target.value)} placeholder="Confirm password" /> 50 |
51 |
52 | setCity(event.target.value)} placeholder="Enter city" /> 53 |
54 |
55 | setAddress(event.target.value)} placeholder="Enter address" /> 56 |
57 |
58 | setMobile(event.target.value)} placeholder="Enter mobile" /> 59 |
60 |
61 | 62 |
63 |
64 | ) 65 | } 66 | 67 | export default UserSignUp -------------------------------------------------------------------------------- /src/app/_components/restaurantLogin.js: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/navigation"; 2 | import { useState } from "react"; 3 | 4 | const RestaurantLogin = () => { 5 | const [email,setEmail]=useState(); 6 | const [password,setPassword]=useState(); 7 | const [error,setError]=useState(false); 8 | const router= useRouter(); 9 | 10 | const handleLogin=async ()=>{ 11 | if(!email || !password){ 12 | setError(true) 13 | return false 14 | }else{ 15 | setError(false) 16 | } 17 | let response = await fetch("http://localhost:3000/api/restaurant",{ 18 | method:'POST', 19 | body:JSON.stringify({email,password,login:true}) 20 | }); 21 | 22 | response = await response.json(); 23 | if(response.success){ 24 | const {result}=response; 25 | delete result.password; 26 | localStorage.setItem("restaurantUser",JSON.stringify(result)); 27 | router.push("/restaurant/dashboard"); 28 | }else{ 29 | alert("Login failed") 30 | } 31 | 32 | 33 | } 34 | 35 | return <> 36 |

Login

37 |
38 |
39 | setEmail(e.target.value)} 41 | /> 42 | {error && !email && Please enter valid email } 43 |
44 |
45 | setPassword(e.target.value)} 47 | /> 48 | {error && !password && Please enter valid password } 49 | 50 | 51 |
52 |
53 | 54 |
55 |
56 | 57 | } 58 | 59 | export default RestaurantLogin; -------------------------------------------------------------------------------- /src/app/_components/restaurantSignUp.js: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/navigation"; 2 | import { useState } from "react" 3 | 4 | const RestaurantSignUp=()=>{ 5 | const [email,setEmail]=useState(''); 6 | const [password,setPassword]=useState(''); 7 | const [c_password,setC_password]=useState(''); 8 | const [name,setName]=useState(''); 9 | const [city,setcity]=useState(''); 10 | const [address,setAddress]=useState(''); 11 | const [contact,setContact]=useState(''); 12 | const router= useRouter(); 13 | const [error,setError]=useState(false); 14 | const [passwordError,setPasswordError]=useState(false) 15 | 16 | const handleSignup=async ()=>{ 17 | if(password!==c_password){ 18 | setPasswordError(true); 19 | return false 20 | }else{ 21 | setPasswordError(false) 22 | } 23 | if(!email || !password || !c_password || !name || !city || !address || !contact){ 24 | setError(true) 25 | return false 26 | }else{ 27 | setError(false) 28 | } 29 | 30 | 31 | console.log(email,password,c_password,name,city,address,contact); 32 | let response = await fetch("http://localhost:3000/api/restaurant",{ 33 | method:"POST", 34 | body:JSON.stringify({email,password,name,city,address,contact}) 35 | }) 36 | response = await response.json(); 37 | console.log(response); 38 | if(response.success){ 39 | const {result} =response; 40 | delete result.password; 41 | localStorage.setItem("restaurantUser", JSON.stringify(result)) 42 | router.push("/restaurant/dashboard") 43 | } 44 | } 45 | 46 | return( 47 | <> 48 |

Signup

49 |
50 |
51 | setEmail(event.target.value)} 53 | /> 54 | { 55 | error && !email && Please enter valid email 56 | } 57 |
58 |
59 | setPassword(event.target.value)} 61 | /> 62 | { 63 | passwordError && Password and Confirm password not match 64 | } 65 | { 66 | error && !password && Please enter valid password 67 | } 68 |
69 | 70 |
71 | setC_password(event.target.value)} /> 73 | { 74 | passwordError && Password and Confirm password not match 75 | } 76 | { 77 | error && !c_password && Please enter valid confirm password 78 | } 79 |
80 | 81 |
82 | setName(event.target.value)} 84 | /> 85 | { 86 | error && !name && Please enter name email 87 | } 88 |
89 |
90 | setcity(event.target.value)} /> 92 | { 93 | error && !city && Please enter valid city 94 | } 95 |
96 |
97 | setAddress(event.target.value)}/> 99 | { 100 | error && !address && Please enter valid address 101 | } 102 |
103 |
104 | setContact(event.target.value)}/> 106 | { 107 | error && !contact && Please enter valid contact 108 | } 109 |
110 | 111 |
112 | 113 |
114 |
115 | 116 | ) 117 | } 118 | 119 | export default RestaurantSignUp -------------------------------------------------------------------------------- /src/app/api/customer/[id]/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { foodSchema } from "@/app/lib/foodsModel"; 3 | import { restaurantSchema } from "@/app/lib/restaurantsModel"; 4 | import mongoose from "mongoose"; 5 | import { NextResponse } from "next/server"; 6 | 7 | export async function GET(request,content){ 8 | 9 | const id = content.params.id; 10 | console.log(id); 11 | 12 | await mongoose.connect(connectionStr,{useNewUrlParser:true}) 13 | const details=await restaurantSchema.findOne({_id:id}) 14 | const foodItems=await foodSchema.find({resto_id:id}) 15 | 16 | 17 | return NextResponse.json({success:true,details,foodItems}) 18 | 19 | } -------------------------------------------------------------------------------- /src/app/api/customer/locations/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { restaurantSchema } from "@/app/lib/restaurantsModel"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server"; 5 | 6 | 7 | export async function GET(){ 8 | await mongoose.connect(connectionStr,{useNewUrlParser:true}) 9 | let result = await restaurantSchema.find(); 10 | result = result.map((item)=>item?.city?.charAt(0).toUpperCase()+ item?.city?.slice(1)); 11 | 12 | result = [...new Set(result.map((item)=>item))] 13 | 14 | return NextResponse.json({success:true,result}) 15 | } -------------------------------------------------------------------------------- /src/app/api/customer/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { restaurantSchema } from "@/app/lib/restaurantsModel"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server"; 5 | 6 | 7 | export async function GET(request){ 8 | let queryParams= request.nextUrl.searchParams; 9 | console.log(queryParams.get("location")); 10 | let filter={}; 11 | if(queryParams.get("location")){ 12 | let city =queryParams.get("location"); 13 | filter={city:{$regex: new RegExp(city,'i')}} 14 | }else if(queryParams.get("restaurant")){ 15 | let name =queryParams.get("restaurant"); 16 | filter={name:{$regex: new RegExp(name,'i')}} 17 | } 18 | await mongoose.connect(connectionStr,{useNewUrlParser:true}) 19 | let result = await restaurantSchema.find(filter); 20 | return NextResponse.json({success:true,result}) 21 | } -------------------------------------------------------------------------------- /src/app/api/deliverypartners/[city]/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { deliveryPartnersSchema } from "@/app/lib/deliverypartnersMode"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server" 5 | 6 | export async function GET(request,content){ 7 | let city= content.params.city 8 | let success=false; 9 | await mongoose.connect(connectionStr,{useNewUrlParser:true}); 10 | let filter ={city:{$regex:new RegExp(city,'i')}} 11 | const result = await deliveryPartnersSchema.find(filter) 12 | return NextResponse.json({result}) 13 | } -------------------------------------------------------------------------------- /src/app/api/deliverypartners/login/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { deliveryPartnersSchema } from "@/app/lib/deliverypartnersMode"; 3 | 4 | import mongoose from "mongoose"; 5 | import { NextResponse } from "next/server"; 6 | 7 | export async function POST(request) { 8 | const payload = await request.json(); 9 | let success = false; 10 | await mongoose.connect(connectionStr, { useNewUrlParser:true }); 11 | const result = await deliveryPartnersSchema.findOne({ mobile: payload.mobile, password: payload.password }); 12 | if (result) { 13 | success = true; 14 | } 15 | return NextResponse.json({ result, success }) 16 | } -------------------------------------------------------------------------------- /src/app/api/deliverypartners/orders/[id]/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { orderSchema } from "@/app/lib/ordersMode"; 3 | import { restaurantSchema } from "@/app/lib/restaurantsModel"; 4 | import mongoose from "mongoose"; 5 | import { NextResponse } from "next/server"; 6 | 7 | 8 | 9 | export async function GET(request,content) { 10 | const id = content.params.id 11 | let success = false 12 | await mongoose.connect(connectionStr, { useNewUrlParser: true }) 13 | let result = await orderSchema.find({ deliveryBoy_id: id }); 14 | if (result) { 15 | let restoData = await Promise.all( 16 | result.map(async (item) => { 17 | let restoInfo = {}; 18 | restoInfo.data = await restaurantSchema.findOne({ _id: item.resto_id }) 19 | restoInfo.amount = item.amount; 20 | restoInfo.status = item.status; 21 | return restoInfo; 22 | }) 23 | ) 24 | result = restoData; 25 | success = true 26 | } 27 | 28 | return NextResponse.json({ result,success }) 29 | 30 | } -------------------------------------------------------------------------------- /src/app/api/deliverypartners/signup/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { deliveryPartnersSchema } from "@/app/lib/deliverypartnersMode"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server"; 5 | 6 | 7 | export async function POST(request) { 8 | const payload = await request.json(); 9 | let success = false; 10 | await mongoose.connect(connectionStr,{useNewUrlParser:true}); 11 | const user= new deliveryPartnersSchema(payload); 12 | const result = await user.save() 13 | if(result){ 14 | success=true 15 | } 16 | 17 | 18 | return NextResponse.json({result,success}) 19 | 20 | } -------------------------------------------------------------------------------- /src/app/api/order/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { orderSchema } from "@/app/lib/ordersMode"; 3 | import { restaurantSchema } from "@/app/lib/restaurantsModel"; 4 | import mongoose from "mongoose"; 5 | import { NextResponse } from "next/server"; 6 | 7 | 8 | export async function POST(request) { 9 | const payload = await request.json(); 10 | await mongoose.connect(connectionStr, { useNewUrlParser: true }); 11 | let success = false; 12 | const orderObj = new orderSchema(payload); 13 | const result = await orderObj.save(); 14 | if (result) { 15 | success = true 16 | } 17 | return NextResponse.json({ result, success }) 18 | } 19 | 20 | export async function GET(request) { 21 | const userId = request.nextUrl.searchParams.get('id'); 22 | let success = false 23 | await mongoose.connect(connectionStr, { useNewUrlParser: true }) 24 | let result = await orderSchema.find({ user_id: userId }); 25 | if (result) { 26 | let restoData = await Promise.all( 27 | result.map(async (item) => { 28 | let restoInfo = {}; 29 | restoInfo.data = await restaurantSchema.findOne({ _id: item.resto_id }) 30 | restoInfo.amount = item.amount; 31 | restoInfo.status = item.status; 32 | return restoInfo; 33 | }) 34 | ) 35 | result = restoData; 36 | success = true 37 | } 38 | 39 | return NextResponse.json({ result,success }) 40 | 41 | } -------------------------------------------------------------------------------- /src/app/api/restaurant/foods/[id]/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { foodSchema } from "@/app/lib/foodsModel"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server"; 5 | 6 | export async function GET(request,content){ 7 | const id = content.params.id 8 | let success=false; 9 | await mongoose.connect(connectionStr,{useNewUrlParser:true}); 10 | const result = await foodSchema.find({resto_id:id}); 11 | if(result){ 12 | success=true 13 | } 14 | return NextResponse.json({result,success}) 15 | 16 | } 17 | export async function DELETE(request,content){ 18 | const id = content.params.id; 19 | let success = false; 20 | await mongoose.connect(connectionStr,{useNewUrlParser:true}); 21 | const result = await foodSchema.deleteOne({_id:id}) 22 | if(result.deletedCount>0){ 23 | success=true 24 | } 25 | 26 | return NextResponse.json({result,success}) 27 | } 28 | -------------------------------------------------------------------------------- /src/app/api/restaurant/foods/edit/[id]/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { foodSchema } from "@/app/lib/foodsModel"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server"; 5 | 6 | 7 | export async function GET(request,content){ 8 | const id = content.params.id; 9 | let success=false; 10 | await mongoose.connect(connectionStr,{useNewUrlParser:true}); 11 | const result = await foodSchema.findOne({_id:id}) 12 | if(result){ 13 | success=true 14 | } 15 | return NextResponse.json({result,success}) 16 | } 17 | 18 | export async function PUT(request,content){ 19 | const id = content.params.id; 20 | const payload = await request.json(); 21 | let success=false; 22 | await mongoose.connect(connectionStr,{useNewUrlParser:true}); 23 | const result = await foodSchema.findOneAndUpdate({_id:id},payload); 24 | if(result){ 25 | success=true 26 | }; 27 | return NextResponse.json({result,success}) 28 | 29 | } -------------------------------------------------------------------------------- /src/app/api/restaurant/foods/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { foodSchema } from "@/app/lib/foodsModel"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server"; 5 | 6 | export async function POST(request) { 7 | const payload = await request.json(); 8 | let success=false; 9 | await mongoose.connect(connectionStr, { useNewUrlParser: true }); 10 | const food = new foodSchema(payload); 11 | const result = await food.save(); 12 | if(result){ 13 | success=true 14 | } 15 | return NextResponse.json({ result, success }) 16 | } -------------------------------------------------------------------------------- /src/app/api/restaurant/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { restaurantSchema } from "@/app/lib/restaurantsModel"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server"; 5 | 6 | export async function GET() { 7 | await mongoose.connect(connectionStr, { useNewUrlParser: true }); 8 | const data = await restaurantSchema.find() 9 | console.log(data); 10 | 11 | return NextResponse.json({ result: data }) 12 | } 13 | 14 | export async function POST(request) { 15 | let payload = await request.json(); 16 | let result; 17 | let success=false 18 | await mongoose.connect(connectionStr, { useNewUrlParser: true }) 19 | 20 | if (payload.login) { 21 | result = await restaurantSchema.findOne({ email: payload.email, password: payload.password }) 22 | if(result){ 23 | success=true 24 | } 25 | } else { 26 | const restaurant = new restaurantSchema(payload) 27 | result = await restaurant.save(); 28 | if(result){ 29 | success=true; 30 | } 31 | } 32 | 33 | return NextResponse.json({ result, success }) 34 | } -------------------------------------------------------------------------------- /src/app/api/user/login/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { userSchema } from "@/app/lib/userModel"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server"; 5 | 6 | export async function POST(request) { 7 | const payload = await request.json(); 8 | let success = false; 9 | await mongoose.connect(connectionStr, { useNewUrlParser:true }); 10 | const result = await userSchema.findOne({ email: payload.email, password: payload.password }); 11 | if (result) { 12 | success = true; 13 | } 14 | return NextResponse.json({ result, success }) 15 | } -------------------------------------------------------------------------------- /src/app/api/user/route.js: -------------------------------------------------------------------------------- 1 | import { connectionStr } from "@/app/lib/db"; 2 | import { userSchema } from "@/app/lib/userModel"; 3 | import mongoose from "mongoose"; 4 | import { NextResponse } from "next/server"; 5 | 6 | 7 | export async function POST(request) { 8 | const payload = await request.json(); 9 | let success = false; 10 | await mongoose.connect(connectionStr,{useNewUrlParser:true}); 11 | const user= new userSchema(payload); 12 | const result = await user.save() 13 | if(result){ 14 | success=true 15 | } 16 | 17 | 18 | return NextResponse.json({result,success}) 19 | 20 | } -------------------------------------------------------------------------------- /src/app/cart/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { useState } from "react" 3 | import CustomerHeader from "../_components/CustomerHeader" 4 | import Footer from "../_components/Footer" 5 | import { DELIVERY_CHARGES, TAX } from "../lib/constant" 6 | import { useRouter } from "next/navigation" 7 | 8 | 9 | 10 | const Page = () => { 11 | 12 | const [cartStorage, setCartStorage] = useState(JSON.parse(localStorage.getItem('cart'))) 13 | const [total]=useState(()=>cartStorage.length==1?cartStorage[0].price:cartStorage.reduce((a,b)=>{ 14 | return a.price+b.price 15 | })) 16 | const router = useRouter() 17 | console.log(total); 18 | 19 | const orderNow=()=>{ 20 | if(JSON.parse(localStorage.getItem('user'))){ 21 | router.push('/order') 22 | }else{ 23 | router.push('/user-auth?order=true') 24 | } 25 | 26 | } 27 | return ( 28 |
29 | 30 |
31 | { 32 | cartStorage.length > 0 ? cartStorage.map((item) => ( 33 |
34 |
35 |
36 |
{item.name}
37 | 38 |
{item.description}
39 | { 40 | 41 | 42 | 43 | } 44 | 45 |
46 |
Price: {item.price}
47 | 48 |
49 | )) 50 | :

No Food Items for this Restaurant

51 | } 52 |
53 |
54 |
55 |
56 | Food Charges : 57 | {total} 58 |
59 |
60 | Tax : 61 | {total*TAX/100} 62 |
63 |
64 | Delivery Charges : 65 | {DELIVERY_CHARGES} 66 |
67 |
68 | Total Amount : 69 | {total+DELIVERY_CHARGES+(total*TAX/100)} 70 |
71 | 72 |
73 |
74 | 75 |
76 |
77 |
79 | ) 80 | } 81 | 82 | export default Page -------------------------------------------------------------------------------- /src/app/deliverydashboard/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { useEffect, useState } from "react"; 3 | import DeliveryHeader from "../DeliveryHeader"; 4 | import { useRouter } from "next/navigation"; 5 | 6 | const Page = () => { 7 | 8 | const router = useRouter() 9 | 10 | 11 | const [myOrders,setMyOrders]=useState([]); 12 | useEffect(()=>{ 13 | getMyOrders() 14 | },[]) 15 | 16 | const getMyOrders=async()=>{ 17 | const deliveryData= JSON.parse(localStorage.getItem('delivery')); 18 | let response = await fetch('http://localhost:3000/api/deliverypartners/orders/'+deliveryData._id) 19 | response = await response.json(); 20 | if(response.success){ 21 | setMyOrders(response.result) 22 | } 23 | } 24 | 25 | 26 | useEffect(() => { 27 | const delivery = JSON.parse(localStorage.getItem('delivery')); 28 | if (!delivery) { 29 | router.push('/deliverypartner') 30 | } 31 | }, []) 32 | return ( 33 |
34 | 35 |

My Order List

36 | { 37 | myOrders.map((item)=>(
39 |

Name : {item.data.name}

40 |
Amount:{item.amount}
41 |
Address:{item.data.address}
42 |
Status:{item.status}
43 |
Update Status: 44 | 50 |
51 | 52 | 53 |
)) 54 | } 55 |
56 | ) 57 | } 58 | 59 | export default Page; -------------------------------------------------------------------------------- /src/app/deliverypartner/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { useEffect, useState } from "react"; 3 | import DeliveryHeader from "../DeliveryHeader"; 4 | import { useRouter } from "next/navigation"; 5 | 6 | const Page = () => { 7 | const [loginMobile, setLoginMobile] = useState(''); 8 | const [loginPassword, setLoginPassword] = useState(''); 9 | 10 | const [name, setName] = useState(''); 11 | const [password, setPassword] = useState(''); 12 | const [confirmPassword, setConfirmPassword] = useState(''); 13 | const [city, setCity] = useState(''); 14 | const [address, setAddress] = useState(''); 15 | const [mobile, setMobile] = useState(''); 16 | const router = useRouter(); 17 | 18 | 19 | useEffect(()=>{ 20 | const delivery= JSON.parse(localStorage.getItem('delivery')); 21 | if(delivery){ 22 | router.push('/deliverydashboard') 23 | } 24 | },[]) 25 | 26 | 27 | const handleSignUp = async () => { 28 | console.log(name, mobile, password, confirmPassword, city, address); 29 | let response = await fetch('http://localhost:3000/api/deliverypartners/signup', { 30 | method: 'post', 31 | body: JSON.stringify({ name, mobile, password, city, address }) 32 | }) 33 | response = await response.json(); 34 | if (response.success) { 35 | const { result } = response; 36 | delete result.password; 37 | localStorage.setItem('delivery', JSON.stringify(result)); 38 | router.push('deliverydashboard') 39 | 40 | } else { 41 | alert("failed") 42 | } 43 | } 44 | 45 | const loginHandle = async () => { 46 | let response = await fetch('http://localhost:3000/api/deliverypartners/login', { 47 | method: 'post', 48 | body: JSON.stringify({ mobile: loginMobile, password: loginPassword }) 49 | }) 50 | response = await response.json(); 51 | if (response.success) { 52 | const { result } = response; 53 | delete result.password; 54 | localStorage.setItem('delivery', JSON.stringify(result)); 55 | router.push('deliverydashboard') 56 | 57 | } else { 58 | alert("failed to login. Please try again with valid mobile and password") 59 | } 60 | } 61 | 62 | return ( 63 |
64 | 65 |

Delivery Partner

66 |
67 | 68 |
69 |

Login

70 |
71 | setLoginMobile(event.target.value)} className="input-field" /> 72 |
73 |
74 | setLoginPassword(event.target.value)} className="input-field" /> 75 |
76 |
77 | 78 |
79 | 80 |
81 |
82 |

Signup

83 |
84 | setName(event.target.value)} placeholder="Enter name" /> 85 |
86 |
87 | setMobile(event.target.value)} placeholder="Enter mobile" /> 88 |
89 | 90 |
91 | setPassword(event.target.value)} placeholder="Enter password" /> 92 |
93 |
94 | setConfirmPassword(event.target.value)} placeholder="Confirm password" /> 95 |
96 |
97 | setCity(event.target.value)} placeholder="Enter city" /> 98 |
99 |
100 | setAddress(event.target.value)} placeholder="Enter address" /> 101 |
102 | 103 |
104 | 105 |
106 |
107 |
108 |
109 | ) 110 | } 111 | 112 | export default Page; -------------------------------------------------------------------------------- /src/app/explore/[name]/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import CustomerHeader from "@/app/_components/CustomerHeader" 3 | import { useEffect, useState } from "react" 4 | 5 | const Page = (props) => { 6 | const name = props.params.name; 7 | const [restaurantDetails, setRestaurantDetails] = useState(); 8 | const [foodItems, setFoodItems] = useState([]) 9 | const [cartData, setCartData] = useState(); 10 | const [cartStorage, setCartStorage] = useState(JSON.parse(localStorage.getItem('cart'))); 11 | const [cartIds, setCartIds] = useState(cartStorage?() => cartStorage.map((cartItem) => { 12 | return cartItem._id 13 | }):[]) 14 | const [removeCartData,setRemoveCartData]=useState() 15 | 16 | console.log(cartIds); 17 | 18 | useEffect(() => { 19 | loadRestaurantDetails() 20 | }, []); 21 | 22 | const loadRestaurantDetails = async () => { 23 | const id = props.searchParams.id; 24 | let response = await fetch("http://localhost:3000/api/customer/" + id) 25 | response = await response.json(); 26 | if (response.success) { 27 | setRestaurantDetails(response.details) 28 | setFoodItems(response.foodItems) 29 | } 30 | 31 | } 32 | const addToCart = (item) => { 33 | let localCartIds=cartIds; 34 | localCartIds.push(item._id); 35 | setCartIds(localCartIds) 36 | setCartData(item) 37 | setRemoveCartData(); 38 | 39 | } 40 | 41 | const removeFromCart=(id)=>{ 42 | setRemoveCartData(id); 43 | var localIds=cartIds.filter(item=>item!=id); 44 | setCartData() 45 | setCartIds(localIds) 46 | } 47 | return ( 48 |
49 | 50 |
51 |

{decodeURI(name)}

52 |
53 |
54 |

Contact : {restaurantDetails?.contact}

55 |

City:{restaurantDetails?.city}

56 |

Address:{restaurantDetails?.address}

57 |

Email:{restaurantDetails?.email}

58 |
59 |
60 | { 61 | foodItems.length > 0 ? foodItems.map((item) => ( 62 |
63 |
64 | 65 |
66 |
{item.name}
67 |
{item.price}
68 |
{item.description}
69 | { 70 | cartIds.includes(item._id) ? 71 | 72 | : 73 | 74 | } 75 | 76 |
77 | 78 |
79 | )) 80 | :

No Food Items for this Restaurant

81 | } 82 |
83 |
84 | ) 85 | } 86 | 87 | export default Page -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anil-sidhu/next-js-project/7192e37a002965a9adbe018a73d13de2eb89d66b/src/app/favicon.ico -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | body{ 2 | padding: 0; 3 | margin: 0; 4 | } 5 | *:focus{ 6 | outline: none; 7 | } 8 | .header-wrapper{ 9 | display: flex; 10 | justify-content: space-between; 11 | } 12 | .header-wrapper ul { 13 | display: flex; 14 | } 15 | 16 | .header-wrapper ul li { 17 | list-style-type: none; 18 | padding: 5px; 19 | 20 | } 21 | .header-wrapper ul li a{ 22 | text-decoration: none; 23 | } 24 | 25 | .header-wrapper ul li button{ 26 | border: none; 27 | background-color: transparent; 28 | cursor: pointer; 29 | color: blueviolet; 30 | font-size: 16px; 31 | } 32 | 33 | .footer-wrapper{ 34 | position: fixed; 35 | bottom: 0; 36 | width: 100%; 37 | text-align: center; 38 | font-size: 10px; 39 | background-color: #fff; 40 | } 41 | 42 | 43 | .input-wrapper{ 44 | margin: 10px; 45 | } 46 | .input-field{ 47 | width: 200px; 48 | height: 30px; 49 | } 50 | .button{ 51 | width: 200px; 52 | height: 30px; 53 | } 54 | .container{ 55 | text-align: center; 56 | } 57 | .button-link{ 58 | border: 0; 59 | cursor: pointer; 60 | background-color: transparent; 61 | color: skyblue; 62 | margin: 20px; 63 | } 64 | .input-error{ 65 | position: absolute; 66 | padding: 8px; 67 | color: red; 68 | font-size: 13px; 69 | } 70 | table, th, td{ 71 | border: 1px solid #000 ; 72 | border-collapse: collapse; 73 | padding: 10px; 74 | } 75 | table td button{ 76 | margin: 5px; 77 | } 78 | table img { 79 | width: 80px; 80 | } 81 | 82 | .main-page-banner,.restaurant-page-banner{ 83 | background-image: url('https://a.storyblok.com/f/88809/1150x450/30a9c4f9a6/igevia_header_fastfood01_450.jpg'); 84 | height: 230px; 85 | text-align: center; 86 | padding: 30px; 87 | background-color: rgba(0, 0, 0, 0.7); 88 | background-blend-mode: multiply; 89 | color: #fff; 90 | } 91 | 92 | .main-page-banner .input-wrapper{ 93 | background-color: #fff; 94 | padding: 5px; 95 | border: 1px solid #ccc; 96 | border-radius: 5px; 97 | width: 60%; 98 | margin: auto; 99 | } 100 | 101 | .main-page-banner .select-input{ 102 | height: 40px; 103 | border: none; 104 | padding-left: 15px; 105 | width: 25%; 106 | } 107 | .main-page-banner .search-input{ 108 | height: 40px; 109 | border: none; 110 | padding-left: 15px; 111 | border-left: 1px solid #ccc; 112 | width: 45%; 113 | } 114 | 115 | .location-list { 116 | color: #000; 117 | list-style-type: none; 118 | text-align: left; 119 | position: absolute; 120 | background-color: #fff; 121 | padding: 0; 122 | margin: 0; 123 | margin-left: -5px; 124 | border: 1px solid #ccc; 125 | } 126 | .location-list li { 127 | width: 180px; 128 | padding: 5px; 129 | border-bottom: 1px solid #ccc; 130 | cursor: pointer; 131 | } 132 | .restaurant-list-container { 133 | display: flex; 134 | flex-direction: row; 135 | flex-wrap: wrap; 136 | margin-top: 40px; 137 | margin-bottom: 50px; 138 | } 139 | .restaurant-wrapper { 140 | width: 45%; 141 | background-color: orange; 142 | margin: 10px; 143 | padding: 10px; 144 | border: 1px solid #aaa; 145 | border-radius: 5px; 146 | cursor: pointer; 147 | } 148 | .restaurant-wrapper .heading-wrapper , .restaurant-wrapper .address-wrapper{ 149 | padding-left: 15px; 150 | display: flex; 151 | justify-content: flex-start; 152 | } 153 | .restaurant-wrapper h5{ 154 | margin-left: 15px; 155 | } 156 | .restaurant-wrapper .address{ 157 | margin-left: 5px; 158 | } 159 | .restaurant-page-banner h1{ 160 | font-size: 65px; 161 | } 162 | .details-wrapper { 163 | display: flex; 164 | background-color: orange; 165 | } 166 | .details-wrapper h4{ 167 | width: 50%; 168 | } 169 | 170 | .food-list-wrapper{ 171 | margin-bottom: 50px; 172 | margin-top: 50px; 173 | } 174 | 175 | .food-list-wrapper .list-item { 176 | color: orange; 177 | font-weight: bold; 178 | border-bottom: 1px solid; 179 | padding: 20px; 180 | display: flex; 181 | text-transform: capitalize; 182 | } 183 | .food-list-wrapper .list-item .description{ 184 | font-weight: lighter; 185 | } 186 | .food-list-wrapper .list-item button { 187 | color: #fff; 188 | background-color: orange; 189 | border: 0; 190 | padding: 10px; 191 | cursor: pointer; 192 | margin-top: 5px; 193 | border-radius: 5px; 194 | } 195 | .food-list-wrapper .list-item img{ 196 | width: 100px; 197 | padding-right: 20px; 198 | } 199 | 200 | .list-item-block-1{ 201 | width: 20%; 202 | } 203 | .list-item-block-2{ 204 | width: 60%; 205 | } 206 | .list-item-block-3{ 207 | width: 20%; 208 | } 209 | .total-wrapper { 210 | display: flex; 211 | flex-wrap: wrap; 212 | border-bottom: 1px solid orange; 213 | padding-bottom: 20px; 214 | } 215 | 216 | .total-wrapper .row{ 217 | display: flex; 218 | justify-content: space-between; 219 | margin-left: 20%; 220 | margin-right: 20%; 221 | color: orange; 222 | font-size: 20px; 223 | font-weight: bold; 224 | } 225 | .total-wrapper .block-1{ 226 | width: 70%; 227 | } 228 | .total-wrapper .block-2{ 229 | width: 30%; 230 | } 231 | 232 | .total-wrapper .block-2 button{ 233 | padding: 10px 25px; 234 | border: navajowhite; 235 | background-color: orange; 236 | color: #fff; 237 | border-radius: 4px; 238 | cursor: pointer; 239 | } 240 | 241 | 242 | .auth-container{ 243 | display: flex; 244 | } 245 | 246 | .login-wrapper,.signup-wrapper{ 247 | height: 400px; 248 | border: 1px solid #ccc; 249 | margin: 50px; 250 | padding: 20px; 251 | width: 50%; 252 | text-align: center; 253 | } -------------------------------------------------------------------------------- /src/app/layout.js: -------------------------------------------------------------------------------- 1 | import { Inter } from "next/font/google"; 2 | import "./globals.css"; 3 | 4 | const inter = Inter({ subsets: ["latin"] }); 5 | 6 | export const metadata = { 7 | title: "Create Next App", 8 | description: "Generated by create next app", 9 | }; 10 | 11 | export default function RootLayout({ children }) { 12 | return ( 13 | 14 | {children} 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/app/lib/constant.js: -------------------------------------------------------------------------------- 1 | export const TAX=10; 2 | export const DELIVERY_CHARGES=100; -------------------------------------------------------------------------------- /src/app/lib/db.js: -------------------------------------------------------------------------------- 1 | const {username,password} = process.env 2 | export const connectionStr="mongodb+srv://"+username+":"+password+"@cluster0.bqag9b5.mongodb.net/restoDB?retryWrites=true&w=majority&appName=Cluster0" -------------------------------------------------------------------------------- /src/app/lib/deliverypartnersMode.js: -------------------------------------------------------------------------------- 1 | const { default: mongoose } = require("mongoose"); 2 | 3 | 4 | const deliveryPartnersModel= new mongoose.Schema({ 5 | name:String, 6 | mobile:String, 7 | password:String, 8 | city:String, 9 | address:String, 10 | }) 11 | 12 | export const deliveryPartnersSchema= mongoose.models.deliverypartners || mongoose.model('deliverypartners',deliveryPartnersModel); -------------------------------------------------------------------------------- /src/app/lib/foodsModel.js: -------------------------------------------------------------------------------- 1 | const { default: mongoose } = require("mongoose"); 2 | 3 | 4 | 5 | const foodModel = new mongoose.Schema({ 6 | name:String, 7 | price:Number, 8 | img_path:String, 9 | description:String, 10 | resto_id:mongoose.Schema.Types.ObjectId 11 | }); 12 | 13 | export const foodSchema= mongoose.models.foods || mongoose.model("foods",foodModel); -------------------------------------------------------------------------------- /src/app/lib/ordersMode.js: -------------------------------------------------------------------------------- 1 | const { default: mongoose } = require("mongoose"); 2 | 3 | 4 | const orderModel= new mongoose.Schema({ 5 | user_id:mongoose.Schema.Types.ObjectId, 6 | foodItemIds:String, 7 | resto_id:mongoose.Schema.Types.ObjectId, 8 | deliveryBoy_id:mongoose.Schema.Types.ObjectId, 9 | status:String, 10 | amount:String, 11 | 12 | }) 13 | 14 | export const orderSchema= mongoose.models.orders || mongoose.model('orders',orderModel); -------------------------------------------------------------------------------- /src/app/lib/restaurantsModel.js: -------------------------------------------------------------------------------- 1 | const { default: mongoose } = require("mongoose"); 2 | 3 | 4 | const restaurantModel= new mongoose.Schema({ 5 | name:String, 6 | email:String, 7 | password:String, 8 | city:String, 9 | address:String, 10 | contact:String, 11 | }); 12 | 13 | export const restaurantSchema= mongoose.models.restaurants 14 | || mongoose.model("restaurants",restaurantModel); -------------------------------------------------------------------------------- /src/app/lib/userModel.js: -------------------------------------------------------------------------------- 1 | const { default: mongoose } = require("mongoose"); 2 | 3 | 4 | const userModel= new mongoose.Schema({ 5 | name:String, 6 | email:String, 7 | password:String, 8 | city:String, 9 | address:String, 10 | mobile:String 11 | }) 12 | 13 | export const userSchema= mongoose.models.users || mongoose.model('users',userModel); -------------------------------------------------------------------------------- /src/app/myprofile/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { useEffect, useState } from "react"; 3 | import CustomerHeader from "../_components/CustomerHeader"; 4 | import Footer from "../_components/Footer"; 5 | 6 | const Page = ()=>{ 7 | 8 | const [myOrders,setMyOrders]=useState([]); 9 | useEffect(()=>{ 10 | getMyOrders() 11 | },[]) 12 | 13 | const getMyOrders=async()=>{ 14 | const userStorage= JSON.parse(localStorage.getItem('user')); 15 | let response = await fetch('http://localhost:3000/api/order?id='+userStorage._id) 16 | response = await response.json(); 17 | if(response.success){ 18 | setMyOrders(response.result) 19 | } 20 | } 21 | 22 | return( 23 |
24 | 25 | { 26 | myOrders.map((item)=>(
28 |

Name {item.data.name}

29 |
Amount:{item.amount}
30 |
Address:{item.data.address}
31 |
Status:{item.status}
32 | 33 | 34 |
)) 35 | } 36 |
38 | ) 39 | } 40 | 41 | export default Page; -------------------------------------------------------------------------------- /src/app/order/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { useEffect, useState } from "react" 3 | import CustomerHeader from "../_components/CustomerHeader" 4 | import Footer from "../_components/Footer" 5 | import { DELIVERY_CHARGES, TAX } from "../lib/constant" 6 | import { useRouter } from "next/navigation" 7 | 8 | 9 | 10 | const Page = () => { 11 | 12 | const [userStorage, setUserStorage] = useState(JSON.parse(localStorage.getItem('user'))); 13 | const [cartStorage, setCartStorage] = useState(JSON.parse(localStorage.getItem('cart'))) 14 | const [total] = useState(() => cartStorage?.length == 1 ? cartStorage[0].price : cartStorage?.reduce((a, b) => { 15 | return a.price + b.price 16 | })) 17 | 18 | const [removeCartData, setRemoveCartData] = useState(false) 19 | const router = useRouter() 20 | 21 | 22 | useEffect(() => { 23 | if (!total) { 24 | router.push('/') 25 | } 26 | }, [total]) 27 | 28 | const orderNow = async () => { 29 | let user_id = JSON.parse(localStorage.getItem('user'))._id; 30 | let city = JSON.parse(localStorage.getItem('user')).city; 31 | 32 | let cart = JSON.parse(localStorage.getItem('cart')); 33 | let foodItemIds = cart.map((item) => item._id).toString(); 34 | let deliveryBoyResponse = await fetch('http://localhost:3000/api/deliverypartners/' + city); 35 | deliveryBoyResponse = await deliveryBoyResponse.json(); 36 | let deliveryBoyIds = deliveryBoyResponse.result.map((item) => item._id); 37 | 38 | let deliveryBoy_id = deliveryBoyIds[Math.floor(Math.random() * deliveryBoyIds.length)] 39 | console.log(deliveryBoy_id); 40 | if (!deliveryBoy_id) { 41 | alert("delivery partner not available ") 42 | return false; 43 | } 44 | 45 | 46 | 47 | let resto_id = cart[0].resto_id; 48 | let collection = { 49 | user_id, 50 | resto_id, 51 | foodItemIds, 52 | deliveryBoy_id, 53 | status: 'confirm', 54 | amount: total + DELIVERY_CHARGES + (total * TAX / 100), 55 | } 56 | 57 | let response = await fetch('http://localhost:3000/api/order', { 58 | method: 'POST', 59 | body: JSON.stringify(collection) 60 | }); 61 | response = await response.json(); 62 | if (response.success) { 63 | alert("order confirmed") 64 | setRemoveCartData(true) 65 | router.push('myprofile') 66 | 67 | } else { 68 | alert("order failed") 69 | } 70 | console.log(collection); 71 | } 72 | return ( 73 |
74 | 75 |
76 |
77 |

User Details

78 |
79 | Name 80 | {userStorage.name} 81 |
82 |
83 | address 84 | {userStorage.address} 85 |
86 |
87 | Mobile 88 | {userStorage.mobile} 89 |
90 |

Amount Details

91 |
92 | Tax : 93 | {total * TAX / 100} 94 |
95 |
96 | Delivery Charges : 97 | {DELIVERY_CHARGES} 98 |
99 |
100 | Total Amount : 101 | {total + DELIVERY_CHARGES + (total * TAX / 100)} 102 |
103 |

Payment Methods

104 |
105 | Cash on Delivery : 106 | {total + DELIVERY_CHARGES + (total * TAX / 100)} 107 |
108 | 109 |
110 |
111 | 112 |
113 |
114 |
116 | ) 117 | } 118 | 119 | export default Page -------------------------------------------------------------------------------- /src/app/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import Image from "next/image"; 3 | import styles from "./page.module.css"; 4 | import CustomerHeader from "./_components/CustomerHeader"; 5 | import Footer from "./_components/Footer"; 6 | import { useEffect, useState } from "react"; 7 | import { useRouter } from "next/navigation"; 8 | 9 | export default function Home() { 10 | const [locations, setLocations] = useState([]); 11 | const [restaurants, setRestaurants] = useState([]); 12 | const [selectedLocation, setSelectedLocation] = useState(''); 13 | const [showLocation, setShowLocation] = useState(false); 14 | const router=useRouter(); 15 | 16 | useEffect(() => { 17 | loadLocations(); 18 | loadRestaurants() 19 | }, []) 20 | 21 | const loadLocations = async () => { 22 | let response = await fetch('http://localhost:3000/api/customer/locations'); 23 | response = await response.json() 24 | if (response.success) { 25 | setLocations(response.result) 26 | } 27 | } 28 | 29 | const loadRestaurants = async (params) => { 30 | let url="http://localhost:3000/api/customer"; 31 | if(params?.location){ 32 | url=url+"?location="+params.location 33 | }else if(params?.restaurant){ 34 | url=url+"?restaurant="+params.restaurant 35 | } 36 | let response = await fetch(url); 37 | response = await response.json() 38 | if (response.success) { 39 | setRestaurants(response.result) 40 | } 41 | } 42 | 43 | 44 | const handleListItem = (item) => { 45 | setSelectedLocation(item) 46 | setShowLocation(false) 47 | loadRestaurants({location:item}) 48 | } 49 | console.log(restaurants); 50 | return ( 51 |
52 | 53 |
54 |

Food Delivery App

55 |
56 | setShowLocation(true)} 58 | className="select-input" placeholder="Select Place" /> 59 |
    60 | { 61 | showLocation && locations.map((item) => ( 62 |
  • handleListItem(item)}>{item}
  • 63 | )) 64 | } 65 |
66 | 67 | loadRestaurants({restaurant:event.target.value})} 69 | placeholder="Enter food or restaurant name" /> 70 |
71 |
72 |
73 | { 74 | restaurants.map((item) => ( 75 |
router.push('explore/'+item.name+"?id="+item._id)} className="restaurant-wrapper"> 76 |
77 |

{item.name}

78 |
Contact:{item.contact}
79 |
80 |
81 |
{item.city},
82 |
{item.address}, Email: {item.email}
83 | 84 |
85 |
86 | )) 87 | } 88 |
89 |
91 | ); 92 | } 93 | -------------------------------------------------------------------------------- /src/app/page.module.css: -------------------------------------------------------------------------------- 1 | .main { 2 | display: flex; 3 | flex-direction: column; 4 | justify-content: space-between; 5 | align-items: center; 6 | padding: 6rem; 7 | min-height: 100vh; 8 | } 9 | 10 | .description { 11 | display: inherit; 12 | justify-content: inherit; 13 | align-items: inherit; 14 | font-size: 0.85rem; 15 | max-width: var(--max-width); 16 | width: 100%; 17 | z-index: 2; 18 | font-family: var(--font-mono); 19 | } 20 | 21 | .description a { 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | gap: 0.5rem; 26 | } 27 | 28 | .description p { 29 | position: relative; 30 | margin: 0; 31 | padding: 1rem; 32 | background-color: rgba(var(--callout-rgb), 0.5); 33 | border: 1px solid rgba(var(--callout-border-rgb), 0.3); 34 | border-radius: var(--border-radius); 35 | } 36 | 37 | .code { 38 | font-weight: 700; 39 | font-family: var(--font-mono); 40 | } 41 | 42 | .grid { 43 | display: grid; 44 | grid-template-columns: repeat(4, minmax(25%, auto)); 45 | max-width: 100%; 46 | width: var(--max-width); 47 | } 48 | 49 | .card { 50 | padding: 1rem 1.2rem; 51 | border-radius: var(--border-radius); 52 | background: rgba(var(--card-rgb), 0); 53 | border: 1px solid rgba(var(--card-border-rgb), 0); 54 | transition: background 200ms, border 200ms; 55 | } 56 | 57 | .card span { 58 | display: inline-block; 59 | transition: transform 200ms; 60 | } 61 | 62 | .card h2 { 63 | font-weight: 600; 64 | margin-bottom: 0.7rem; 65 | } 66 | 67 | .card p { 68 | margin: 0; 69 | opacity: 0.6; 70 | font-size: 0.9rem; 71 | line-height: 1.5; 72 | max-width: 30ch; 73 | text-wrap: balance; 74 | } 75 | 76 | .center { 77 | display: flex; 78 | justify-content: center; 79 | align-items: center; 80 | position: relative; 81 | padding: 4rem 0; 82 | } 83 | 84 | .center::before { 85 | background: var(--secondary-glow); 86 | border-radius: 50%; 87 | width: 480px; 88 | height: 360px; 89 | margin-left: -400px; 90 | } 91 | 92 | .center::after { 93 | background: var(--primary-glow); 94 | width: 240px; 95 | height: 180px; 96 | z-index: -1; 97 | } 98 | 99 | .center::before, 100 | .center::after { 101 | content: ""; 102 | left: 50%; 103 | position: absolute; 104 | filter: blur(45px); 105 | transform: translateZ(0); 106 | } 107 | 108 | .logo { 109 | position: relative; 110 | } 111 | /* Enable hover only on non-touch devices */ 112 | @media (hover: hover) and (pointer: fine) { 113 | .card:hover { 114 | background: rgba(var(--card-rgb), 0.1); 115 | border: 1px solid rgba(var(--card-border-rgb), 0.15); 116 | } 117 | 118 | .card:hover span { 119 | transform: translateX(4px); 120 | } 121 | } 122 | 123 | @media (prefers-reduced-motion) { 124 | .card:hover span { 125 | transform: none; 126 | } 127 | } 128 | 129 | /* Mobile */ 130 | @media (max-width: 700px) { 131 | .content { 132 | padding: 4rem; 133 | } 134 | 135 | .grid { 136 | grid-template-columns: 1fr; 137 | margin-bottom: 120px; 138 | max-width: 320px; 139 | text-align: center; 140 | } 141 | 142 | .card { 143 | padding: 1rem 2.5rem; 144 | } 145 | 146 | .card h2 { 147 | margin-bottom: 0.5rem; 148 | } 149 | 150 | .center { 151 | padding: 8rem 0 6rem; 152 | } 153 | 154 | .center::before { 155 | transform: none; 156 | height: 300px; 157 | } 158 | 159 | .description { 160 | font-size: 0.8rem; 161 | } 162 | 163 | .description a { 164 | padding: 1rem; 165 | } 166 | 167 | .description p, 168 | .description div { 169 | display: flex; 170 | justify-content: center; 171 | position: fixed; 172 | width: 100%; 173 | } 174 | 175 | .description p { 176 | align-items: center; 177 | inset: 0 0 auto; 178 | padding: 2rem 1rem 1.4rem; 179 | border-radius: 0; 180 | border: none; 181 | border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); 182 | background: linear-gradient( 183 | to bottom, 184 | rgba(var(--background-start-rgb), 1), 185 | rgba(var(--callout-rgb), 0.5) 186 | ); 187 | background-clip: padding-box; 188 | backdrop-filter: blur(24px); 189 | } 190 | 191 | .description div { 192 | align-items: flex-end; 193 | pointer-events: none; 194 | inset: auto 0 0; 195 | padding: 2rem; 196 | height: 200px; 197 | background: linear-gradient( 198 | to bottom, 199 | transparent 0%, 200 | rgb(var(--background-end-rgb)) 40% 201 | ); 202 | z-index: 1; 203 | } 204 | } 205 | 206 | /* Tablet and Smaller Desktop */ 207 | @media (min-width: 701px) and (max-width: 1120px) { 208 | .grid { 209 | grid-template-columns: repeat(2, 50%); 210 | } 211 | } 212 | 213 | @media (prefers-color-scheme: dark) { 214 | .vercelLogo { 215 | filter: invert(1); 216 | } 217 | 218 | .logo { 219 | filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); 220 | } 221 | } 222 | 223 | @keyframes rotate { 224 | from { 225 | transform: rotate(360deg); 226 | } 227 | to { 228 | transform: rotate(0deg); 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /src/app/restaurant/dashboard/[id]/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { useRouter } from "next/navigation"; 3 | import { useEffect, useState } from "react"; 4 | 5 | const EditFoodItems = (props) => { 6 | 7 | console.log(props.params.id); 8 | const [name, setName] = useState(""); 9 | const [price, setPrice] = useState(""); 10 | const [path, setPath] = useState(""); 11 | const [description, setDescription] = useState(""); 12 | const [error, setError] = useState(false) 13 | const router = useRouter(); 14 | 15 | useEffect(() => { 16 | handleLoadFoodItem(); 17 | }, []) 18 | 19 | const handleLoadFoodItem = async () => { 20 | let response = await fetch("http://localhost:3000/api/restaurant/foods/edit/" + props.params.id); 21 | response = await response.json(); 22 | if (response.success) { 23 | console.log(response.result); 24 | setName(response.result.name) 25 | setPrice(response.result.price) 26 | setPath(response.result.img_path) 27 | setDescription(response.result.description) 28 | } 29 | } 30 | 31 | const handleEditFoodItem = async () => { 32 | console.log(name, price, path, description); 33 | if (!name || !path || !price || !description) { 34 | setError(true); 35 | return false 36 | } else { 37 | setError(false) 38 | } 39 | 40 | let response = await fetch("http://localhost:3000/api/restaurant/foods/edit/" + props.params.id,{ 41 | method:'PUT', 42 | body:JSON.stringify({name,price,img_path:path,description}) 43 | }); 44 | response = await response.json(); 45 | if(response.success){ 46 | router.push('../dashboard') 47 | }else{ 48 | alert("data is not updated please try again") 49 | } 50 | 51 | 52 | } 53 | 54 | return (
55 |

Update Food Item

56 |
57 | setName(e.target.value)} 59 | /> 60 | {error && !name && Please enter valid name} 61 |
62 |
63 | setPrice(e.target.value)} 65 | /> 66 | {error && !price && Please enter valid price} 67 | 68 |
69 |
70 | setPath(e.target.value)} 72 | /> 73 | {error && !path && Please enter valid path} 74 | 75 |
76 |
77 | setDescription(e.target.value)} 79 | /> 80 | {error && !description && Please enter valid description} 81 | 82 |
83 |
84 | 85 |
86 |
87 | 88 |
89 |
) 90 | } 91 | 92 | export default EditFoodItems; -------------------------------------------------------------------------------- /src/app/restaurant/dashboard/page.js: -------------------------------------------------------------------------------- 1 | "use client" 2 | import RestaurantHeader from "@/app/_components/RestaurantHeader"; 3 | import './../style.css' 4 | import AddFoodItems from "@/app/_components/AddFoodItem"; 5 | import { useState } from "react"; 6 | import FoodItemList from "@/app/_components/FoodItemList"; 7 | const Dashboard = () => { 8 | const [addItem, setAddItem] = useState(false) 9 | return (
10 | 11 | 12 | 13 | { 14 | addItem ? : 15 | } 16 |
) 17 | } 18 | 19 | export default Dashboard; -------------------------------------------------------------------------------- /src/app/restaurant/page.js: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { useState } from "react"; 3 | import RestaurantLogin from "../_components/RestaurantLogin"; 4 | import RestaurantSignUp from "../_components/RestaurantSignUp"; 5 | import RestaurantHeader from "../_components/RestaurantHeader"; 6 | import Footer from "../_components/Footer"; 7 | import './style.css' 8 | 9 | const Restaurant = () => { 10 | const [login, setLogin] = useState(true) 11 | return ( 12 | <> 13 |
14 | 15 |

Restaurant Login/Signup Page

16 | { 17 | login ? : 18 | } 19 | 20 |
21 | 24 |
25 |
26 |