@@ -1,16 +1,25 @@
|
||||
<template>
|
||||
<router-link
|
||||
class="mbz-card max-w-xs shrink-0 w-[18rem] snap-center dark:bg-mbz-purple"
|
||||
:to="{ name: RouteName.EVENT, params: { uuid: event.uuid } }"
|
||||
<LinkOrRouterLink
|
||||
class="mbz-card snap-center dark:bg-mbz-purple"
|
||||
:class="{
|
||||
'sm:flex sm:items-start': mode === 'row',
|
||||
'max-w-xs w-[18rem] shrink-0 flex flex-col': mode === 'column',
|
||||
}"
|
||||
:to="to"
|
||||
:isInternal="isInternal"
|
||||
>
|
||||
<div class="bg-secondary rounded-lg">
|
||||
<div
|
||||
class="bg-secondary rounded-lg"
|
||||
:class="{ 'sm:w-full sm:max-w-[20rem]': mode === 'row' }"
|
||||
>
|
||||
<figure class="block relative pt-40">
|
||||
<lazy-image-wrapper
|
||||
:picture="event.picture"
|
||||
style="height: 100%; position: absolute; top: 0; left: 0; width: 100%"
|
||||
/>
|
||||
<div
|
||||
class="absolute top-3 right-0 ltr:-mr-1 rtl:-ml-1 z-10 max-w-xs no-underline flex flex-col gap-1"
|
||||
class="absolute top-3 right-0 ltr:-mr-1 rtl:-ml-1 z-10 max-w-xs no-underline flex flex-col gap-1 items-end"
|
||||
v-show="mode === 'column'"
|
||||
v-if="event.tags || event.status !== EventStatus.CONFIRMED"
|
||||
>
|
||||
<mobilizon-tag
|
||||
@@ -30,30 +39,39 @@
|
||||
v-for="tag in (event.tags || []).slice(0, 3)"
|
||||
:key="tag.slug"
|
||||
>
|
||||
<mobilizon-tag dir="auto">{{ tag.title }}</mobilizon-tag>
|
||||
<mobilizon-tag dir="auto" :with-hash-tag="true">{{
|
||||
tag.title
|
||||
}}</mobilizon-tag>
|
||||
</router-link>
|
||||
</div>
|
||||
</figure>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<div class="p-2 flex-auto" :class="{ 'sm:flex-1': mode === 'row' }">
|
||||
<div class="relative flex flex-col h-full">
|
||||
<div class="-mt-3 h-0 flex mb-3 ltr:ml-0 rtl:mr-0 items-end self-start">
|
||||
<div
|
||||
class="-mt-3 h-0 flex mb-3 ltr:ml-0 rtl:mr-0 items-end self-start"
|
||||
:class="{ 'sm:hidden': mode === 'row' }"
|
||||
>
|
||||
<date-calendar-icon
|
||||
:small="true"
|
||||
v-if="!mergedOptions.hideDate"
|
||||
:date="event.beginsOn.toString()"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full flex flex-col justify-between">
|
||||
<h3
|
||||
class="text-lg leading-5 line-clamp-3 font-bold text-violet-3 dark:text-white"
|
||||
:title="event.title"
|
||||
<span
|
||||
class="text-gray-700 dark:text-white font-semibold hidden"
|
||||
:class="{ 'sm:block': mode === 'row' }"
|
||||
>{{ formatDateTimeWithCurrentLocale }}</span
|
||||
>
|
||||
<div class="w-full flex flex-col justify-between h-full">
|
||||
<h2
|
||||
class="mt-0 mb-2 text-2xl line-clamp-3 font-bold text-violet-3 dark:text-white"
|
||||
dir="auto"
|
||||
:lang="event.language"
|
||||
>
|
||||
{{ event.title }}
|
||||
</h3>
|
||||
<div class="pt-3">
|
||||
</h2>
|
||||
<div class="">
|
||||
<div
|
||||
class="flex items-center text-violet-3 dark:text-white"
|
||||
dir="auto"
|
||||
@@ -68,7 +86,7 @@
|
||||
/>
|
||||
</figure>
|
||||
<account-circle v-else />
|
||||
<span class="text-sm font-semibold ltr:pl-2 rtl:pr-2">
|
||||
<span class="font-semibold ltr:pl-2 rtl:pr-2">
|
||||
{{ organizerDisplayName(event) }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -84,11 +102,38 @@
|
||||
<Video />
|
||||
<span class="ltr:pl-2 rtl:pr-2">{{ $t("Online") }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="mt-1 no-underline gap-1 items-center hidden"
|
||||
:class="{ 'sm:flex': mode === 'row' }"
|
||||
v-if="event.tags || event.status !== EventStatus.CONFIRMED"
|
||||
>
|
||||
<mobilizon-tag
|
||||
variant="info"
|
||||
v-if="event.status === EventStatus.TENTATIVE"
|
||||
>
|
||||
{{ $t("Tentative") }}
|
||||
</mobilizon-tag>
|
||||
<mobilizon-tag
|
||||
variant="danger"
|
||||
v-if="event.status === EventStatus.CANCELLED"
|
||||
>
|
||||
{{ $t("Cancelled") }}
|
||||
</mobilizon-tag>
|
||||
<router-link
|
||||
:to="{ name: RouteName.TAG, params: { tag: tag.title } }"
|
||||
v-for="tag in (event.tags || []).slice(0, 3)"
|
||||
:key="tag.slug"
|
||||
>
|
||||
<mobilizon-tag :with-hash-tag="true" dir="auto">{{
|
||||
tag.title
|
||||
}}</mobilizon-tag>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
</LinkOrRouterLink>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -104,17 +149,29 @@ import { EventStatus } from "@/types/enums";
|
||||
import RouteName from "../../router/name";
|
||||
import InlineAddress from "@/components/Address/InlineAddress.vue";
|
||||
|
||||
import { computed } from "vue";
|
||||
import MobilizonTag from "../Tag.vue";
|
||||
import { computed, inject } from "vue";
|
||||
import MobilizonTag from "@/components/Tag.vue";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Video from "vue-material-design-icons/Video.vue";
|
||||
import { formatDateTimeForEvent } from "@/utils/datetime";
|
||||
import type { Locale } from "date-fns";
|
||||
import LinkOrRouterLink from "../core/LinkOrRouterLink.vue";
|
||||
|
||||
const props = defineProps<{ event: IEvent; options?: IEventCardOptions }>();
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
event: IEvent;
|
||||
options?: IEventCardOptions;
|
||||
mode?: "row" | "column";
|
||||
}>(),
|
||||
{ mode: "column" }
|
||||
);
|
||||
const defaultOptions: IEventCardOptions = {
|
||||
hideDate: false,
|
||||
loggedPerson: false,
|
||||
hideDetails: false,
|
||||
organizerActor: null,
|
||||
isRemoteEvent: false,
|
||||
isLoggedIn: true,
|
||||
};
|
||||
|
||||
const mergedOptions = computed<IEventCardOptions>(() => ({
|
||||
@@ -132,4 +189,31 @@ const mergedOptions = computed<IEventCardOptions>(() => ({
|
||||
const actorAvatarURL = computed<string | null>(() =>
|
||||
organizerAvatarUrl(props.event)
|
||||
);
|
||||
|
||||
const dateFnsLocale = inject<Locale>("dateFnsLocale");
|
||||
|
||||
const formatDateTimeWithCurrentLocale = computed(() => {
|
||||
if (!dateFnsLocale) return;
|
||||
return formatDateTimeForEvent(new Date(props.event.beginsOn), dateFnsLocale);
|
||||
});
|
||||
|
||||
const isInternal = computed(() => {
|
||||
return (
|
||||
mergedOptions.value.isRemoteEvent &&
|
||||
mergedOptions.value.isLoggedIn === false
|
||||
);
|
||||
});
|
||||
|
||||
const to = computed(() => {
|
||||
if (mergedOptions.value.isRemoteEvent) {
|
||||
if (mergedOptions.value.isLoggedIn === false) {
|
||||
return props.event.url;
|
||||
}
|
||||
return {
|
||||
name: RouteName.INTERACT,
|
||||
query: { uri: encodeURI(props.event.url) },
|
||||
};
|
||||
}
|
||||
return { name: RouteName.EVENT, params: { uuid: props.event.uuid } };
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user