mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-08-04 21:15:22 +02:00
feat: ✨ (WIP) base-shoppinglist infra (#911)
* feat: ✨ base-shoppinglist infra (WIP) * add type checker * implement controllers * apply router fixes * add checked section hide/animation * add label support * formatting * fix overflow images * add experimental banner * fix #912 word break issue * remove any type errors * bump dependencies * remove templates * fix build errors * bump node version * fix template literal
This commit is contained in:
parent
86c99b10a2
commit
6db1357064
66 changed files with 3455 additions and 1311 deletions
102
frontend/pages/shopping-lists/index.vue
Normal file
102
frontend/pages/shopping-lists/index.vue
Normal file
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<v-container v-if="shoppingLists" class="narrow-container">
|
||||
<BaseDialog v-model="createDialog" :title="$t('shopping-list.create-shopping-list')" @submit="createOne">
|
||||
<v-card-text>
|
||||
<v-text-field v-model="createName" autofocus :label="$t('shopping-list.new-list')"> </v-text-field>
|
||||
</v-card-text>
|
||||
</BaseDialog>
|
||||
|
||||
<BaseDialog v-model="deleteDialog" :title="$t('general.confirm')" color="error" @confirm="deleteOne">
|
||||
<v-card-text> Are you sure you want to delete this item?</v-card-text>
|
||||
</BaseDialog>
|
||||
<BasePageTitle divider>
|
||||
<template #header>
|
||||
<v-img max-height="100" max-width="100" :src="require('~/static/svgs/shopping-cart.svg')"></v-img>
|
||||
</template>
|
||||
<template #title> Shopping Lists </template>
|
||||
</BasePageTitle>
|
||||
<BaseButton create @click="createDialog = true" />
|
||||
|
||||
<section>
|
||||
<v-card v-for="list in shoppingLists" :key="list.id" class="my-2 left-border" :to="`/shopping-lists/${list.id}`">
|
||||
<v-card-title>
|
||||
<v-icon left>
|
||||
{{ $globals.icons.cartCheck }}
|
||||
</v-icon>
|
||||
{{ list.name }}
|
||||
<v-btn class="ml-auto" icon @click.prevent="openDelete(list.id)">
|
||||
<v-icon>
|
||||
{{ $globals.icons.delete }}
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
</section>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, useAsync, reactive, toRefs } from "@nuxtjs/composition-api";
|
||||
import { useUserApi } from "~/composables/api";
|
||||
import { useAsyncKey } from "~/composables/use-utils";
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const userApi = useUserApi();
|
||||
|
||||
const state = reactive({
|
||||
createName: "",
|
||||
createDialog: false,
|
||||
deleteDialog: false,
|
||||
deleteTarget: "",
|
||||
});
|
||||
|
||||
const shoppingLists = useAsync(async () => {
|
||||
return await fetchShoppingLists();
|
||||
}, useAsyncKey());
|
||||
|
||||
async function fetchShoppingLists() {
|
||||
const { data } = await userApi.shopping.lists.getAll();
|
||||
return data;
|
||||
}
|
||||
|
||||
async function refresh() {
|
||||
shoppingLists.value = await fetchShoppingLists();
|
||||
}
|
||||
|
||||
async function createOne() {
|
||||
const { data } = await userApi.shopping.lists.createOne({ name: state.createName });
|
||||
|
||||
if (data) {
|
||||
refresh();
|
||||
state.createName = "";
|
||||
}
|
||||
}
|
||||
|
||||
function openDelete(id: string) {
|
||||
state.deleteDialog = true;
|
||||
state.deleteTarget = id;
|
||||
}
|
||||
|
||||
async function deleteOne() {
|
||||
const { data } = await userApi.shopping.lists.deleteOne(state.deleteTarget);
|
||||
if (data) {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
shoppingLists,
|
||||
createOne,
|
||||
deleteOne,
|
||||
openDelete,
|
||||
};
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.$t("shopping-list.shopping-list") as string,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue