EventImageModal feature
This commit is contained in:
parent
deee3ed673
commit
ef890fb577
65
src/components/Event/EventImageModal.vue
Normal file
65
src/components/Event/EventImageModal.vue
Normal file
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<div class="modal-overlay" @click.self="closeModal">
|
||||
<div class="modal-content">
|
||||
<img :src="image" alt="Full-size event banner" />
|
||||
<button class="close-button" @click="closeModal">X</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
image: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
const closeModal = () => {
|
||||
emit('close');
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.modal-overlay {
|
||||
position: fixed !important;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000000 !important;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
position: relative;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.modal-content {
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-content img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: white;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
|
@ -154,13 +154,32 @@
|
|||
>
|
||||
<span v-else>{{ extra.value }}</span>
|
||||
</event-metadata-block>
|
||||
<event-metadata-block
|
||||
v-if="isUserUploadedImage"
|
||||
:title="t('Title Picture')"
|
||||
>
|
||||
<!-- Event Banner Component, only displayed if user uploaded image -->
|
||||
<div class="clickable-banner" @click="showBannerFullScreen">
|
||||
<event-banner :picture="event.picture" />
|
||||
</div>
|
||||
</event-metadata-block>
|
||||
|
||||
<!-- Modal to display full-screen image -->
|
||||
<Teleport to=body>
|
||||
<event-image-modal
|
||||
v-if="showFullScreen"
|
||||
:image="event.picture.url"
|
||||
@close="showFullScreen = false"
|
||||
/>
|
||||
</Teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Address, addressToPoiInfos } from "@/types/address.model";
|
||||
import { EventMetadataKeyType, EventMetadataType } from "@/types/enums";
|
||||
import { IEvent } from "@/types/event.model";
|
||||
import { computed } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import RouteName from "../../router/name";
|
||||
import { usernameWithDomain } from "../../types/actor";
|
||||
import EventMetadataBlock from "./EventMetadataBlock.vue";
|
||||
|
@ -174,6 +193,8 @@ import { useI18n } from "vue-i18n";
|
|||
import Earth from "vue-material-design-icons/Earth.vue";
|
||||
import Calendar from "vue-material-design-icons/Calendar.vue";
|
||||
import Link from "vue-material-design-icons/Link.vue";
|
||||
import EventBanner from "@/components/Event/EventBanner.vue";
|
||||
import EventImageModal from "@/components/Event/EventImageModal.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -242,7 +263,22 @@ const accountURL = (extra: IEventMetadataDescription): string | undefined => {
|
|||
const userTimezone = computed((): string | undefined => {
|
||||
return props.user?.settings?.timezone;
|
||||
});
|
||||
|
||||
/** Define the default image URL */
|
||||
const DEFAULT_CARD_URL = "/img/mobilizon_default_card.png";
|
||||
|
||||
/** Computed property to check if the image is a user-uploaded image */
|
||||
const isUserUploadedImage = computed(() => {
|
||||
return props.event.picture?.url && props.event.picture.url !== DEFAULT_CARD_URL;
|
||||
});
|
||||
|
||||
/** Handle click to show banner in full-screen */
|
||||
const showFullScreen = ref(false);
|
||||
const showBannerFullScreen = () => {
|
||||
showFullScreen.value = true; // Open full-screen modal
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.metadata-organized-by) {
|
||||
.v-popover.popover .trigger {
|
||||
|
@ -272,4 +308,19 @@ div.address-wrapper {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.clickable-banner {
|
||||
max-width: 150px;
|
||||
height: auto;
|
||||
max-height: 150px; /* Constrain image size */
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
object-fit: contain;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
object-fit: cover; /* Ensure the image fits within the constrained area */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue