diff --git a/src/components/LoginPage.vue b/src/components/LoginPage.vue
index 80edb80..39b1427 100644
--- a/src/components/LoginPage.vue
+++ b/src/components/LoginPage.vue
@@ -33,7 +33,7 @@ export default {
methods: {
async login() {
const person = await data.login(this.username);
- if (person?.id) {
+ if (person?.id >= 0) {
this.$router.push(this.redirect);
return;
}
diff --git a/src/components/meals/EditMealPage.vue b/src/components/meals/EditMealPage.vue
index 75fecaf..bf00c5a 100644
--- a/src/components/meals/EditMealPage.vue
+++ b/src/components/meals/EditMealPage.vue
@@ -55,7 +55,7 @@ export default {
data() {
return {
meal: {
- id: 0,
+ id: -1,
meal_date: new Date(),
recipes: [],
extra_ingredients: [],
@@ -66,7 +66,7 @@ export default {
};
},
async beforeMount() {
- if (this.id) {
+ if (this.id >= 0) {
this.meal = await data.getMeal(this.id);
}
},
@@ -109,7 +109,7 @@ export default {
},
async saveMeal() {
const meal = await data.saveMeal(this.meal);
- if (meal?.id) {
+ if (meal?.id >= 0) {
this.$router.push(`/meals/${meal.id}`);
return;
}
diff --git a/src/components/meals/PersonList.vue b/src/components/meals/PersonList.vue
index 62a7c5d..793f6ec 100644
--- a/src/components/meals/PersonList.vue
+++ b/src/components/meals/PersonList.vue
@@ -148,12 +148,12 @@ export default {
this.searchResults = results.filter(p => !idSet.has(p.id));
},
addPerson(person) {
- if (!person?.id && this.searchResults.length > 0)
+ if (!person?.id >= 0 && this.searchResults.length > 0)
{
person = this.searchResults[0];
}
- if (person?.id && !this.people.find(p => p.id === person.id))
+ if (person?.id >= 0 && !this.people.find(p => p.id === person.id))
{
this.$emit('add-person', person);
}
diff --git a/src/components/recipes/EditRecipePage.vue b/src/components/recipes/EditRecipePage.vue
index ed9bbfc..fe61278 100644
--- a/src/components/recipes/EditRecipePage.vue
+++ b/src/components/recipes/EditRecipePage.vue
@@ -99,7 +99,7 @@ export default {
this.refreshRecipe();
},
async refreshRecipe() {
- if (this.id) {
+ if (this.id >= 0) {
this.recipe = await data.getRecipe(this.id);
this.link = this.recipe.link;
return;
@@ -120,7 +120,7 @@ export default {
},
async saveRecipe() {
const recipe = await data.saveRecipe(this.recipe);
- if (recipe?.id) {
+ if (recipe?.id >= 0) {
this.$router.push(`/recipes/${recipe.id}`);
return;
}
@@ -129,8 +129,9 @@ export default {
},
async createFromScratch() {
this.recipe = {
- id: 0,
+ id: -1,
name: 'My new recipe',
+ created_by_id: -1,
link: '',
ingredients: [],
image_urls: []
diff --git a/src/components/shopping/FullShoppingListPage.vue b/src/components/shopping/CurrentShoppingListPage.vue
similarity index 88%
rename from src/components/shopping/FullShoppingListPage.vue
rename to src/components/shopping/CurrentShoppingListPage.vue
index 63d1b7b..41cec6f 100644
--- a/src/components/shopping/FullShoppingListPage.vue
+++ b/src/components/shopping/CurrentShoppingListPage.vue
@@ -16,6 +16,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/components/shopping/shopping.js b/src/components/shopping/shopping.js
index 62ed9a7..b1d7b5a 100644
--- a/src/components/shopping/shopping.js
+++ b/src/components/shopping/shopping.js
@@ -46,7 +46,7 @@ export function groupingToIngredients(grouping) {
const product = grouping.product;
const totals = [];
for (const total of grouping.totals) {
- totals.push({ id: 0, line: `${total.quantity} ${total.unit} of ${product.name}`, preparation: '', name: product.name, product, ...total });
+ totals.push({ id: -1, line: `${total.quantity} ${total.unit} of ${product.name}`, preparation: '', name: product.name, product, ...total });
}
return totals;
}
diff --git a/src/data.js b/src/data.js
index 9a5d1db..f36dd2b 100644
--- a/src/data.js
+++ b/src/data.js
@@ -1,46 +1,89 @@
const BASE_URL = window.location.href.replace(/^(http:\/\/[^/:]+).*/, "$1:8000")
-function fixDates(obj, ...fields) {
- for (const field of fields) {
+const datesToFix = {
+ Meal: { fields: [ "meal_date" ] },
+ ShoppingList: { fields: [ "created_date", "purchased_date" ], dependants: l => ({ ShoppingListResult: l.results, ShoppingListRequest: l.requests }) },
+ ShoppingListResult: { fields: [ "found_date", "created_date" ], },
+ ShoppingListRequest: { fields: [ "created_date" ], dependants: r => ({ Meal: r.meal }) },
+ Recipe: { fields: [ "date_created", "date_hidden" ], },
+};
+
+const fixDates = (obj, type) => {
+ if (!obj) return;
+
+ if (Array.isArray(obj)) {
+ for (const item of obj) {
+ fixDates(item, type);
+ }
+ }
+
+ const toFix = datesToFix[type];
+ if (!toFix) return;
+
+ for (const field of toFix.fields) {
if (obj[field]) {
obj[field] = new Date(obj[field]);
}
}
+
+ if (toFix.dependants) {
+ for (const [key, value] of Object.entries(toFix.dependants(obj))) {
+ if (Array.isArray(value)) {
+ for (const item of value) {
+ fixDates(item, key);
+ }
+ }
+ else {
+ fixDates(value, key);
+ }
+ }
+ }
}
-const fixMealDates = meals => meals.forEach(meal => fixDates(meal, "meal_date"));
-const fixResultDates = results => results.forEach(result => fixDates(result, "found_date"));
let user = null;
export default {
async getMeals(from, to) {
const response = await fetch(BASE_URL + "/meals?from=" + from.toISOString() + "&to=" + to.toISOString());
const meals = await response.json();
- fixMealDates(meals);
+ fixDates(meals, "Meal");
return meals.sort((a, b) => a.meal_date - b.meal_date);
},
async getMeal(id) {
var response = await fetch(BASE_URL + `/meals/${encodeURIComponent(id)}`);
- return await response.json();
+ const meal = await response.json();
+ fixDates(meal, "Meal");
+
+ return meal;
},
async deleteMeal(id) {
var response = await fetch(BASE_URL + `/meals/${encodeURIComponent(id)}`, {
method: "DELETE",
});
+
return await response.json();
},
async searchRecipes(query) {
const response = await fetch(BASE_URL + "/recipes?q=" + encodeURIComponent(query));
- return await response.json();
+ const recipes = await response.json();
+ fixDates(recipes, "Recipe");
+
+ return recipes;
},
async parseRecipe(url) {
const response = await fetch(BASE_URL + `/recipes/parse?url=${encodeURIComponent(url)}`, { credentials: "include" });
- return await response.json();
+ const recipe = await response.json();
+ fixDates(recipe, "Recipe");
+
+ return recipe;
},
async getRecipe(id) {
const response = await fetch(BASE_URL + `/recipes/${encodeURIComponent(id)}`);
- return await response.json();
+ const recipe = await response.json();
+ fixDates(recipe, "Recipe");
+
+ return recipe;
},
async parseProduct(ingredient, url) {
const body = {
@@ -73,11 +116,15 @@ export default {
body: JSON.stringify(recipe),
});
- return await response.json();
+ const saved = await response.json();
+ fixDates(saved, "Recipe");
+
+ return saved;
},
async saveMeal(meal) {
- if (meal.id) {
- const response = await fetch(BASE_URL + `/meals/${encodeURIComponent(meal.id)}`, {
+ let response = null;
+ if (meal.id >= 0) {
+ response = await fetch(BASE_URL + `/meals/${encodeURIComponent(meal.id)}`, {
method: "PUT",
credentials: "include",
headers: {
@@ -85,19 +132,21 @@ export default {
},
body: JSON.stringify(meal),
});
- return await response.json();
+ } else {
+ response = await fetch(BASE_URL + "/meals", {
+ method: "POST",
+ credentials: "include",
+ headers: {
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify(meal),
+ });
}
- const response = await fetch(BASE_URL + "/meals", {
- method: "POST",
- credentials: "include",
- headers: {
- "Content-Type": "application/json"
- },
- body: JSON.stringify(meal),
- });
-
- return await response.json();
+ const saved = await response.json();
+ fixDates(saved, "Meal");
+
+ return saved;
},
async currentUser() {
if (user) {
@@ -139,7 +188,10 @@ export default {
method: "DELETE",
credentials: "include",
});
- return await response.json();
+
+ const recipe = await response.json();
+ fixDates(recipe, "Recipe");
+ return recipe;
},
async searchPerson(name) {
const response = await fetch(BASE_URL + "/persons?q=" + encodeURIComponent(name));
@@ -147,7 +199,10 @@ export default {
},
async getMyShoppingList() {
const response = await fetch(BASE_URL + "/shopping/current/me/ingredients", { credentials: "include" });
- return await response.json();
+ const requests = await response.json();
+ fixDates(requests, "ShoppingListRequest");
+
+ return requests;
},
async saveMyShoppingList(list) {
const response = await fetch(BASE_URL + "/shopping/current/me/ingredients", {
@@ -159,18 +214,22 @@ export default {
body: JSON.stringify(list),
});
- return await response.json();
+ const requests = await response.json();
+ fixDates(requests, "ShoppingListRequest");
+
+ return requests;
},
async getShoppingList(id) {
const response = await fetch(BASE_URL + `/shopping/${encodeURIComponent(id)}`);
- return await response.json();
+
+ const lst = await response.json();
+ fixDates(lst, "ShoppingList");
+ return lst;
},
async getCurrentShoppingList() {
const response = await fetch(BASE_URL + "/shopping/current");
const lst = await response.json();
- fixMealDates(lst.requests.map(request => request.meal).filter(meal => meal));
- fixResultDates(lst.results);
- fixDates(lst, "created_date");
+ fixDates(lst, "ShoppingList");
return lst;
},
@@ -184,9 +243,10 @@ export default {
body: JSON.stringify({ meal_id }),
});
- const result = await response.json();
- fixMealDates([result.meal]);
- return result;
+ const requests = await response.json();
+ fixDates(requests, "ShoppingListRequest");
+
+ return requests;
},
async unrequestMeal(meal_id) {
const response = await fetch(BASE_URL + `/shopping/current/meals/${encodeURIComponent(meal_id)}`, {
@@ -194,7 +254,8 @@ export default {
credentials: "include",
});
- return await response.json();
+ const requests = await response.json();
+ fixDates(requests, "ShoppingListRequest");
},
async markFound(ingredients) {
const response = await fetch(BASE_URL + "/shopping/current/found", {
@@ -207,8 +268,9 @@ export default {
});
const results = await response.json();
- fixResultDates(results.created);
- fixResultDates(results.removed);
+ fixDates(results.created, "ShoppingListResult");
+ fixDates(results.removed, "ShoppingListResult");
+
return results;
},
async markNotFound(product_id) {
@@ -217,8 +279,20 @@ export default {
credentials: "include",
});
- const results = await response.json();
- fixResultDates(results);
- return results;
+ const removedResults = await response.json();
+ fixDates(removedResults, "ShoppingListResult");
+
+ return removedResults;
+ },
+ async markCurrentShoppingListPurchased() {
+ const response = await fetch(BASE_URL + "/shopping/current/purchased", {
+ method: "POST",
+ credentials: "include",
+ });
+
+ const lst = await response.json();
+ fixDates(lst, "ShoppingList");
+
+ return lst;
}
}
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 4d692de..11fadfb 100644
--- a/src/main.js
+++ b/src/main.js
@@ -7,7 +7,8 @@ import LoginPage from './components/LoginPage.vue'
import RecipesPage from './components/recipes/RecipesPage.vue'
import MealPlanPage from './components/meals/MealPlanPage.vue'
import MyShoppingPage from './components/shopping/MyShoppingPage.vue'
-import FullShoppingListPage from './components/shopping/FullShoppingListPage.vue'
+import PurchasedShoppingListPage from './components/shopping/PurchasedShoppingListPage.vue'
+import CurrentShoppingListPage from './components/shopping/CurrentShoppingListPage.vue'
import EditMealPage from './components/meals/EditMealPage.vue'
import EditRecipePage from './components/recipes/EditRecipePage.vue'
@@ -19,7 +20,8 @@ const routes = [
{ path: '/mealplan', component: MealPlanPage },
{ path: '/login', component: LoginPage },
{ path: '/shopping', component: MyShoppingPage },
- { path: '/shopping/:id', component: FullShoppingListPage, props : true },
+ { path: '/shopping/current', component: CurrentShoppingListPage },
+ { path: '/shopping/:id', component: PurchasedShoppingListPage, props : true },
{ path: '/recipes', component: RecipesPage },
{ path: '/recipes/add', component: EditRecipePage },
{ path: '/recipes/:id', component: EditRecipePage, props: true },