diff --git a/package-lock.json b/package-lock.json index b19f8e8..ac77b8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "0.1.0", "dependencies": { "core-js": "^3.8.3", - "vue": "^3.2.13" + "vue": "^3.2.13", + "vue-router": "^4.2.5" }, "devDependencies": { "@babel/core": "^7.12.16", @@ -3045,6 +3046,11 @@ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", "dev": true }, + "node_modules/@vue/devtools-api": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz", + "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==" + }, "node_modules/@vue/reactivity": { "version": "3.4.5", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.5.tgz", @@ -11026,6 +11032,20 @@ "node": ">=8" } }, + "node_modules/vue-router": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz", + "integrity": "sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==", + "dependencies": { + "@vue/devtools-api": "^6.5.0" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, "node_modules/vue-style-loader": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", @@ -12108,7 +12128,8 @@ "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "dev": true + "dev": true, + "requires": {} }, "@babel/plugin-syntax-async-generators": { "version": "7.8.4", @@ -13691,7 +13712,8 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-5.0.8.tgz", "integrity": "sha512-HSYWPqrunRE5ZZs8kVwiY6oWcn95qf/OQabwLfprhdpFWAGtLStShjsGED2aDpSSeGAskQETrtR/5h7VqgIlBA==", - "dev": true + "dev": true, + "requires": {} }, "@vue/cli-service": { "version": "5.0.8", @@ -13961,6 +13983,11 @@ } } }, + "@vue/devtools-api": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz", + "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==" + }, "@vue/reactivity": { "version": "3.4.5", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.5.tgz", @@ -14207,13 +14234,15 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true + "dev": true, + "requires": {} }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "8.3.1", @@ -14272,7 +14301,8 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true + "dev": true, + "requires": {} }, "ansi-colors": { "version": "4.1.3", @@ -15079,7 +15109,8 @@ "version": "6.4.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "dev": true + "dev": true, + "requires": {} }, "css-loader": { "version": "6.8.1", @@ -15265,7 +15296,8 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true + "dev": true, + "requires": {} }, "csso": { "version": "4.2.0", @@ -16787,7 +16819,8 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true + "dev": true, + "requires": {} }, "ieee754": { "version": "1.2.1", @@ -18174,25 +18207,29 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-duplicates": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-empty": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true + "dev": true, + "requires": {} }, "postcss-discard-overridden": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-loader": { "version": "6.2.1", @@ -18297,7 +18334,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true + "dev": true, + "requires": {} }, "postcss-modules-local-by-default": { "version": "4.0.3", @@ -18332,7 +18370,8 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true + "dev": true, + "requires": {} }, "postcss-normalize-display-values": { "version": "5.1.0", @@ -19831,6 +19870,14 @@ } } }, + "vue-router": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz", + "integrity": "sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==", + "requires": { + "@vue/devtools-api": "^6.5.0" + } + }, "vue-style-loader": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", @@ -20114,7 +20161,8 @@ "version": "8.16.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", - "dev": true + "dev": true, + "requires": {} } } }, @@ -20236,7 +20284,8 @@ "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true + "dev": true, + "requires": {} }, "y18n": { "version": "5.0.8", diff --git a/package.json b/package.json index aafa2d8..ae944eb 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ }, "dependencies": { "core-js": "^3.8.3", - "vue": "^3.2.13" + "vue": "^3.2.13", + "vue-router": "^4.2.5" }, "devDependencies": { "@babel/core": "^7.12.16", diff --git a/src/App.vue b/src/App.vue index 591a031..f7394ff 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,16 +1,28 @@ @@ -23,4 +35,32 @@ export default { color: #2c3e50; margin-top: 60px; } + +/* Make nav bar links buttons across top of screen */ +.nav { + display: flex; + justify-content: space-around; + list-style-type: none; + margin: 0; + padding: 0; + position: fixed; + top: 0; + width: 100%; + background-color: #333; +} + +/* Style the links inside the navigation bar */ +.nav a { + display: inline-block; + color: #f2f2f2; + text-align: center; + padding: 14px 16px; + text-decoration: none; +} + +/* Have active route use different color */ +.nav a.active { + background-color: #4CAF50; + color: white; +} diff --git a/src/assets/add-cart.svg b/src/assets/add-cart.svg new file mode 100644 index 0000000..0493e04 --- /dev/null +++ b/src/assets/add-cart.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/assets/add-recipe.svg b/src/assets/add-recipe.svg new file mode 100644 index 0000000..314a45d --- /dev/null +++ b/src/assets/add-recipe.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/logo.png b/src/assets/logo.png deleted file mode 100644 index f3d2503..0000000 Binary files a/src/assets/logo.png and /dev/null differ diff --git a/src/components/ActionItem.vue b/src/components/ActionItem.vue new file mode 100644 index 0000000..98523b7 --- /dev/null +++ b/src/components/ActionItem.vue @@ -0,0 +1,37 @@ + + + + + \ No newline at end of file diff --git a/src/components/ActionsPage.vue b/src/components/ActionsPage.vue new file mode 100644 index 0000000..3b72138 --- /dev/null +++ b/src/components/ActionsPage.vue @@ -0,0 +1,25 @@ + + \ No newline at end of file diff --git a/src/components/EditMealPage.vue b/src/components/EditMealPage.vue new file mode 100644 index 0000000..0b8a03e --- /dev/null +++ b/src/components/EditMealPage.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/components/EditRecipePage.vue b/src/components/EditRecipePage.vue new file mode 100644 index 0000000..ad8b39c --- /dev/null +++ b/src/components/EditRecipePage.vue @@ -0,0 +1,114 @@ + + + + + \ No newline at end of file diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue deleted file mode 100644 index 879051a..0000000 --- a/src/components/HelloWorld.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - diff --git a/src/components/IngredientLine.vue b/src/components/IngredientLine.vue new file mode 100644 index 0000000..17a39bf --- /dev/null +++ b/src/components/IngredientLine.vue @@ -0,0 +1,110 @@ + + + + + + \ No newline at end of file diff --git a/src/components/MealCard.vue b/src/components/MealCard.vue new file mode 100644 index 0000000..04185f2 --- /dev/null +++ b/src/components/MealCard.vue @@ -0,0 +1,39 @@ + + + + + \ No newline at end of file diff --git a/src/components/MealPlanPage.vue b/src/components/MealPlanPage.vue new file mode 100644 index 0000000..7857b0f --- /dev/null +++ b/src/components/MealPlanPage.vue @@ -0,0 +1,83 @@ + + + + + \ No newline at end of file diff --git a/src/components/ShoppingPage.vue b/src/components/ShoppingPage.vue new file mode 100644 index 0000000..6c2c4f4 --- /dev/null +++ b/src/components/ShoppingPage.vue @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/src/components/SwapMealPage.vue b/src/components/SwapMealPage.vue new file mode 100644 index 0000000..0b8a03e --- /dev/null +++ b/src/components/SwapMealPage.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/data.js b/src/data.js new file mode 100644 index 0000000..9aa6920 --- /dev/null +++ b/src/data.js @@ -0,0 +1,36 @@ +const BASE_URL = "http://localhost:8000" + +export default { + getMeals() { + return fetch(BASE_URL + "/meals") + .then(response => response.json()) + }, + getMeal(id) { + return fetch(BASE_URL + `/meals/${encodeURIComponent(id)}`) + .then(response => response.json()) + }, + getRecipes() { + }, + parseRecipe(url) { + return fetch(BASE_URL + `/recipes/parse?url=${encodeURIComponent(url)}`) + .then(response => response.json()) + }, + parseProduct(ingredient, url) { + const body = { + url, tags: [ingredient.name, ingredient.line], + } + + return fetch(BASE_URL + "/products", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(body), + }).then(response => response.json()) + }, + parseIngredients(lines) { + const params = lines.map(line => "ingredients=" + encodeURIComponent(line)).join("&"); + return fetch(BASE_URL + "/recipes/ingredients/parse?" + params) + .then(response => response.json()) + } +} \ No newline at end of file diff --git a/src/main.js b/src/main.js index 01433bc..0c67384 100644 --- a/src/main.js +++ b/src/main.js @@ -1,4 +1,42 @@ import { createApp } from 'vue' +import { createRouter, createWebHashHistory } from 'vue-router' + import App from './App.vue' -createApp(App).mount('#app') +import ActionsPage from './components/ActionsPage.vue' +import MealPlanPage from './components/MealPlanPage.vue' +import ShoppingPage from './components/ShoppingPage.vue' +import EditMealPage from './components/EditMealPage.vue' +import SwapMealPage from './components/SwapMealPage.vue' +import EditRecipePage from './components/EditRecipePage.vue' + +// 2. Define some routes +// Each route should map to a component. +// We'll talk about nested routes later. +const routes = [ + { path: '/', component: ActionsPage }, + { path: '/mealplan', component: MealPlanPage }, + { path: '/shopping', component: ShoppingPage }, + { path: '/meal/:id/edit', component: EditMealPage }, + { path: '/meal/:id/swap', component: SwapMealPage }, + { path: '/recipes/add', component: EditRecipePage }, +] + +// 3. Create the router instance and pass the `routes` option +// You can pass in additional options here, but let's +// keep it simple for now. +const router = createRouter({ + // 4. Provide the history implementation to use. We are using the hash history for simplicity here. + history: createWebHashHistory(), + routes, // short for `routes: routes` +}) + +// 5. Create and mount the root instance. +const app = createApp(App) +// Make sure to _use_ the router instance to make the +// whole app router-aware. +app.use(router) + +app.mount('#app') + +// Now the app has started! \ No newline at end of file