enrecipes/app/components/MealPlanner.vue

372 lines
14 KiB
Vue
Raw Normal View History

2020-11-15 21:13:06 +00:00
<template>
2021-01-13 05:02:48 +00:00
<Page @loaded="onPageLoad" @unloaded="onPageUnload">
<ActionBar flat="true">
<GridLayout rows="*" columns="auto, *, auto">
<MDButton class="bx left" variant="text" :text="icon.menu" automationText="Back" @tap="showDrawer" col="0" />
2021-01-13 05:02:48 +00:00
<Label class="title orkm" :text="'planner' | L" col="1" />
<MDButton class="bx left" variant="text" :text="icon.today" automationText="today" @tap="goToToday" col="2" />
2020-11-23 09:49:58 +00:00
</GridLayout>
</ActionBar>
<GridLayout rows="280, *">
<RadCalendar :androidElevation="viewIsScrolled ? 4 : 0" class="orkm" row="0" ref="calendar" @loaded="onCalendarLoad" @dateSelected="onDateSelected" :viewMode="viewMode" :transitionMode="transitionMode" :selectionMode="selectionMode"
:eventsViewMode="eventsViewMode" :eventSource="getMealPlans"></RadCalendar>
<ScrollView row="1" width="100%" height="100%" @scroll="onScroll">
<StackLayout class="dayPlan">
<StackLayout v-for="(mealType, index) in mealTimes" :key="'mealType' + index" class="plansContainer" :class="mealType">
2021-01-13 05:02:48 +00:00
<GridLayout columns="auto, auto" class="header">
<Label col="0" class="periodLabel orkm" :text="mealType | L" />
2020-12-29 10:35:19 +00:00
<MDButton col="1" variant="text" class="bx" :text="icon.plus" @tap="addRecipe(mealType)" />
</GridLayout>
2021-01-13 05:02:48 +00:00
<GridLayout class="recipe" :paddingTop="index == 0?8:0" columns="*, auto" v-for="(recipeID, index) in getRecipes[mealType]" :key="mealType + index">
<GridLayout androidElevation="1" col="0" columns="*" class="titleContainer">
<MDRipple class="recipeRipple" @tap="viewRecipe(recipeID)" />
<Label verticalAlignment="center" class="recipeTitle" :text="getRecipeTitle(recipeID)" textWrap="true" />
</GridLayout>
<MDButton variant="text" col="1" class="bx closeBtn" :text="icon.close" @tap="removeRecipe(mealType, recipeID)" />
</GridLayout>
</StackLayout>
</StackLayout>
</ScrollView>
</GridLayout>
</Page>
2020-11-15 21:13:06 +00:00
</template>
<script>
import {
ApplicationSettings,
Color,
Page,
Observable,
Device
}
from "@nativescript/core"
2020-11-23 09:49:58 +00:00
import {
CalendarViewMode,
CalendarTransitionMode,
CalendarSelectionMode,
CalendarMonthViewStyle,
CalendarSelectionShape,
DayCellStyle,
CalendarFontStyle,
CalendarCellAlignment,
CellStyle,
CalendarEventsViewMode,
CalendarEvent
}
from "nativescript-ui-calendar"
2021-01-13 05:02:48 +00:00
import {
SnackBar
} from '@nativescript-community/ui-material-snackbar';
const snackbar = new SnackBar();
import {
mapState,
mapActions
}
from "vuex"
import ViewRecipe from "./ViewRecipe.vue"
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue"
import ConfirmDialog from "./modal/ConfirmDialog.vue"
2020-11-23 09:49:58 +00:00
import * as utils from "~/shared/utils"
2020-11-15 21:13:06 +00:00
export default {
data() {
return {
viewIsScrolled: false,
appTheme: "Light",
mealTimes: [ "breakfast", "lunch", "dinner", "snacks" ],
2020-11-23 09:49:58 +00:00
selectedDayMealPlans: [],
viewMode: CalendarViewMode.Month,
transitionMode: CalendarTransitionMode.Slide,
selectionMode: CalendarSelectionMode.Single,
eventsViewMode: CalendarEventsViewMode.None,
color: {
white: new Color( "#ffffff" ),
gray1: new Color( "#f1f3f5" ),
gray2: new Color( "#e9ecef" ),
gray3: new Color( "#dee2e6" ),
gray4: new Color( "#ced4da" ),
gray5: new Color( "#adb5bd" ),
gray6: new Color( "#868e96" ),
gray7: new Color( "#495057" ),
gray8: new Color( "#343a40" ),
gray9: new Color( "#212529" ),
black: new Color( "#111111" ),
orange: new Color( "#ff5200" ),
2020-12-29 10:35:19 +00:00
breakfast: "#ff922b",
lunch: "#94d82d",
dinner: "#339af0",
snacks: "#845ef7",
2020-11-23 09:49:58 +00:00
},
appFontRegular: "Orkney-Regular",
appFontMedium: "Orkney-Medium",
selectedDate: null,
2020-11-15 21:13:06 +00:00
}
},
computed: {
...mapState( [ "icon", "recipes", "mealPlans" ] ),
2020-11-23 09:49:58 +00:00
isLightMode() {
return this.appTheme === "Light"
},
monthViewStyle() {
const monthViewStyle = new CalendarMonthViewStyle()
2020-12-29 10:35:19 +00:00
monthViewStyle.backgroundColor = this.isLightMode ? this.color.gray1 : this.color.gray9
2020-11-23 09:49:58 +00:00
monthViewStyle.showTitle = true
monthViewStyle.showWeekNumbers = false
monthViewStyle.showDayNames = true
const titleCellStyle = new DayCellStyle()
2020-12-29 10:35:19 +00:00
titleCellStyle.cellBackgroundColor = this.isLightMode ? this.color.gray2 : this.color.black
2020-11-23 09:49:58 +00:00
titleCellStyle.cellBorderWidth = 1
2020-12-29 10:35:19 +00:00
titleCellStyle.cellBorderColor = this.isLightMode ? this.color.gray2 : this.color.black
2020-11-23 09:49:58 +00:00
titleCellStyle.cellTextSize = 16
2020-12-29 10:35:19 +00:00
titleCellStyle.cellTextColor = this.isLightMode ? this.color.gray9 : this.color.gray1
2020-11-23 09:49:58 +00:00
titleCellStyle.cellTextFontName = this.appFontMedium
monthViewStyle.titleCellStyle = titleCellStyle
const dayNameCellStyle = new CellStyle()
2020-12-29 10:35:19 +00:00
dayNameCellStyle.cellBackgroundColor = this.isLightMode ? this.color.gray2 : this.color.black
dayNameCellStyle.cellTextColor = this.isLightMode ? this.color.gray9 : this.color.gray1
2020-11-23 09:49:58 +00:00
dayNameCellStyle.cellBorderWidth = 1
2020-12-29 10:35:19 +00:00
dayNameCellStyle.cellBorderColor = this.isLightMode ? this.color.gray2 : this.color.black
2020-11-28 19:21:57 +00:00
dayNameCellStyle.cellTextSize = 10
2020-11-23 09:49:58 +00:00
dayNameCellStyle.cellAlignment = CalendarCellAlignment.Center
dayNameCellStyle.cellTextFontName = this.appFontMedium
monthViewStyle.dayNameCellStyle = dayNameCellStyle
const dayCellStyle = new DayCellStyle()
dayCellStyle.showEventsText = false
dayCellStyle.eventTextColor = this.color.orange
dayCellStyle.eventFontName = this.appFontRegular
dayCellStyle.eventFontStyle = CalendarFontStyle.Bold
dayCellStyle.eventTextSize = 8
dayCellStyle.cellTextSize = 16
2020-12-29 10:35:19 +00:00
dayCellStyle.cellTextColor = this.isLightMode ? this.color.gray9 : this.color.gray1
2020-11-23 09:49:58 +00:00
dayCellStyle.cellAlignment = CalendarCellAlignment.Bottom
2020-12-29 10:35:19 +00:00
dayCellStyle.cellBackgroundColor = this.isLightMode ? this.color.gray1 : this.color.gray9
2020-11-23 09:49:58 +00:00
dayCellStyle.cellTextFontName = this.appFontRegular
dayCellStyle.cellBorderWidth = 1
2020-12-29 10:35:19 +00:00
dayCellStyle.cellBorderColor = this.isLightMode ? this.color.gray2 : this.color.black
2020-11-23 09:49:58 +00:00
monthViewStyle.dayCellStyle = dayCellStyle
const todayCellStyle = new DayCellStyle()
2020-12-29 10:35:19 +00:00
todayCellStyle.cellBackgroundColor = this.isLightMode ? this.color.gray1 : this.color.gray9
2020-11-23 09:49:58 +00:00
todayCellStyle.cellTextColor = this.color.orange
todayCellStyle.cellBorderWidth = 1
todayCellStyle.cellTextFontName = this.appFontMedium
todayCellStyle.cellTextFontStyle = CalendarFontStyle.Bold
todayCellStyle.cellTextSize = 16
todayCellStyle.cellAlignment = CalendarCellAlignment.Bottom
2020-12-29 10:35:19 +00:00
todayCellStyle.cellBorderColor = this.isLightMode ? this.color.gray2 : this.color.black
2020-11-23 09:49:58 +00:00
monthViewStyle.todayCellStyle = todayCellStyle
const selectedCellStyle = new DayCellStyle()
selectedCellStyle.eventTextSize = 1
selectedCellStyle.cellAlignment = CalendarCellAlignment.Bottom
2020-12-29 10:35:19 +00:00
selectedCellStyle.cellBackgroundColor = this.isLightMode ? this.color.white : this.color.gray8
2020-11-23 09:49:58 +00:00
selectedCellStyle.cellBorderWidth = 1
selectedCellStyle.cellBorderColor = this.color.orange
2020-12-29 10:35:19 +00:00
selectedCellStyle.cellTextColor = this.isLightMode ? this.color.gray9 : this.color.gray1
2020-11-23 09:49:58 +00:00
selectedCellStyle.cellTextFontName = this.appFontMedium
selectedCellStyle.cellTextFontStyle = CalendarFontStyle.Bold
selectedCellStyle.cellTextSize = 16
monthViewStyle.selectedDayCellStyle = selectedCellStyle
return monthViewStyle
},
getRecipes() {
if ( this.selectedDayMealPlans.length ) {
return this.selectedDayMealPlans.reduce( ( acc, e ) => {
switch ( e.startDate.getHours() ) {
2020-11-23 09:49:58 +00:00
case 0: //breakfast
acc[ "breakfast" ] = [ ...( acc[ "breakfast" ] || [] ), e.title ]
2020-11-23 09:49:58 +00:00
break
case 5: //lunch
acc[ "lunch" ] = [ ...( acc[ "lunch" ] || [] ), e.title ]
2020-11-23 09:49:58 +00:00
break
case 10: //dinner
acc[ "dinner" ] = [ ...( acc[ "dinner" ] || [] ), e.title ]
2020-11-23 09:49:58 +00:00
break
case 15: //snacks
acc[ "snacks" ] = [ ...( acc[ "snacks" ] || [] ), e.title ]
2020-11-23 09:49:58 +00:00
break
default:
break
}
return acc
}, {} )
2020-12-29 10:35:19 +00:00
} else return 0
2020-11-23 09:49:58 +00:00
},
getMealPlans() {
const getDate = ( date ) => {
let d = new Date( date )
2020-12-29 10:35:19 +00:00
let result = new Date( d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() )
2020-11-23 09:49:58 +00:00
return result
}
let events = []
this.mealPlans.forEach( ( plan ) => {
2020-12-29 10:35:19 +00:00
let e = new CalendarEvent( plan.title, getDate( plan.startDate ), getDate( plan.endDate ), false, new Color( plan.eventColor ) )
events = [ ...events, e ]
} )
2020-11-23 09:49:58 +00:00
return events
},
2020-11-15 21:13:06 +00:00
},
methods: {
2020-12-29 10:35:19 +00:00
...mapActions( [ "setCurrentComponentAction", "initializeMealPlans", "addMealPlanAction", "deleteMealPlanAction", ] ),
onPageLoad( args ) {
const page = args.object;
page.bindingContext = new Observable();
this.setCurrentComponentAction( "MealPlanner" )
2020-11-23 09:49:58 +00:00
},
2021-01-13 05:02:48 +00:00
onPageUnload(args){
snackbar.dismiss()
},
onCalendarLoad( args ) {
args.object.locale = `${Device.language}-${Device.language.toUpperCase()}`
2020-11-23 09:49:58 +00:00
args.object.monthViewStyle = this.monthViewStyle
2020-12-29 10:35:19 +00:00
args.object.android.getGestureManager().setDoubleTapToChangeDisplayMode( false )
args.object.android.getGestureManager().setPinchCloseToChangeDisplayMode( false )
if ( args.object.selectedDate == null ) args.object.selectedDate = new Date()
if ( args.object.nativeView.getEventAdapter() ) {
2020-12-29 10:35:19 +00:00
args.object.nativeView.getEventAdapter().getRenderer().setEventRenderMode( com.telerik.widget.calendar.events.EventRenderMode.Shape )
2020-11-23 09:49:58 +00:00
}
2020-11-15 21:13:06 +00:00
},
// HELPERS
2020-11-23 09:49:58 +00:00
showDrawer() {
utils.showDrawer()
},
onScroll( args ) {
2020-11-28 19:21:57 +00:00
this.viewIsScrolled = args.scrollY ? true : false
2020-11-15 21:13:06 +00:00
},
getDate( index ) {
let date = new Date()
date.setDate( date.getDate() + index )
return date.getTime()
},
getDateString( days ) {
let date = new Date()
date.setDate( date.getDate() + days )
return date.toDateString().slice( 0, -5 )
},
getRecipeTitle( id ) {
let recipe = this.recipes.filter( ( e ) => e.id === id )[ 0 ]
2021-01-13 05:02:48 +00:00
return recipe ? recipe.title : `[ ${this.$options.filters.L('resNF')} ]`
},
// NAVIGATION HANDLERS
viewRecipe( recipeID ) {
let recipe = this.recipes.filter( ( e ) => e.id === recipeID )[ 0 ]
if ( recipe ) {
this.$navigateTo( ViewRecipe, {
2020-11-23 09:49:58 +00:00
props: {
filterTrylater: true,
recipeID,
},
2020-11-28 20:09:09 +00:00
backstackVisible: false,
} )
2020-11-23 09:49:58 +00:00
}
},
// DATA HANDLERS
addRecipe( mealType ) {
2020-12-29 10:35:19 +00:00
let filteredRecipes = this.recipes.filter( ( e ) => this.getRecipes[ mealType ] ? !this.getRecipes[ mealType ].includes( e.id ) : true )
this.$showModal( ActionDialogWithSearch, {
props: {
2021-01-13 05:02:48 +00:00
title: "selRec",
recipes: filteredRecipes,
2021-01-13 05:02:48 +00:00
helpIcon: "calendar",
},
} ).then( ( recipeID ) => {
2021-01-13 05:02:48 +00:00
recipeID && this.newEvent( recipeID, mealType, null )
} )
},
2021-01-13 05:02:48 +00:00
undoRemove( message ) {
return snackbar
.action( {
message,
textColor: this.appTheme == "Light" ? "#f1f3f5" : "#212529",
actionTextColor: '#ff5200',
backgroundColor: this.appTheme == "Light" ? "#212529" : "#f1f3f5",
actionText: 'Undo',
hideDelay: 5000
} )
},
removeRecipe( mealType, recipeID ) {
2020-11-23 09:49:58 +00:00
let startHour = {
breakfast: 0,
lunch: 5,
dinner: 10,
snacks: 15,
}
2021-01-13 05:02:48 +00:00
let actualMealPlan = this.selectedDayMealPlans.filter(
( e ) => e.startDate.getHours() === startHour[ mealType ] && e.title === recipeID )[ 0 ]
let mealPlan = {
title: actualMealPlan.title,
startDate: actualMealPlan.startDate,
}
let index = this.mealPlans.findIndex( e =>
e.title === mealPlan.title && new Date( e.startDate ).getTime() === new Date( mealPlan.startDate ).getTime() )
this.deleteMealPlanAction( mealPlan )
this.updateSelectedDatePlans()
this.undoRemove( `${this.$options.filters.L('recRm')}` ).then( res => {
if ( res.command === 'action' ) {
this.newEvent( recipeID, mealType, index )
2020-11-23 09:49:58 +00:00
}
} )
},
// CALENDAR
2020-11-23 09:49:58 +00:00
updateSelectedDatePlans() {
let date = new Date( this.selectedDate )
setTimeout( () => {
2020-12-29 10:35:19 +00:00
this.selectedDayMealPlans = this.$refs.calendar.nativeView.getEventsForDate( date )
}, 100 )
2020-11-23 09:49:58 +00:00
},
onDateSelected( args ) {
2020-11-23 09:49:58 +00:00
this.selectedDate = args.date
this.selectedDayMealPlans = args.object.getEventsForDate( args.date )
2020-11-23 09:49:58 +00:00
},
2021-01-13 05:02:48 +00:00
newEvent( recipeID, mealType, index ) {
let date = new Date( this.selectedDate )
2020-11-23 09:49:58 +00:00
const selectedDate = () => {
return {
y: date.getFullYear(),
m: date.getMonth(),
d: date.getDate(),
}
}
let {
y,
m,
d
} = selectedDate()
2020-11-23 09:49:58 +00:00
let mealTime = {
breakfast: {
start: new Date( y, m, d, 0 ),
end: new Date( y, m, d, 4 ),
2020-11-23 09:49:58 +00:00
},
lunch: {
start: new Date( y, m, d, 5 ),
end: new Date( y, m, d, 9 ),
2020-11-23 09:49:58 +00:00
},
dinner: {
start: new Date( y, m, d, 10 ),
end: new Date( y, m, d, 14 ),
2020-11-23 09:49:58 +00:00
},
snacks: {
start: new Date( y, m, d, 15 ),
end: new Date( y, m, d, 19 ),
2020-11-23 09:49:58 +00:00
},
}
2020-12-29 10:35:19 +00:00
let event = new CalendarEvent( recipeID, mealTime[ mealType ].start, mealTime[ mealType ].end, false, new Color( this.color[ mealType ] ) )
this.addMealPlanAction( {
event,
2021-01-13 05:02:48 +00:00
eventColor: this.color[ mealType ],
index
} )
2020-11-23 09:49:58 +00:00
this.updateSelectedDatePlans()
},
goToToday() {
const date = new Date()
this.$refs.calendar.goToDate( date )
2020-11-23 09:49:58 +00:00
this.$refs.calendar.nativeView.selectedDate = date
},
2020-11-15 21:13:06 +00:00
},
created() {
this.appTheme = ApplicationSettings.getString( "appTheme", "Light" )
2020-11-23 09:49:58 +00:00
let d = new Date()
d.setHours( 0, 0, 0 )
2020-11-23 09:49:58 +00:00
this.selectedDate = d
2020-11-15 21:13:06 +00:00
},
}
</script>