mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-11-03 18:53:17 -05:00 
			
		
		
		
	
		
			
	
	
		
			260 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
		
		
			
		
	
	
			260 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| 
								 | 
							
								<template>
							 | 
						||
| 
								 | 
							
								  <div :style="`width: ${width}; height: 100%;`">
							 | 
						||
| 
								 | 
							
								    <LanguageDialog v-model="langDialog" />
							 | 
						||
| 
								 | 
							
								    <v-card>
							 | 
						||
| 
								 | 
							
								      <div>
							 | 
						||
| 
								 | 
							
								        <v-toolbar width="100%" color="primary" class="d-flex justify-center" style="margin-bottom: 4rem" dark>
							 | 
						||
| 
								 | 
							
								          <v-toolbar-title class="headline text-h4"> Mealie </v-toolbar-title>
							 | 
						||
| 
								 | 
							
								        </v-toolbar>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        <div class="icon-container">
							 | 
						||
| 
								 | 
							
								          <v-divider class="icon-divider"></v-divider>
							 | 
						||
| 
								 | 
							
								          <v-avatar class="pa-2 icon-avatar" color="primary" size="75">
							 | 
						||
| 
								 | 
							
								            <svg class="icon-white" style="width: 75" viewBox="0 0 24 24">
							 | 
						||
| 
								 | 
							
								              <path
							 | 
						||
| 
								 | 
							
								                d="M8.1,13.34L3.91,9.16C2.35,7.59 2.35,5.06 3.91,3.5L10.93,10.5L8.1,13.34M13.41,13L20.29,19.88L18.88,21.29L12,14.41L5.12,21.29L3.71,19.88L13.36,10.22L13.16,10C12.38,9.23 12.38,7.97 13.16,7.19L17.5,2.82L18.43,3.74L15.19,7L16.15,7.94L19.39,4.69L20.31,5.61L17.06,8.85L18,9.81L21.26,6.56L22.18,7.5L17.81,11.84C17.03,12.62 15.77,12.62 15,11.84L14.78,11.64L13.41,13Z"
							 | 
						||
| 
								 | 
							
								              />
							 | 
						||
| 
								 | 
							
								            </svg>
							 | 
						||
| 
								 | 
							
								          </v-avatar>
							 | 
						||
| 
								 | 
							
								        </div>
							 | 
						||
| 
								 | 
							
								      </div>
							 | 
						||
| 
								 | 
							
								      <div class="d-flex justify-center grow items-center my-4">
							 | 
						||
| 
								 | 
							
								        <slot :width="pageWidth"></slot>
							 | 
						||
| 
								 | 
							
								      </div>
							 | 
						||
| 
								 | 
							
								      <div class="mx-2 my-4">
							 | 
						||
| 
								 | 
							
								        <v-progress-linear
							 | 
						||
| 
								 | 
							
								          v-if="value > 0"
							 | 
						||
| 
								 | 
							
								          :value="Math.ceil((value/maxPageNumber)*100)"
							 | 
						||
| 
								 | 
							
								          striped
							 | 
						||
| 
								 | 
							
								          height="10"
							 | 
						||
| 
								 | 
							
								        />
							 | 
						||
| 
								 | 
							
								      </div>
							 | 
						||
| 
								 | 
							
								      <v-divider class="ma-2" />
							 | 
						||
| 
								 | 
							
								      <v-card-actions width="100%">
							 | 
						||
| 
								 | 
							
								        <v-btn
							 | 
						||
| 
								 | 
							
								          v-if="prevButtonShow"
							 | 
						||
| 
								 | 
							
								          :disabled="!prevButtonEnable"
							 | 
						||
| 
								 | 
							
								          :color="prevButtonColor"
							 | 
						||
| 
								 | 
							
								          @click="decrementPage"
							 | 
						||
| 
								 | 
							
								        >
							 | 
						||
| 
								 | 
							
								          <v-icon v-if="prevButtonIconRef">
							 | 
						||
| 
								 | 
							
								            {{ prevButtonIconRef }}
							 | 
						||
| 
								 | 
							
								          </v-icon>
							 | 
						||
| 
								 | 
							
								          {{ prevButtonTextRef }}
							 | 
						||
| 
								 | 
							
								        </v-btn>
							 | 
						||
| 
								 | 
							
								        <v-spacer />
							 | 
						||
| 
								 | 
							
								        <v-btn
							 | 
						||
| 
								 | 
							
								          v-if="nextButtonShow"
							 | 
						||
| 
								 | 
							
								          :disabled="!nextButtonEnable"
							 | 
						||
| 
								 | 
							
								          :color="nextButtonColorRef"
							 | 
						||
| 
								 | 
							
								          @click="incrementPage"
							 | 
						||
| 
								 | 
							
								        >
							 | 
						||
| 
								 | 
							
								          <div v-if="isSubmitting">
							 | 
						||
| 
								 | 
							
								            <v-progress-circular indeterminate color="white" size="24" />
							 | 
						||
| 
								 | 
							
								          </div>
							 | 
						||
| 
								 | 
							
								          <div v-else>
							 | 
						||
| 
								 | 
							
								            <v-icon v-if="nextButtonIconRef && !nextButtonIconAfter">
							 | 
						||
| 
								 | 
							
								              {{ nextButtonIconRef }}
							 | 
						||
| 
								 | 
							
								            </v-icon>
							 | 
						||
| 
								 | 
							
								            {{ nextButtonTextRef }}
							 | 
						||
| 
								 | 
							
								            <v-icon v-if="nextButtonIconRef && nextButtonIconAfter">
							 | 
						||
| 
								 | 
							
								              {{ nextButtonIconRef }}
							 | 
						||
| 
								 | 
							
								            </v-icon>
							 | 
						||
| 
								 | 
							
								          </div>
							 | 
						||
| 
								 | 
							
								        </v-btn>
							 | 
						||
| 
								 | 
							
								      </v-card-actions>
							 | 
						||
| 
								 | 
							
								      <v-card-actions class="justify-center flex-column py-8">
							 | 
						||
| 
								 | 
							
								        <BaseButton large color="primary" @click="langDialog = true">
							 | 
						||
| 
								 | 
							
								          <template #icon> {{ $globals.icons.translate }}</template>
							 | 
						||
| 
								 | 
							
								          {{ $t("language-dialog.choose-language") }}
							 | 
						||
| 
								 | 
							
								        </BaseButton>
							 | 
						||
| 
								 | 
							
								      </v-card-actions>
							 | 
						||
| 
								 | 
							
								    </v-card>
							 | 
						||
| 
								 | 
							
								  </div>
							 | 
						||
| 
								 | 
							
								</template>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<script lang="ts">
							 | 
						||
| 
								 | 
							
								import { computed, defineComponent, ref, useContext } from "@nuxtjs/composition-api";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default defineComponent({
							 | 
						||
| 
								 | 
							
								  props: {
							 | 
						||
| 
								 | 
							
								    value: {
							 | 
						||
| 
								 | 
							
								      type: Number,
							 | 
						||
| 
								 | 
							
								      required: true,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    minPageNumber: {
							 | 
						||
| 
								 | 
							
								      type: Number,
							 | 
						||
| 
								 | 
							
								      default: 0,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    maxPageNumber: {
							 | 
						||
| 
								 | 
							
								      type: Number,
							 | 
						||
| 
								 | 
							
								      required: true,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    width: {
							 | 
						||
| 
								 | 
							
								      type: [String, Number],
							 | 
						||
| 
								 | 
							
								      default: "1200px",
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    pageWidth: {
							 | 
						||
| 
								 | 
							
								      type: [String, Number],
							 | 
						||
| 
								 | 
							
								      default: "600px",
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    prevButtonText: {
							 | 
						||
| 
								 | 
							
								      type: String,
							 | 
						||
| 
								 | 
							
								      default: undefined,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    prevButtonIcon: {
							 | 
						||
| 
								 | 
							
								      type: String,
							 | 
						||
| 
								 | 
							
								      default: null,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    prevButtonColor: {
							 | 
						||
| 
								 | 
							
								      type: String,
							 | 
						||
| 
								 | 
							
								      default: "grey-darken-3",
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    prevButtonShow: {
							 | 
						||
| 
								 | 
							
								      type: Boolean,
							 | 
						||
| 
								 | 
							
								      default: true,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    prevButtonEnable: {
							 | 
						||
| 
								 | 
							
								      type: Boolean,
							 | 
						||
| 
								 | 
							
								      default: true,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    nextButtonText: {
							 | 
						||
| 
								 | 
							
								      type: String,
							 | 
						||
| 
								 | 
							
								      default: undefined,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    nextButtonIcon: {
							 | 
						||
| 
								 | 
							
								      type: String,
							 | 
						||
| 
								 | 
							
								      default: null,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    nextButtonIconAfter: {
							 | 
						||
| 
								 | 
							
								      type: Boolean,
							 | 
						||
| 
								 | 
							
								      default: true,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    nextButtonColor: {
							 | 
						||
| 
								 | 
							
								      type: String,
							 | 
						||
| 
								 | 
							
								      default: undefined,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    nextButtonShow: {
							 | 
						||
| 
								 | 
							
								      type: Boolean,
							 | 
						||
| 
								 | 
							
								      default: true,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    nextButtonEnable: {
							 | 
						||
| 
								 | 
							
								      type: Boolean,
							 | 
						||
| 
								 | 
							
								      default: true,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    nextButtonIsSubmit: {
							 | 
						||
| 
								 | 
							
								      type: Boolean,
							 | 
						||
| 
								 | 
							
								      default: false,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    title: {
							 | 
						||
| 
								 | 
							
								      type: String,
							 | 
						||
| 
								 | 
							
								      required: true,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    icon: {
							 | 
						||
| 
								 | 
							
								      type: String,
							 | 
						||
| 
								 | 
							
								      default: null,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    isSubmitting: {
							 | 
						||
| 
								 | 
							
								      type: Boolean,
							 | 
						||
| 
								 | 
							
								      default: false,
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  setup(props, context) {
							 | 
						||
| 
								 | 
							
								    const { $globals, i18n } = useContext();
							 | 
						||
| 
								 | 
							
								    const ready = ref(false);
							 | 
						||
| 
								 | 
							
								    const langDialog = ref(false);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const prevButtonTextRef = computed(() => props.prevButtonText || i18n.tc("general.back"));
							 | 
						||
| 
								 | 
							
								    const prevButtonIconRef = computed(() => props.prevButtonIcon || $globals.icons.back);
							 | 
						||
| 
								 | 
							
								    const nextButtonTextRef = computed(
							 | 
						||
| 
								 | 
							
								      () => props.nextButtonText || (
							 | 
						||
| 
								 | 
							
								          props.nextButtonIsSubmit ? i18n.tc("general.submit") : i18n.tc("general.next")
							 | 
						||
| 
								 | 
							
								        )
							 | 
						||
| 
								 | 
							
								      );
							 | 
						||
| 
								 | 
							
								    const nextButtonIconRef = computed(
							 | 
						||
| 
								 | 
							
								      () => props.nextButtonIcon || (
							 | 
						||
| 
								 | 
							
								          props.nextButtonIsSubmit ? $globals.icons.createAlt : $globals.icons.forward
							 | 
						||
| 
								 | 
							
								      )
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								    const nextButtonColorRef = computed(
							 | 
						||
| 
								 | 
							
								      () => props.nextButtonColor || (props.nextButtonIsSubmit ? "success" : "info")
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function goToPage(page: number) {
							 | 
						||
| 
								 | 
							
								      if (page < props.minPageNumber) {
							 | 
						||
| 
								 | 
							
								        goToPage(props.minPageNumber);
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								      } else if (page > props.maxPageNumber) {
							 | 
						||
| 
								 | 
							
								        goToPage(props.maxPageNumber);
							 | 
						||
| 
								 | 
							
								        return;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      context.emit("input", page);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function decrementPage() {
							 | 
						||
| 
								 | 
							
								      goToPage(props.value - 1);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function incrementPage() {
							 | 
						||
| 
								 | 
							
								      if (props.nextButtonIsSubmit) {
							 | 
						||
| 
								 | 
							
								        context.emit("submit", props.value);
							 | 
						||
| 
								 | 
							
								      } else {
							 | 
						||
| 
								 | 
							
								        goToPage(props.value + 1);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ready.value = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								      ready,
							 | 
						||
| 
								 | 
							
								      langDialog,
							 | 
						||
| 
								 | 
							
								      prevButtonTextRef,
							 | 
						||
| 
								 | 
							
								      prevButtonIconRef,
							 | 
						||
| 
								 | 
							
								      nextButtonTextRef,
							 | 
						||
| 
								 | 
							
								      nextButtonIconRef,
							 | 
						||
| 
								 | 
							
								      nextButtonColorRef,
							 | 
						||
| 
								 | 
							
								      decrementPage,
							 | 
						||
| 
								 | 
							
								      incrementPage,
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								</script>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<style lang="css" scoped>
							 | 
						||
| 
								 | 
							
								.icon-primary {
							 | 
						||
| 
								 | 
							
								  fill: var(--v-primary-base);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.icon-white {
							 | 
						||
| 
								 | 
							
								  fill: white;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.icon-container {
							 | 
						||
| 
								 | 
							
								  display: flex;
							 | 
						||
| 
								 | 
							
								  flex-direction: column;
							 | 
						||
| 
								 | 
							
								  align-items: center;
							 | 
						||
| 
								 | 
							
								  width: 100%;
							 | 
						||
| 
								 | 
							
								  position: relative;
							 | 
						||
| 
								 | 
							
								  margin-top: 2.5rem;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.icon-divider {
							 | 
						||
| 
								 | 
							
								  width: 100%;
							 | 
						||
| 
								 | 
							
								  margin-bottom: -2.5rem;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.icon-avatar {
							 | 
						||
| 
								 | 
							
								  border-color: rgba(0, 0, 0, 0.12);
							 | 
						||
| 
								 | 
							
								  border: 2px;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.bg-off-white {
							 | 
						||
| 
								 | 
							
								  background: #f5f8fa;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								.preferred-width {
							 | 
						||
| 
								 | 
							
								  width: 840px;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								</style>
							 |