From 14952c45cd3c84bb2636720510dcd4619346a026 Mon Sep 17 00:00:00 2001 From: Satyabrat Ojha Date: Mon, 29 May 2023 10:25:14 +0530 Subject: [PATCH] REST API --- .env | 1 + components/PizzaCard.jsx | 15 +- components/PizzaList.jsx | 13 +- models/Order.js | 32 ++++ models/Product.js | 37 ++++ package-lock.json | 336 ++++++++++++++++++++++++++++++++++++ package.json | 3 + pages/api/hello.js | 5 - pages/api/products/[id].jsx | 38 ++++ pages/api/products/index.js | 26 +++ pages/index.js | 14 +- pages/product/[id].jsx | 110 ++++++------ util/mongo.js | 40 +++++ 13 files changed, 598 insertions(+), 72 deletions(-) create mode 100644 .env create mode 100644 models/Order.js create mode 100644 models/Product.js delete mode 100644 pages/api/hello.js create mode 100644 pages/api/products/[id].jsx create mode 100644 pages/api/products/index.js create mode 100644 util/mongo.js diff --git a/.env b/.env new file mode 100644 index 0000000..356e4de --- /dev/null +++ b/.env @@ -0,0 +1 @@ +MONGO_URL = mongodb+srv://satyabratojha04:x3emesatya@cluster0.14lpurt.mongodb.net/pizza?retryWrites=true&w=majority \ No newline at end of file diff --git a/components/PizzaCard.jsx b/components/PizzaCard.jsx index 969e321..fa1e492 100644 --- a/components/PizzaCard.jsx +++ b/components/PizzaCard.jsx @@ -1,15 +1,16 @@ import Image from "next/image"; import styles from "../styles/PizzaCard.module.css"; +import Link from "next/link"; -const PizzaCard = () => { +const PizzaCard = ({ pizza }) => { return (
- -

FIORI DI ZUCCA

- $ 19.90 -

- Lorem ipsum dolar sit amet adipisicing elit. -

+ + + +

{pizza.title}

+ ${pizza.prices[0]} +

{pizza.desc}

); }; diff --git a/components/PizzaList.jsx b/components/PizzaList.jsx index 04c563a..0c39763 100644 --- a/components/PizzaList.jsx +++ b/components/PizzaList.jsx @@ -1,7 +1,7 @@ import styles from "../styles/PizzaList.module.css"; import PizzaCard from "./PizzaCard"; -const PizzaList = () => { +const PizzaList = ({ pizzaList }) => { return (

THE BEST PIZZA IN TOWN

@@ -12,14 +12,9 @@ const PizzaList = () => { voluptatibus.

- - - - - - - - + {pizzaList.map((pizza) => ( + + ))}
); diff --git a/models/Order.js b/models/Order.js new file mode 100644 index 0000000..5faa7f5 --- /dev/null +++ b/models/Order.js @@ -0,0 +1,32 @@ +import { Timestamp } from "mongodb"; +import mongoose from "mongoose"; + +const OrderSchema = new mongoose.Schema( + { + customer: { + type: String, + required: true, + maxlength: 60, + }, + address: { + type: String, + required: true, + maxlength: 200, + }, + total: { + type: Number, + required: true, + }, + status: { + type: Number, + default: 0, + }, + method: { + type: Number, + required: true, + }, + }, + { timestamps: true } +); + +export default mongoose.models.Order || mongoose.model("Order", OrderSchema); diff --git a/models/Product.js b/models/Product.js new file mode 100644 index 0000000..9518f03 --- /dev/null +++ b/models/Product.js @@ -0,0 +1,37 @@ +import { Timestamp } from "mongodb"; +import mongoose from "mongoose"; + +const ProductSchema = new mongoose.Schema( + { + title: { + type: String, + required: true, + maxlength: 60, + }, + desc: { + type: String, + required: true, + maxlength: 200, + }, + img: { + type: String, + required: true, + }, + prices: { + type: [Number], + required: true, + }, + extraOptions: { + type: [ + { + text: { type: String, required: true }, + price: { type: Number, required: true }, + }, + ], + }, + }, + { timestamps: true } +); + +export default mongoose.models.Product || + mongoose.model("Product", ProductSchema); diff --git a/package-lock.json b/package-lock.json index 5a95651..6990ba7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,11 @@ "name": "restaurant", "version": "0.1.0", "dependencies": { + "axios": "^1.4.0", "eslint": "8.39.0", "eslint-config-next": "13.3.4", + "mongodb": "^5.4.0", + "mongoose": "^7.1.0", "next": "13.3.4", "react": "18.2.0", "react-dom": "18.2.0" @@ -325,6 +328,25 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/node": { + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.2.tgz", + "integrity": "sha512-CTO/wa8x+rZU626cL2BlbCDzydgnFNgc19h4YvizpTO88MFQxab8wqisxaofQJ/9bLGugRdWIuX/TbIs6VVF6g==" + }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", + "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, "node_modules/@typescript-eslint/parser": { "version": "5.59.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", @@ -579,6 +601,11 @@ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -598,6 +625,16 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", @@ -650,6 +687,14 @@ "node": ">=8" } }, + "node_modules/bson": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-5.2.0.tgz", + "integrity": "sha512-HevkSpDbpUfsrHWmWiAsNavANKYIErV2ePXllp1bwq5CDreAaFVj6RVlZpJnxK4WWDCJ/5jMUpaY6G526q3Hjg==", + "engines": { + "node": ">=14.20.1" + } + }, "node_modules/bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -750,6 +795,17 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -880,6 +936,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1581,6 +1645,25 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -1589,6 +1672,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1909,6 +2005,11 @@ "node": ">= 0.4" } }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -2313,6 +2414,14 @@ "node": ">=4.0" } }, + "node_modules/kareem": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", + "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -2379,6 +2488,12 @@ "node": ">=10" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2404,6 +2519,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", @@ -2434,6 +2568,124 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mongodb": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.4.0.tgz", + "integrity": "sha512-6GDKgO7WiYUw+ILap143VXfAou06hjxDGgYUZWGnI4hgoZfP3el0G3l69JqJF8SEQbZmC+SN/2a0aWI/aWJoxA==", + "dependencies": { + "bson": "^5.2.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" + }, + "engines": { + "node": ">=14.20.1" + }, + "optionalDependencies": { + "saslprep": "^1.0.3" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.201.0", + "mongodb-client-encryption": ">=2.3.0 <3", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", + "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongoose": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.1.0.tgz", + "integrity": "sha512-shoo9z/7o96Ojx69wpJn65+EC+Mt3q1SWTducW+F2Y4ieCXo0lZwpCZedgC841MIvJ7V8o6gmzoN1NfcnOTOuw==", + "dependencies": { + "bson": "^5.2.0", + "kareem": "2.5.1", + "mongodb": "5.3.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "16.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/mongodb": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.3.0.tgz", + "integrity": "sha512-Wy/sbahguL8c3TXQWXmuBabiLD+iVmz+tOgQf+FwkCjhUIorqbAxRbbz00g4ZoN4sXIPwpAlTANMaGRjGGTikQ==", + "dependencies": { + "bson": "^5.2.0", + "mongodb-connection-string-url": "^2.6.0", + "socks": "^2.7.1" + }, + "engines": { + "node": ">=14.20.1" + }, + "optionalDependencies": { + "saslprep": "^1.0.3" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.201.0", + "mongodb-client-encryption": ">=2.3.0 <3", + "snappy": "^7.2.2" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2839,6 +3091,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -3093,6 +3350,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -3147,6 +3416,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", + "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -3160,6 +3434,28 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -3168,6 +3464,15 @@ "node": ">=0.10.0" } }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", @@ -3382,6 +3687,17 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/tsconfig-paths": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", @@ -3495,6 +3811,26 @@ "punycode": "^2.1.0" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 2b0b5a3..2f7e5c2 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,11 @@ "lint": "next lint" }, "dependencies": { + "axios": "^1.4.0", "eslint": "8.39.0", "eslint-config-next": "13.3.4", + "mongodb": "^5.4.0", + "mongoose": "^7.1.0", "next": "13.3.4", "react": "18.2.0", "react-dom": "18.2.0" diff --git a/pages/api/hello.js b/pages/api/hello.js deleted file mode 100644 index df63de8..0000000 --- a/pages/api/hello.js +++ /dev/null @@ -1,5 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction - -export default function handler(req, res) { - res.status(200).json({ name: 'John Doe' }) -} diff --git a/pages/api/products/[id].jsx b/pages/api/products/[id].jsx new file mode 100644 index 0000000..27d3223 --- /dev/null +++ b/pages/api/products/[id].jsx @@ -0,0 +1,38 @@ +import dbConnect from "@/util/mongo"; +import Product from "@/models/Product"; + +export default async function handler(req, res) { + const { + method, + query: { id }, + } = req; + + dbConnect(); + + if (method === "GET") { + try { + const product = await Product.findById(id); + res.status(200).json(product); + } catch (err) { + res.status(500).json(err); + } + } + + if (method === "PUT") { + try { + const product = await Product.create(req.body); + res.status(201).json(product); + } catch (err) { + res.status(500).json(err); + } + } + + if (method === "DELETE") { + try { + const product = await Product.create(req.body); + res.status(201).json(product); + } catch (err) { + res.status(500).json(err); + } + } +} diff --git a/pages/api/products/index.js b/pages/api/products/index.js new file mode 100644 index 0000000..7a9d18c --- /dev/null +++ b/pages/api/products/index.js @@ -0,0 +1,26 @@ +import dbConnect from "@/util/mongo"; +import Product from "@/models/Product"; + +export default async function handler(req, res) { + const { method } = req; + + dbConnect(); + + if (method === "GET") { + try { + const products = await Product.find(); + res.status(200).json(products); + } catch (err) { + res.status(500).json(err); + } + } + + if (method === "POST") { + try { + const product = await Product.create(req.body); + res.status(201).json(product); + } catch (err) { + res.status(500).json(err); + } + } +} diff --git a/pages/index.js b/pages/index.js index 9e3ef07..9115fb5 100644 --- a/pages/index.js +++ b/pages/index.js @@ -4,10 +4,11 @@ import { Inter } from "next/font/google"; import styles from "@/styles/Home.module.css"; import Featured from "@/components/Featured"; import PizzaList from "@/components/PizzaList"; +import axios from "axios"; const inter = Inter({ subsets: ["latin"] }); -export default function Home() { +export default function Home({ pizzaList }) { return ( <> @@ -17,7 +18,16 @@ export default function Home() { - + ); } + +export const getServerSideProps = async () => { + const res = await axios.get("http://localhost:3000/api/products"); + return { + props: { + pizzaList: res.data, + }, + }; +}; diff --git a/pages/product/[id].jsx b/pages/product/[id].jsx index ed34ab9..ec0ad47 100644 --- a/pages/product/[id].jsx +++ b/pages/product/[id].jsx @@ -1,16 +1,35 @@ import styles from "@/styles/Product.module.css"; import Image from "next/image"; import { useState } from "react"; +import axios from "axios"; +import { set } from "mongoose"; -const Product = () => { +const Product = ({ pizza }) => { + const [price, setPrice] = useState(pizza.prices[0]); const [size, setSize] = useState(0); + const [extras, setExtras] = useState([]); + const [quantity, setQuantity] = useState(1); - const pizza = { - id: 1, - img: "/img/pizza.png", - name: "CAMPAGNOLA", - price: [19.9, 23.9, 27.9], - desc: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis arcu purus, rhoncus fringilla vestibulum vel, dignissim vel ante. Nulla facilisi. Nullam a urna sit amet tellus pellentesque egestas in in ante.", + const changePrice = (number) => { + setPrice(price + number); + }; + + const handleSize = (sizeIndex) => { + const difference = pizza.prices[sizeIndex] - pizza.prices[size]; + setSize(sizeIndex); + changePrice(difference); + }; + + const handleChanges = (e, option) => { + const checked = e.target.checked; + + if (checked) { + changePrice(option.price); + setExtras([...extras, option]); + } else { + changePrice(-option.price); + setExtras(extras.filter((extra) => extra._id !== option._id)); + } }; return ( @@ -26,65 +45,47 @@ const Product = () => {
-

{pizza.name}

- ${pizza.price[size]} +

{pizza.title}

+ {price}

{pizza.desc}

Choose the size

-
setSize(0)}> +
handleSize(0)}> Small
-
setSize(1)}> +
handleSize(1)}> Medium
-
setSize(2)}> +
handleSize(2)}> Large

Choose additional ingredients

-
- - -
-
- - -
-
- - -
-
- - -
+ {pizza.extraOptions.map((option) => ( +
+ handleChanges(e, option)} + /> + +
+ ))}
- + setQuantity(e.target.value)} + type="number" + defaultValue={1} + className={styles.quantity} + min={1} + />
@@ -92,4 +93,15 @@ const Product = () => { ); }; +export const getServerSideProps = async ({ params }) => { + const res = await axios.get( + `http://localhost:3000/api/products/${params.id}` + ); + return { + props: { + pizza: res.data, + }, + }; +}; + export default Product; diff --git a/util/mongo.js b/util/mongo.js new file mode 100644 index 0000000..c1c9cbe --- /dev/null +++ b/util/mongo.js @@ -0,0 +1,40 @@ +import mongoose from "mongoose"; + +const MONGO_URL = process.env.MONGO_URL; + +if (!MONGO_URL) { + throw new Error( + "Please define the MONGO_URL environment variable inside .env.local" + ); +} + +/** + * Global is used here to maintain a cached connection across hot reloads + * in development. This prevents connections growing exponentially + * during API Route usage. + */ +let cached = global.mongoose; + +if (!cached) { + cached = global.mongoose = { conn: null, promise: null }; +} + +async function dbConnect() { + if (cached.conn) { + return cached.conn; + } + + if (!cached.promise) { + const opts = { + bufferCommands: false, + }; + + cached.promise = mongoose.connect(MONGO_URL, opts).then((mongoose) => { + return mongoose; + }); + } + cached.conn = await cached.promise; + return cached.conn; +} + +export default dbConnect;