mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-28 17:49:40 +02:00
init 2
This commit is contained in:
commit
beed8576c2
137 changed files with 40218 additions and 0 deletions
48
frontend/src/components/UI/ButtonRow.vue
Normal file
48
frontend/src/components/UI/ButtonRow.vue
Normal file
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<v-toolbar class="card-btn" flat height="0" extension-height="0">
|
||||
<template v-slot:extension>
|
||||
<v-col></v-col>
|
||||
<div v-if="open">
|
||||
<v-btn class="mr-2" fab dark small color="error" @click="deleteRecipe">
|
||||
<v-icon>mdi-delete</v-icon>
|
||||
</v-btn>
|
||||
<v-btn class="mr-2" fab dark small color="success" @click="save">
|
||||
<v-icon>mdi-content-save</v-icon>
|
||||
</v-btn>
|
||||
<v-btn class="mr-5" fab dark small color="accent" @click="json">
|
||||
<v-icon>mdi-code-braces</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
<v-btn color="secondary" fab dark small @click="editor">
|
||||
<v-icon>mdi-square-edit-outline</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-toolbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
open: {
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
editor() {
|
||||
this.$emit("editor");
|
||||
},
|
||||
save() {
|
||||
this.$emit("save");
|
||||
},
|
||||
deleteRecipe() {
|
||||
this.$emit("delete");
|
||||
},
|
||||
json() {
|
||||
this.$emit("json");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
99
frontend/src/components/UI/Login.vue
Normal file
99
frontend/src/components/UI/Login.vue
Normal file
|
@ -0,0 +1,99 @@
|
|||
<template>
|
||||
<div class="text-center">
|
||||
<v-btn icon @click="showLogin = true">
|
||||
<v-icon>mdi-account</v-icon>
|
||||
</v-btn>
|
||||
<v-dialog v-model="showLogin" width="500">
|
||||
<v-flex class="login-form text-xs-center">
|
||||
<v-card>
|
||||
<v-card-text>
|
||||
<v-form>
|
||||
<v-text-field
|
||||
v-if="!options.isLoggingIn"
|
||||
v-model="user.name"
|
||||
light="light"
|
||||
prepend-icon="person"
|
||||
label="Name"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
v-model="user.email"
|
||||
light="light"
|
||||
prepend-icon="mdi-email"
|
||||
label="Email"
|
||||
type="email"
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
v-model="user.password"
|
||||
light="light"
|
||||
prepend-icon="mdi-lock"
|
||||
label="Password"
|
||||
type="password"
|
||||
></v-text-field>
|
||||
<v-checkbox
|
||||
class="mb-2 mt-0"
|
||||
v-if="options.isLoggingIn"
|
||||
v-model="options.shouldStayLoggedIn"
|
||||
light="light"
|
||||
label="Stay logged in?"
|
||||
hide-details="hide-details"
|
||||
></v-checkbox>
|
||||
<v-btn
|
||||
v-if="options.isLoggingIn"
|
||||
@click.prevent="login"
|
||||
dark
|
||||
color="primary"
|
||||
block="block"
|
||||
type="submit"
|
||||
>Sign in</v-btn
|
||||
>
|
||||
<v-btn
|
||||
v-else
|
||||
block="block"
|
||||
type="submit"
|
||||
@click.prevent="options.isLoggingIn = true"
|
||||
>Sign up</v-btn
|
||||
>
|
||||
</v-form>
|
||||
</v-card-text>
|
||||
<!-- <v-card-actions v-if="options.isLoggingIn" class="card-actions">
|
||||
Don't have an account?
|
||||
<v-btn
|
||||
color="primary"
|
||||
light="light"
|
||||
@click="options.isLoggingIn = false"
|
||||
>
|
||||
Sign up
|
||||
</v-btn>
|
||||
</v-card-actions> -->
|
||||
</v-card>
|
||||
</v-flex>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import api from "../../api";
|
||||
export default {
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
showLogin: false,
|
||||
user: {
|
||||
email: "",
|
||||
password: "",
|
||||
},
|
||||
options: {
|
||||
isLoggingIn: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async login() {
|
||||
let key = await api.login(this.user.email, this.user.password);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
66
frontend/src/components/UI/Menu.vue
Normal file
66
frontend/src/components/UI/Menu.vue
Normal file
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<div class="text-center">
|
||||
<v-menu
|
||||
transition="slide-x-transition"
|
||||
bottom
|
||||
right
|
||||
offset-y
|
||||
open-on-hover
|
||||
close-delay="200"
|
||||
>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn v-bind="attrs" v-on="on" icon>
|
||||
<v-icon>mdi-menu</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<v-list>
|
||||
<v-list-item v-for="(item, i) in items" :key="i" link>
|
||||
<v-list-item-icon @click="navRouter(item.nav)">
|
||||
<v-icon>{{ item.icon }}</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content @click="navRouter(item.nav)">
|
||||
<v-list-item-title>
|
||||
{{ item.title }}
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: () => ({
|
||||
items: [
|
||||
{
|
||||
icon: "mdi-calendar-week",
|
||||
title: "Dinner This Week",
|
||||
nav: "/meal-plan/this-week",
|
||||
},
|
||||
{
|
||||
icon: "mdi-calendar-today",
|
||||
title: "Dinner Today",
|
||||
nav: "/meal-plan/today",
|
||||
},
|
||||
{
|
||||
icon: "mdi-calendar-multiselect",
|
||||
title: "Planner",
|
||||
nav: "/meal-plan/planner",
|
||||
},
|
||||
{ icon: "mdi-cog", title: "Settings", nav: "/settings/site" },
|
||||
],
|
||||
}),
|
||||
methods: {
|
||||
navRouter(route) {
|
||||
this.$router.push(route);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.menu-text {
|
||||
text-align: left !important;
|
||||
}
|
||||
</style>
|
63
frontend/src/components/UI/RecipeCard.vue
Normal file
63
frontend/src/components/UI/RecipeCard.vue
Normal file
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<v-hover v-slot="{ hover }" :open-delay="50">
|
||||
<v-card
|
||||
:class="{ 'on-hover': hover }"
|
||||
:elevation="hover ? 12 : 2"
|
||||
@click="moreInfo(slug)"
|
||||
>
|
||||
<v-img height="200" :src="getImage(image)"></v-img>
|
||||
<v-card-title class="my-n3 mb-n6">{{ name | truncate(30) }}</v-card-title>
|
||||
|
||||
<v-card-actions class="">
|
||||
<v-row dense align="center">
|
||||
<v-col>
|
||||
<v-rating
|
||||
class="mr-2"
|
||||
color="accent"
|
||||
background-color="accent lighten-3"
|
||||
dense
|
||||
length="5"
|
||||
size="15"
|
||||
:value="rating"
|
||||
></v-rating>
|
||||
</v-col>
|
||||
<v-col></v-col>
|
||||
<v-col align="end">
|
||||
<v-tooltip top color="secondary" max-width="400" open-delay="50">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn color="secondary" v-on="on" v-bind="attrs" text
|
||||
>Description</v-btn
|
||||
>
|
||||
</template>
|
||||
<span>{{ description }}</span>
|
||||
</v-tooltip>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-hover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import utils from "../../utils";
|
||||
export default {
|
||||
props: {
|
||||
name: String,
|
||||
slug: String,
|
||||
description: String,
|
||||
rating: Number,
|
||||
image: String,
|
||||
},
|
||||
methods: {
|
||||
moreInfo(recipeSlug) {
|
||||
this.$router.push(`/recipe/${recipeSlug}`);
|
||||
},
|
||||
getImage(image) {
|
||||
return utils.getImageURL(image);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
65
frontend/src/components/UI/Search.vue
Normal file
65
frontend/src/components/UI/Search.vue
Normal file
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<v-autocomplete
|
||||
:items="items"
|
||||
:loading="isLoading"
|
||||
v-model="selected"
|
||||
clearable
|
||||
return
|
||||
dense
|
||||
hide-details
|
||||
hide-selected
|
||||
item-text="slug"
|
||||
label="Search for a Recipe"
|
||||
single-line
|
||||
@keyup.enter.native="moreInfo(selected)"
|
||||
>
|
||||
<template v-slot:no-data>
|
||||
<v-list-item>
|
||||
<v-list-item-title>
|
||||
Search for your Favorite
|
||||
<strong>Recipe</strong>
|
||||
</v-list-item-title>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<template v-slot:item="{ item }">
|
||||
<v-list-item-avatar
|
||||
color="primary"
|
||||
class="headline font-weight-light white--text"
|
||||
>
|
||||
<v-img :src="getImage(item.image)"></v-img>
|
||||
</v-list-item-avatar>
|
||||
<v-list-item-content @click="moreInfo(item.slug)">
|
||||
<v-list-item-title v-text="item.name"></v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</template>
|
||||
</v-autocomplete>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import utils from "../../utils";
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
selected: null,
|
||||
isLoading: false,
|
||||
}),
|
||||
|
||||
computed: {
|
||||
items() {
|
||||
return this.$store.getters.getRecentRecipes;
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
moreInfo(recipeSlug) {
|
||||
this.$router.push(`/recipe/${recipeSlug}`);
|
||||
},
|
||||
getImage(image) {
|
||||
return utils.getImageURL(image);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
27
frontend/src/components/UI/SearchHeader.vue
Normal file
27
frontend/src/components/UI/SearchHeader.vue
Normal file
|
@ -0,0 +1,27 @@
|
|||
<template>
|
||||
<v-row>
|
||||
<v-col cols="2"> </v-col>
|
||||
<v-col>
|
||||
<v-expand-transition>
|
||||
<Search class="search-bar" />
|
||||
</v-expand-transition>
|
||||
</v-col>
|
||||
<v-col cols="2">
|
||||
<v-btn icon>
|
||||
<v-icon> mdi-filter </v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Search from "./Search";
|
||||
export default {
|
||||
components: {
|
||||
Search,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
41
frontend/src/components/UI/SnackBar.vue
Normal file
41
frontend/src/components/UI/SnackBar.vue
Normal file
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<div class="text-center">
|
||||
<v-snackbar :value="active" :timeout="timeout" :color="type">
|
||||
{{ text }}
|
||||
|
||||
<template v-slot:action="{ attrs }">
|
||||
<v-btn color="white" text v-bind="attrs" @click="close(false)">
|
||||
Close
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-snackbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: () => ({
|
||||
snackbar: false,
|
||||
timeout: -1,
|
||||
}),
|
||||
computed: {
|
||||
text() {
|
||||
return this.$store.getters.getSnackText;
|
||||
},
|
||||
active() {
|
||||
return this.$store.getters.getSnackActive;
|
||||
},
|
||||
type() {
|
||||
return this.$store.getters.getSnackType;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
close(value) {
|
||||
this.$store.commit("setSnackActive", value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
Loading…
Add table
Add a link
Reference in a new issue