diff --git a/frontend/api/class-interfaces/_base.ts b/frontend/api/class-interfaces/_base.ts index 3e945f67ec97..e7383434e328 100644 --- a/frontend/api/class-interfaces/_base.ts +++ b/frontend/api/class-interfaces/_base.ts @@ -12,15 +12,14 @@ export interface CrudAPIInterface { export interface CrudAPIMethodsInterface { // CRUD Methods - getAll(): any - createOne(): any - getOne(): any - updateOne(): any - patchOne(): any - deleteOne(): any + getAll(): any; + createOne(): any; + getOne(): any; + updateOne(): any; + patchOne(): any; + deleteOne(): any; } - export abstract class BaseAPI { requests: ApiRequestInstance; @@ -33,9 +32,9 @@ export abstract class BaseCRUDAPI extends BaseAPI implements CrudAPIInterf abstract baseRoute: string; abstract itemRoute(itemId: string | number): string; - async getAll(start = 0, limit = 9999) { + async getAll(start = 0, limit = 9999, params = {}) { return await this.requests.get(this.baseRoute, { - params: { start, limit }, + params: { start, limit, ...params }, }); } diff --git a/frontend/api/class-interfaces/cookbooks.ts b/frontend/api/class-interfaces/group-cookbooks.ts similarity index 100% rename from frontend/api/class-interfaces/cookbooks.ts rename to frontend/api/class-interfaces/group-cookbooks.ts diff --git a/frontend/api/class-interfaces/group-mealplan.ts b/frontend/api/class-interfaces/group-mealplan.ts new file mode 100644 index 000000000000..f81279427008 --- /dev/null +++ b/frontend/api/class-interfaces/group-mealplan.ts @@ -0,0 +1,32 @@ +import { BaseCRUDAPI } from "./_base"; + +const prefix = "/api"; + +const routes = { + mealplan: `${prefix}/groups/mealplans`, + mealplanId: (id: string | number) => `${prefix}/groups/mealplans/${id}`, +}; + +type PlanEntryType = "breakfast" | "lunch" | "dinner" | "snack"; + +export interface CreateMealPlan { + date: string; + entryType: PlanEntryType; + title: string; + text: string; + recipeId?: number; +} + +export interface UpdateMealPlan extends CreateMealPlan { + id: number; + groupId: number; +} + +export interface MealPlan extends UpdateMealPlan { + recipe: any; +} + +export class MealPlanAPI extends BaseCRUDAPI { + baseRoute = routes.mealplan; + itemRoute = routes.mealplanId; +} diff --git a/frontend/api/index.ts b/frontend/api/index.ts index 90605ca05f11..0671b11d1a67 100644 --- a/frontend/api/index.ts +++ b/frontend/api/index.ts @@ -10,10 +10,11 @@ import { UtilsAPI } from "./class-interfaces/utils"; import { NotificationsAPI } from "./class-interfaces/event-notifications"; import { FoodAPI } from "./class-interfaces/recipe-foods"; import { UnitAPI } from "./class-interfaces/recipe-units"; -import { CookbookAPI } from "./class-interfaces/cookbooks"; +import { CookbookAPI } from "./class-interfaces/group-cookbooks"; import { WebhooksAPI } from "./class-interfaces/group-webhooks"; import { AdminAboutAPI } from "./class-interfaces/admin-about"; import { RegisterAPI } from "./class-interfaces/user-registration"; +import { MealPlanAPI } from "./class-interfaces/group-mealplan"; import { ApiRequestInstance } from "~/types/api"; class AdminAPI { @@ -48,6 +49,7 @@ class Api { public cookbooks: CookbookAPI; public groupWebhooks: WebhooksAPI; public register: RegisterAPI; + public mealplans: MealPlanAPI; // Utils public upload: UploadFile; @@ -70,6 +72,7 @@ class Api { this.cookbooks = new CookbookAPI(requests); this.groupWebhooks = new WebhooksAPI(requests); this.register = new RegisterAPI(requests); + this.mealplans = new MealPlanAPI(requests); // Admin this.events = new EventsAPI(requests); diff --git a/frontend/components/Domain/Recipe/RecipeCard.vue b/frontend/components/Domain/Recipe/RecipeCard.vue index 9f76f2638b63..e1c0ebd0c8a5 100644 --- a/frontend/components/Domain/Recipe/RecipeCard.vue +++ b/frontend/components/Domain/Recipe/RecipeCard.vue @@ -30,6 +30,7 @@ + @@ -58,11 +59,13 @@ export default { }, rating: { type: Number, + required: false, default: 0, }, image: { type: String, - default: null, + required: false, + default: "abc123", }, route: { type: Boolean, diff --git a/frontend/components/Domain/Recipe/RecipeCardMobile.vue b/frontend/components/Domain/Recipe/RecipeCardMobile.vue index 23d9369258b0..fa99f6984434 100644 --- a/frontend/components/Domain/Recipe/RecipeCardMobile.vue +++ b/frontend/components/Domain/Recipe/RecipeCardMobile.vue @@ -9,36 +9,41 @@ @click="$emit('selected')" > - - - - {{ $globals.icons.primary }} - - + + + + + {{ $globals.icons.primary }} + + + {{ name }} {{ description }}
- - - - + + + + + +
+ diff --git a/frontend/components/Domain/Recipe/RecipeCategoryTagDialog.vue b/frontend/components/Domain/Recipe/RecipeCategoryTagDialog.vue index fd7dbaaaece2..0dd9e3ffa01b 100644 --- a/frontend/components/Domain/Recipe/RecipeCategoryTagDialog.vue +++ b/frontend/components/Domain/Recipe/RecipeCategoryTagDialog.vue @@ -35,7 +35,7 @@ - - \ No newline at end of file + + function forwardOneWeek() { + if (!state.today) return; + // @ts-ignore + state.today = addDays(state.today, +5); + } + + function backOneWeek() { + if (!state.today) return; + // @ts-ignore + state.today = addDays(state.today, -5); + } + + function onMoveCallback(evt: SortableEvent) { + // Adapted From https://github.com/SortableJS/Vue.Draggable/issues/1029 + const ogEvent: DragEvent = (evt as any).originalEvent; + + if (ogEvent && ogEvent.type !== "drop") { + // The drop was cancelled, unsure if anything needs to be done? + console.log("Cancel Move Event"); + } else { + // A Meal was moved, set the new date value and make a update request and refresh the meals + const fromMealsByIndex = evt.from.getAttribute("data-index"); + const toMealsByIndex = evt.to.getAttribute("data-index"); + + if (fromMealsByIndex) { + // @ts-ignore + const mealData = mealsByDate.value[fromMealsByIndex].meals[evt.oldIndex as number]; + // @ts-ignore + const destDate = mealsByDate.value[toMealsByIndex].date; + + mealData.date = format(destDate, "yyyy-MM-dd"); + + actions.updateOne(mealData); + } + } + } + + const mealsByDate = computed(() => { + return days.value.map((day) => { + return { date: day, meals: filterMealByDate(day as any) }; + }); + }); + + const weekRange = computed(() => { + // @ts-ignore - Not Sure Why This is not working + const end = addDays(state.today, 2); + // @ts-ignore - Not sure why the type is invalid + const start = subDays(state.today, 2); + return { start, end, today: state.today }; + }); + + const days = computed(() => { + if (weekRange.value?.start === null) return []; + return Array.from(Array(8).keys()).map( + // @ts-ignore + (i) => new Date(weekRange.value.start.getTime() + i * 24 * 60 * 60 * 1000) + ); + }); + + const newMeal = reactive({ + date: null, + title: "", + text: "", + recipeId: null, + }); + + return { + mealplans, + actions, + newMeal, + allRecipes, + ...toRefs(state), + mealsByDate, + onMoveCallback, + backOneWeek, + forwardOneWeek, + weekRange, + days, + }; + }, +}); + + \ No newline at end of file diff --git a/frontend/pages/meal-plan/this-week.vue b/frontend/pages/meal-plan/this-week.vue index bb6aebe3f129..411c8fc22c68 100644 --- a/frontend/pages/meal-plan/this-week.vue +++ b/frontend/pages/meal-plan/this-week.vue @@ -1,16 +1,16 @@ +
+ +import { defineComponent } from "@nuxtjs/composition-api"; + +export default defineComponent({ + setup() { + return {}; + }, +}); + \ No newline at end of file + \ No newline at end of file diff --git a/frontend/pages/search.vue b/frontend/pages/search.vue index 15cfa49e79d7..af6e74ef73c9 100644 --- a/frontend/pages/search.vue +++ b/frontend/pages/search.vue @@ -67,7 +67,7 @@