+ wishlist item is active
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
<div class="bg-gray-100 h-12 block lg:hidden"></div>
|
<div class="bg-gray-100 h-12 block lg:hidden"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="footer" class="flex flex-col w-full h-fit bg-gray-200 p-4 gap-4 ">
|
<div v-if="userStore.user && !route.path.startsWith('/mywishlist')" id="footer" class="flex flex-col w-full h-fit bg-gray-200 p-4 gap-4 ">
|
||||||
<div class="flex flex-row items-start gap-2 ">
|
<div class="flex flex-row items-start gap-2 ">
|
||||||
<div class="flex flex-row items-center gap-2 min-w-fit">
|
<div class="flex flex-row items-center gap-2 min-w-fit">
|
||||||
<img alt="logo" src="/apple-touch-icon.png" width="48" height="48"/>
|
<img alt="logo" src="/apple-touch-icon.png" width="48" height="48"/>
|
||||||
@@ -37,9 +37,9 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row justify-between">
|
<div class="flex flex-row w-full items-end">
|
||||||
<div>Ваши предложения можно направлять в <a href="https://t.me/voroninv" class="hover:underline text-blue-600">https://t.me/@voroninv</a>
|
<!-- <div>Ваши предложения можно направлять в <a href="https://t.me/voroninv" class="hover:underline text-blue-600">https://t.me/@voroninv</a>-->
|
||||||
</div>
|
<!-- </div>-->
|
||||||
<div>v0.0.2</div>
|
<div>v0.0.2</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="h-16 lg:h-0"/>
|
<div class="h-16 lg:h-0"/>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {useSpaceStore} from "@/stores/spaceStore";
|
|||||||
import {useToast} from "primevue/usetoast";
|
import {useToast} from "primevue/usetoast";
|
||||||
import WishlistCreationView from "@/components/wishlists/WishlistCreationView.vue";
|
import WishlistCreationView from "@/components/wishlists/WishlistCreationView.vue";
|
||||||
import {useConfirm} from "primevue/useconfirm";
|
import {useConfirm} from "primevue/useconfirm";
|
||||||
|
import {useUserStore} from "@/stores/userStore";
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
const confirm = useConfirm();
|
const confirm = useConfirm();
|
||||||
|
|
||||||
@@ -39,6 +40,8 @@ const wishlistCreationCanceled = () => {
|
|||||||
creationOpened.value = false
|
creationOpened.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const deleteWishlist = async (wishlist: WishList) => {
|
const deleteWishlist = async (wishlist: WishList) => {
|
||||||
confirm.require({
|
confirm.require({
|
||||||
message: `Вы действительно хотите удалить вишлист ${wishlist.name} ?`,
|
message: `Вы действительно хотите удалить вишлист ${wishlist.name} ?`,
|
||||||
@@ -152,13 +155,13 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<div class="flex flex-col justify-between items-end gap-4">
|
<div class="flex flex-col justify-between items-end gap-4">
|
||||||
<div class="flex flex-row gap-2">
|
<div class="flex flex-row gap-2">
|
||||||
<button @click="editingWishlist=wishlist;creationOpened=true"><i class="pi pi-pen-to-square" style="font-size: 1rem"/></button>
|
<button v-if="wishlist.owner.id==userStore.user.id" @click="editingWishlist=wishlist;creationOpened=true"><i class="pi pi-pen-to-square" style="font-size: 1rem"/></button>
|
||||||
<router-link :to="'/wishlists/'+wishlist.id">
|
<router-link :to="'/wishlists/'+wishlist.id">
|
||||||
<i class="pi pi-arrow-circle-right " style=""/>
|
<i class="pi pi-arrow-circle-right " style=""/>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<button @click="deleteWishlist(wishlist)"><i class="pi pi-trash" /></button>
|
<button v-if="wishlist.owner.id==userStore.user.id" @click="deleteWishlist(wishlist)"><i class="pi pi-trash" /></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ const cancelCreation = () => {
|
|||||||
<label for="name">Описание</label>
|
<label for="name">Описание</label>
|
||||||
<Textarea v-model="wishlist.description" id="name" class="w-full"/>
|
<Textarea v-model="wishlist.description" id="name" class="w-full"/>
|
||||||
</FloatLabel>
|
</FloatLabel>
|
||||||
|
|
||||||
<div class="flex flex-row gap-2 justify-end items-center">
|
<div class="flex flex-row gap-2 justify-end items-center">
|
||||||
<Button label="Создать" severity="success" icon="pi pi-save" @click="createWishlist" class="!bg-blue-300 hover:!bg-blue-400 !border-blue-300"/>
|
<Button label="Создать" severity="success" icon="pi pi-save" @click="createWishlist" class="!bg-blue-300 hover:!bg-blue-400 !border-blue-300"/>
|
||||||
<Button label="Отмена" severity="secondary" icon="pi pi-times-circle" @click="cancelCreation"/>
|
<Button label="Отмена" severity="secondary" icon="pi pi-times-circle" @click="cancelCreation"/>
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ import {ref} from "vue";
|
|||||||
import InputGroup from "primevue/inputgroup";
|
import InputGroup from "primevue/inputgroup";
|
||||||
import InputNumber from "primevue/inputnumber";
|
import InputNumber from "primevue/inputnumber";
|
||||||
import InputGroupAddon from "primevue/inputgroupaddon";
|
import InputGroupAddon from "primevue/inputgroupaddon";
|
||||||
import {addWishListItemRequest} from "@/services/WishListService";
|
import {addWishListItemRequest, updateWishListItemRequest} from "@/services/WishListService";
|
||||||
import {useToast} from "primevue/usetoast";
|
import {useToast} from "primevue/usetoast";
|
||||||
|
import Checkbox from "primevue/checkbox";
|
||||||
|
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
@@ -19,9 +20,11 @@ const props = defineProps({
|
|||||||
editItem: Object,
|
editItem: Object,
|
||||||
})
|
})
|
||||||
|
|
||||||
const emits = defineEmits(["item-created", "creation-cancelled"])
|
const emits = defineEmits(["item-created", "creation-cancelled", "item-updated"]);
|
||||||
const isEditing = ref(!!props.editItem)
|
const isEditing = ref(!!props.editItem)
|
||||||
const item = ref(props.editItem ? props.editItem : new WishlistItem())
|
const newItemRef = ref<WishlistItem>(new WishlistItem());
|
||||||
|
newItemRef.value.isActive = true;
|
||||||
|
const item = ref(props.editItem ? props.editItem : newItemRef.value)
|
||||||
const inputNameRef = ref()
|
const inputNameRef = ref()
|
||||||
const inputDescriptionRef = ref()
|
const inputDescriptionRef = ref()
|
||||||
const inputPriceRef = ref()
|
const inputPriceRef = ref()
|
||||||
@@ -63,6 +66,22 @@ const checkForm = () => {
|
|||||||
return false
|
return false
|
||||||
} else return true
|
} else return true
|
||||||
}
|
}
|
||||||
|
const updateWishlistItem = async () => {
|
||||||
|
|
||||||
|
await updateWishListItemRequest(props.wishlistId, item.value)
|
||||||
|
.then(async (res) => {
|
||||||
|
emits("item-updated", res)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
toast.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Ошибка сохранения желания',
|
||||||
|
detail: err.response.data.message,
|
||||||
|
life: 3000
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const itemCreate = async () => {
|
const itemCreate = async () => {
|
||||||
if (checkForm()) {
|
if (checkForm()) {
|
||||||
await addWishListItemRequest(props.wishlistId, item.value)
|
await addWishListItemRequest(props.wishlistId, item.value)
|
||||||
@@ -112,8 +131,12 @@ const resetForm = () => {
|
|||||||
<InputNumber :ref="inputPriceRef" v-model="item.price" placeholder="Сумма"/>
|
<InputNumber :ref="inputPriceRef" v-model="item.price" placeholder="Сумма"/>
|
||||||
<InputGroupAddon>.00</InputGroupAddon>
|
<InputGroupAddon>.00</InputGroupAddon>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<Checkbox v-model="item.isActive" inputId="isActive" name="isActive" binary />
|
||||||
|
<label for="isActive">Активен?</label>
|
||||||
|
</div>
|
||||||
<div class="flex flex-row gap-2 justify-end items-center">
|
<div class="flex flex-row gap-2 justify-end items-center">
|
||||||
<Button label="Создать" severity="success" icon="pi pi-save" @click="itemCreate" class="!bg-blue-300 hover:!bg-blue-400 !border-blue-300"/>
|
<Button :label="props.editItem ? 'Сохранить' : 'Создать'" severity="success" icon="pi pi-save" @click="props.editItem? updateWishlistItem() : itemCreate()" class="!bg-blue-300 hover:!bg-blue-400 !border-blue-300"/>
|
||||||
<Button label="Отмена" severity="secondary" icon="pi pi-times-circle" @click="cancelCreation"/>
|
<Button label="Отмена" severity="secondary" icon="pi pi-times-circle" @click="cancelCreation"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import InputText from "primevue/inputtext";
|
|||||||
import FloatLabel from "primevue/floatlabel";
|
import FloatLabel from "primevue/floatlabel";
|
||||||
import ConfirmDialog from "primevue/confirmdialog";
|
import ConfirmDialog from "primevue/confirmdialog";
|
||||||
import {useConfirm} from "primevue/useconfirm";
|
import {useConfirm} from "primevue/useconfirm";
|
||||||
|
import {useUserStore} from "@/stores/userStore";
|
||||||
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -35,6 +36,9 @@ const confirm = useConfirm()
|
|||||||
|
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const wishlist = ref<WishList>()
|
const wishlist = ref<WishList>()
|
||||||
|
const activeItems = ref<WishlistItem[]>([])
|
||||||
|
const disabledItems = ref<WishlistItem[]>([])
|
||||||
|
const disabledItemsShowed = ref<boolean>(false)
|
||||||
const selectedImage = reactive(new Map<string, string>())
|
const selectedImage = reactive(new Map<string, string>())
|
||||||
const hoveredCancelReservationButton = reactive(new Map<string, boolean>())
|
const hoveredCancelReservationButton = reactive(new Map<string, boolean>())
|
||||||
|
|
||||||
@@ -44,6 +48,9 @@ const fetchWishlist = async () => {
|
|||||||
wishlist.value = res
|
wishlist.value = res
|
||||||
wishlist.value?.items.forEach((item: WishlistItem) => {
|
wishlist.value?.items.forEach((item: WishlistItem) => {
|
||||||
selectedImage.set(item.id, item.images[0])
|
selectedImage.set(item.id, item.images[0])
|
||||||
|
if (item.isActive) {
|
||||||
|
activeItems.value.push(item)
|
||||||
|
} else disabledItems.value.push(item)
|
||||||
})
|
})
|
||||||
shareLink.value = window.location.origin + "/mywishlist/" + wishlist.value?.id
|
shareLink.value = window.location.origin + "/mywishlist/" + wishlist.value?.id
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -235,6 +242,8 @@ const spaceStore = useSpaceStore()
|
|||||||
const selectedSpace = computed(() => spaceStore.space)
|
const selectedSpace = computed(() => spaceStore.space)
|
||||||
const fileUploadLink = ref()
|
const fileUploadLink = ref()
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => selectedSpace.value,
|
() => selectedSpace.value,
|
||||||
@@ -301,7 +310,8 @@ onMounted(async () => {
|
|||||||
@update:visible="editingItem = null;wishlistItemCreationOpened = false"
|
@update:visible="editingItem = null;wishlistItemCreationOpened = false"
|
||||||
class="w-5/6 md:!w-2/6">
|
class="w-5/6 md:!w-2/6">
|
||||||
<WishlistItemCreationView :editItem="editingItem" :wishlistId="wishlist.id" @item-created="itemCreated"
|
<WishlistItemCreationView :editItem="editingItem" :wishlistId="wishlist.id" @item-created="itemCreated"
|
||||||
@creation-cancelled="editingItem = null;wishlistItemCreationOpened = false"/>
|
@creation-cancelled="editingItem = null;wishlistItemCreationOpened = false"
|
||||||
|
@item-updated="itemCreated"/>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
<Dialog :visible="shareDialogOpened" header="Поделиться" @hide="shareDialogOpened = false"
|
<Dialog :visible="shareDialogOpened" header="Поделиться" @hide="shareDialogOpened = false"
|
||||||
@update:visible="shareDialogOpened=false" modal>
|
@update:visible="shareDialogOpened=false" modal>
|
||||||
@@ -340,17 +350,19 @@ onMounted(async () => {
|
|||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="flex flex-row gap-4">
|
<div class="flex flex-row gap-4">
|
||||||
<p class="text-2xl text-gray-700">Желания</p>
|
<p class="text-2xl text-gray-700">Желания</p>
|
||||||
<Button label="+ Создать" @click="wishlistItemCreationOpened=true" size="small" class="!bg-blue-300 hover:!bg-blue-400 !border-blue-300"/>
|
<Button v-if="wishlist.owner.id==userStore.user.id" label="+ Создать"
|
||||||
|
@click="wishlistItemCreationOpened=true" size="small"
|
||||||
|
class="!bg-blue-300 hover:!bg-blue-400 !border-blue-300"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-2">
|
<div class="grid grid-cols-1 lg:grid-cols-4 gap-2">
|
||||||
<div v-for="item in wishlist.items"
|
<div v-for="item in activeItems"
|
||||||
class=" bg-white flex flex-col p-4 flex-shrink-0 gap-4 shadow-md rounded-lg max-w-128 h-full">
|
class=" bg-white flex flex-col p-4 flex-shrink-0 gap-4 shadow-md rounded-lg max-w-128 h-full">
|
||||||
<!-- <div v-if="true" >-->
|
<!-- <div v-if="true" >-->
|
||||||
<!-- <LoadingView :halfscreen="true"/>-->
|
<!-- <LoadingView :halfscreen="true"/>-->
|
||||||
<!-- </div>-->
|
<!-- </div>-->
|
||||||
<div class="flex flex-col gap-2 justify-between h-full">
|
<div class="flex flex-col gap-2 justify-between h-full">
|
||||||
<div class="flex flex-col w-full justify-center gap-2">
|
<div class="flex flex-col w-full justify-center gap-2">
|
||||||
<div v-if="item.images.length > 0 && selectedImage.get(item.id)" class="flex w-full justify-center ">
|
<div v-if="item.images.length > 0 && selectedImage.get(item.id)" class="flex w-full justify-center ">
|
||||||
<Image
|
<Image
|
||||||
:src="selectedImage.get(item.id).startsWith('http') ? selectedImage.get(item.id) : apiClient.defaults.baseURL+'/'+selectedImage.get(item.id) "
|
:src="selectedImage.get(item.id).startsWith('http') ? selectedImage.get(item.id) : apiClient.defaults.baseURL+'/'+selectedImage.get(item.id) "
|
||||||
@@ -359,16 +371,24 @@ onMounted(async () => {
|
|||||||
imageClass="h-64 w-64 object-cover items-center justify-center justify-items-center"/>
|
imageClass="h-64 w-64 object-cover items-center justify-center justify-items-center"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="min-h-64 flex flex-col items-center justify-center gap-2">
|
<div v-else class="min-h-64 flex flex-col items-center justify-center gap-2">
|
||||||
<button @click="imageUploadVisible=true;imageUploadForItemId=item.id" class="flex flex-col items-center gap-2">
|
<button v-if="wishlist.owner.id==userStore.user.id"
|
||||||
<div
|
@click="imageUploadVisible=true;imageUploadForItemId=item.id"
|
||||||
class="rounded-full w-16 h-16 bg-gray-400 opacity-30 group-hover:opacity-70 flex items-center justify-center">
|
class="flex flex-col items-center gap-2">
|
||||||
|
<div
|
||||||
|
class="rounded-full w-16 h-16 bg-gray-400 opacity-30 group-hover:opacity-70 flex items-center justify-center">
|
||||||
|
|
||||||
<i class="pi pi-plus !font-bold !text-3xl text-white"/>
|
<i class="pi pi-plus !font-bold !text-3xl text-white"/>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<span class="text-gray-600 text-xl">Загрузите изображение</span>
|
<span class="text-gray-600 text-xl">Загрузите изображение</span>
|
||||||
</button>
|
</button>
|
||||||
|
<div v-else
|
||||||
|
class="min-h-[304px] flex flex-col items-center w-full justify-center gap-2 bg-gray-100 rounded-lg max-w-128 h-full">
|
||||||
|
<i class="pi pi-images !text-gray-400 z-50" style="font-size: 8rem"/>
|
||||||
|
<span class="text-lg font-bold text-center text-gray-400">Изображение пока не загружено</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row !h-12 gap-2">
|
<div class="flex flex-row !h-12 gap-2">
|
||||||
|
|
||||||
@@ -380,13 +400,14 @@ onMounted(async () => {
|
|||||||
imageClass="w-12 h-12 object-cover"/>
|
imageClass="w-12 h-12 object-cover"/>
|
||||||
</button>
|
</button>
|
||||||
<!-- Иконка для удаления -->
|
<!-- Иконка для удаления -->
|
||||||
<button @click="deleteImage(item, index)">
|
<button v-if="wishlist.owner.id==userStore.user.id" @click="deleteImage(item, index)">
|
||||||
<i class="pi pi-minus absolute -top-2 right-0 text-red-400 z-10 bg-white rounded-full p-[0.2rem] border-2 !hidden group-hover:!block "
|
<i class="pi pi-minus absolute -top-2 right-0 text-red-400 z-10 bg-white rounded-full p-[0.2rem] border-2 !hidden group-hover:!block "
|
||||||
style="font-size: 0.6rem"
|
style="font-size: 0.6rem"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-12 h-12 bg-gray-100 rounded flex items-center justify-center group">
|
<div v-if="wishlist.owner.id==userStore.user.id"
|
||||||
|
class="w-12 h-12 bg-gray-100 rounded flex items-center justify-center group">
|
||||||
<div
|
<div
|
||||||
class="rounded-full w-9 h-9 bg-gray-400 opacity-30 group-hover:opacity-70 flex items-center justify-center">
|
class="rounded-full w-9 h-9 bg-gray-400 opacity-30 group-hover:opacity-70 flex items-center justify-center">
|
||||||
<button @click="imageUploadVisible=true;imageUploadForItemId=item.id">
|
<button @click="imageUploadVisible=true;imageUploadForItemId=item.id">
|
||||||
@@ -401,7 +422,7 @@ onMounted(async () => {
|
|||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<div class="flex flex-row w-full justify-between">
|
<div class="flex flex-row w-full justify-between">
|
||||||
<p class="font-semibold text-xl text-gray-700">{{ item.name }}</p>
|
<p class="font-semibold text-xl text-gray-700">{{ item.name }}</p>
|
||||||
<div class="flex flex-row gap-2">
|
<div v-if="wishlist.owner.id==userStore.user.id" class="flex flex-row gap-2">
|
||||||
<button @click="editingItem=item;wishlistItemCreationOpened=true"><i
|
<button @click="editingItem=item;wishlistItemCreationOpened=true"><i
|
||||||
class="pi pi-pen-to-square"/>
|
class="pi pi-pen-to-square"/>
|
||||||
</button>
|
</button>
|
||||||
@@ -417,7 +438,113 @@ onMounted(async () => {
|
|||||||
<div class="grid grid-cols-2 w-full justify-between items-center">
|
<div class="grid grid-cols-2 w-full justify-between items-center">
|
||||||
<a :href="item.link"
|
<a :href="item.link"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
<Button label="В магазин" icon="pi pi-arrow-up-right" iconPos="right" class="!bg-blue-300 hover:!bg-blue-400 !border-blue-300"/>
|
<Button label="В магазин" icon="pi pi-arrow-up-right" iconPos="right"
|
||||||
|
class="!bg-blue-300 hover:!bg-blue-400 !border-blue-300"/>
|
||||||
|
</a>
|
||||||
|
<span v-if="!item.reservedBy" class="text-gray-500">Не забронировано</span>
|
||||||
|
<Button v-else @mouseover="hoveredCancelReservationButton.set(item.id, true)"
|
||||||
|
@mouseleave="hoveredCancelReservationButton.delete(item.id)"
|
||||||
|
:label="hoveredCancelReservationButton.get(item.id) ? 'Отменить' : 'Забронировано'"
|
||||||
|
:disabled="!hoveredCancelReservationButton.get(item.id)"
|
||||||
|
:severity="hoveredCancelReservationButton.get(item.id) ? 'danger' : ''"
|
||||||
|
class="w-full !bg-blue-300 hover:!bg-blue-400 !border-blue-300"
|
||||||
|
@click="hoveredCancelReservationButton.get(item.id) ? cancelReserve(item): ''"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row gap-4 w-full ju">
|
||||||
|
<p class="text-2xl items-end text-gray-700">Архив</p>
|
||||||
|
<button @click="disabledItemsShowed=!disabledItemsShowed"><span class="text-sm text-gray-600">{{disabledItemsShowed ? 'Скрыть' : 'Раскрыть'}}<i
|
||||||
|
class="pi pi-arrow-up-right" style="font-size: 0.65rem"/></span></button></div>
|
||||||
|
<div class="grid grid-cols-1 lg:grid-cols-4 gap-2">
|
||||||
|
<div v-if="disabledItemsShowed" v-for="item in disabledItems"
|
||||||
|
class=" bg-white flex flex-col p-4 flex-shrink-0 gap-4 shadow-md rounded-lg max-w-128 h-full">
|
||||||
|
<!-- <div v-if="true" >-->
|
||||||
|
<!-- <LoadingView :halfscreen="true"/>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<div class="flex flex-col gap-2 justify-between h-full">
|
||||||
|
<div class="flex flex-col w-full justify-center gap-2">
|
||||||
|
<div v-if="item.images.length > 0 && selectedImage.get(item.id)" class="flex w-full justify-center ">
|
||||||
|
<Image
|
||||||
|
:src="selectedImage.get(item.id).startsWith('http') ? selectedImage.get(item.id) : apiClient.defaults.baseURL+'/'+selectedImage.get(item.id) "
|
||||||
|
alt="Image"
|
||||||
|
width="128" height="128" show="show" preview
|
||||||
|
imageClass="h-64 w-64 object-cover items-center justify-center justify-items-center"/>
|
||||||
|
</div>
|
||||||
|
<div v-else class="min-h-64 flex flex-col items-center justify-center gap-2">
|
||||||
|
<button v-if="wishlist.owner.id==userStore.user.id"
|
||||||
|
@click="imageUploadVisible=true;imageUploadForItemId=item.id"
|
||||||
|
class="flex flex-col items-center gap-2">
|
||||||
|
<div
|
||||||
|
class="rounded-full w-16 h-16 bg-gray-400 opacity-30 group-hover:opacity-70 flex items-center justify-center">
|
||||||
|
|
||||||
|
<i class="pi pi-plus !font-bold !text-3xl text-white"/>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<span class="text-gray-600 text-xl">Загрузите изображение</span>
|
||||||
|
</button>
|
||||||
|
<div v-else
|
||||||
|
class="min-h-[304px] flex flex-col items-center w-full justify-center gap-2 bg-gray-100 rounded-lg max-w-128 h-full">
|
||||||
|
<i class="pi pi-images !text-gray-400 z-50" style="font-size: 8rem"/>
|
||||||
|
<span class="text-lg font-bold text-center text-gray-400">Изображение пока не загружено</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row !h-12 gap-2">
|
||||||
|
|
||||||
|
<div v-for="(image, index) in item.images" class="group relative h-12 w-12 rounded-lg shadow-md ">
|
||||||
|
<button @click="selectedImage.set(item.id, image)">
|
||||||
|
<Image
|
||||||
|
:src="image.startsWith('http') ? image : apiClient.defaults.baseURL+'/'+image " alt="Image"
|
||||||
|
width="48" height="48" show="show"
|
||||||
|
imageClass="w-12 h-12 object-cover"/>
|
||||||
|
</button>
|
||||||
|
<!-- Иконка для удаления -->
|
||||||
|
<button v-if="wishlist.owner.id==userStore.user.id" @click="deleteImage(item, index)">
|
||||||
|
<i class="pi pi-minus absolute -top-2 right-0 text-red-400 z-10 bg-white rounded-full p-[0.2rem] border-2 !hidden group-hover:!block "
|
||||||
|
style="font-size: 0.6rem"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div v-if="wishlist.owner.id==userStore.user.id"
|
||||||
|
class="w-12 h-12 bg-gray-100 rounded flex items-center justify-center group">
|
||||||
|
<div
|
||||||
|
class="rounded-full w-9 h-9 bg-gray-400 opacity-30 group-hover:opacity-70 flex items-center justify-center">
|
||||||
|
<button @click="imageUploadVisible=true;imageUploadForItemId=item.id">
|
||||||
|
<i class="pi pi-plus !font-bold !text-xl text-white"/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col justify-between gap-2 h-full">
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<div class="flex flex-row w-full justify-between">
|
||||||
|
<p class="font-semibold text-xl text-gray-700">{{ item.name }}</p>
|
||||||
|
<div v-if="wishlist.owner.id==userStore.user.id" class="flex flex-row gap-2">
|
||||||
|
<button @click="editingItem=item;wishlistItemCreationOpened=true"><i
|
||||||
|
class="pi pi-pen-to-square"/>
|
||||||
|
</button>
|
||||||
|
<button @click="deleteItem(item)"><i class="pi pi-trash"/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="font-bold text-lg text-blue-700">{{ formatAmount(item.price) }} ₽</p>
|
||||||
|
<p class="font-light text-gray-700 text-wrap">{{ item.description }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="grid grid-cols-2 w-full justify-between items-center">
|
||||||
|
<a :href="item.link"
|
||||||
|
target="_blank">
|
||||||
|
<Button label="В магазин" icon="pi pi-arrow-up-right" iconPos="right"
|
||||||
|
class="!bg-blue-300 hover:!bg-blue-400 !border-blue-300"/>
|
||||||
</a>
|
</a>
|
||||||
<span v-if="!item.reservedBy" class="text-gray-500">Не забронировано</span>
|
<span v-if="!item.reservedBy" class="text-gray-500">Не забронировано</span>
|
||||||
<Button v-else @mouseover="hoveredCancelReservationButton.set(item.id, true)"
|
<Button v-else @mouseover="hoveredCancelReservationButton.set(item.id, true)"
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export class WishlistItem {
|
|||||||
price: number
|
price: number
|
||||||
link: string
|
link: string
|
||||||
images: string[]
|
images: string[]
|
||||||
|
isActive: boolean
|
||||||
updatedAt: Date
|
updatedAt: Date
|
||||||
createdAt: Date
|
createdAt: Date
|
||||||
imagesWithLinks: []
|
imagesWithLinks: []
|
||||||
|
|||||||
Reference in New Issue
Block a user