build: switch from yarn to npm to manage js dependencies and move js contents to root
yarn v1 is being deprecated and starts to have some issues Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
118
src/components/Local/CloseContent.vue
Normal file
118
src/components/Local/CloseContent.vue
Normal file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="relative pt-10 px-2">
|
||||
<div class="mb-2">
|
||||
<div class="w-full flex flex-wrap gap-3 items-center">
|
||||
<h2
|
||||
class="text-xl font-bold tracking-tight text-gray-900 dark:text-gray-100 mt-0"
|
||||
>
|
||||
<slot name="title" />
|
||||
</h2>
|
||||
|
||||
<o-button
|
||||
:disabled="doingGeoloc"
|
||||
v-if="suggestGeoloc"
|
||||
class="inline-flex bg-primary rounded text-white flex-initial px-4 py-2 justify-center w-full md:w-min whitespace-nowrap"
|
||||
@click="emit('doGeoLoc')"
|
||||
>
|
||||
{{ t("Geolocate me") }}
|
||||
</o-button>
|
||||
</div>
|
||||
<slot name="subtitle" />
|
||||
</div>
|
||||
<div class="" v-show="showScrollLeftButton">
|
||||
<button
|
||||
@click="scrollLeft"
|
||||
class="absolute inset-y-0 my-auto z-10 rounded-full bg-white dark:bg-transparent w-10 h-10 border border-shadowColor -left-5 ml-2"
|
||||
>
|
||||
<span class=""><</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="overflow-hidden">
|
||||
<div
|
||||
class="relative w-full snap-x snap-always snap-mandatory overflow-x-auto flex pb-6 gap-x-5 gap-y-8 p-1"
|
||||
ref="scrollContainer"
|
||||
@scroll="scrollHandler"
|
||||
>
|
||||
<slot name="content" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="" v-show="showScrollRightButton">
|
||||
<button
|
||||
@click="scrollRight"
|
||||
class="absolute inset-y-0 my-auto z-10 rounded-full bg-white dark:bg-transparent w-10 h-10 border border-shadowColor -right-5 mr-2"
|
||||
>
|
||||
<span class="">></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
suggestGeoloc?: boolean;
|
||||
doingGeoloc?: boolean;
|
||||
}>(),
|
||||
{ suggestGeoloc: true, doingGeoloc: false }
|
||||
);
|
||||
|
||||
const emit = defineEmits(["doGeoLoc"]);
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const showScrollRightButton = ref(false);
|
||||
const showScrollLeftButton = ref(false);
|
||||
|
||||
const scrollContainer = ref<any>();
|
||||
|
||||
const scrollHandler = () => {
|
||||
if (scrollContainer.value) {
|
||||
showScrollRightButton.value =
|
||||
scrollContainer.value.scrollLeft <
|
||||
scrollContainer.value.scrollWidth - scrollContainer.value.clientWidth;
|
||||
showScrollLeftButton.value = scrollContainer.value.scrollLeft > 0;
|
||||
}
|
||||
};
|
||||
|
||||
const doScroll = (e: Event, left: number) => {
|
||||
e.preventDefault();
|
||||
if (scrollContainer.value) {
|
||||
scrollContainer.value.scrollBy({
|
||||
left,
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const scrollLeft = (e: Event) => {
|
||||
doScroll(e, -300);
|
||||
};
|
||||
|
||||
const scrollRight = (e: Event) => {
|
||||
doScroll(e, 300);
|
||||
};
|
||||
|
||||
const scrollHorizontalToVertical = (evt: WheelEvent) => {
|
||||
evt.deltaY > 0 ? doScroll(evt, 300) : doScroll(evt, -300);
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
// Make sure everything is mounted properly
|
||||
setTimeout(() => {
|
||||
scrollHandler();
|
||||
}, 1500);
|
||||
scrollContainer.value.addEventListener("wheel", scrollHorizontalToVertical);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (scrollContainer.value) {
|
||||
scrollContainer.value.removeEventListener(
|
||||
"wheel",
|
||||
scrollHorizontalToVertical
|
||||
);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
130
src/components/Local/CloseEvents.vue
Normal file
130
src/components/Local/CloseEvents.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<close-content
|
||||
class="container mx-auto px-2"
|
||||
v-show="loading || (events && events.total > 0)"
|
||||
:suggestGeoloc="suggestGeoloc"
|
||||
v-on="attrs"
|
||||
@doGeoLoc="emit('doGeoLoc')"
|
||||
:doingGeoloc="doingGeoloc"
|
||||
>
|
||||
<template #title>
|
||||
<template v-if="userLocationName">
|
||||
{{ t("Events nearby {position}", { position: userLocationName }) }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ t("Events close to you") }}
|
||||
</template>
|
||||
</template>
|
||||
<template #content>
|
||||
<skeleton-event-result
|
||||
v-for="i in 6"
|
||||
class="scroll-ml-6 snap-center shrink-0 w-[18rem] my-4"
|
||||
:key="i"
|
||||
v-show="loading"
|
||||
/>
|
||||
<event-card
|
||||
v-for="event in events.elements"
|
||||
:event="event"
|
||||
:key="event.uuid"
|
||||
/>
|
||||
<more-content
|
||||
v-if="userLocationName && userLocation?.lat && userLocation?.lon"
|
||||
:to="{
|
||||
name: RouteName.SEARCH,
|
||||
query: {
|
||||
locationName: userLocationName,
|
||||
lat: userLocation.lat?.toString(),
|
||||
lon: userLocation.lon?.toString(),
|
||||
contentType: 'EVENTS',
|
||||
distance: `${distance}_km`,
|
||||
},
|
||||
}"
|
||||
:picture="userLocation?.picture"
|
||||
>
|
||||
{{
|
||||
t("View more events around {position}", {
|
||||
position: userLocationName,
|
||||
})
|
||||
}}
|
||||
</more-content>
|
||||
</template>
|
||||
</close-content>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { LocationType } from "../../types/user-location.model";
|
||||
import MoreContent from "./MoreContent.vue";
|
||||
import CloseContent from "./CloseContent.vue";
|
||||
import { computed, onMounted, useAttrs } from "vue";
|
||||
import { SEARCH_EVENTS } from "@/graphql/search";
|
||||
import { IEvent } from "@/types/event.model";
|
||||
import { useLazyQuery } from "@vue/apollo-composable";
|
||||
import EventCard from "../Event/EventCard.vue";
|
||||
import { Paginate } from "@/types/paginate";
|
||||
import SkeletonEventResult from "../Event/SkeletonEventResult.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { coordsToGeoHash } from "@/utils/location";
|
||||
import { roundToNearestMinute } from "@/utils/datetime";
|
||||
import RouteName from "@/router/name";
|
||||
|
||||
const props = defineProps<{
|
||||
userLocation: LocationType;
|
||||
doingGeoloc?: boolean;
|
||||
}>();
|
||||
const emit = defineEmits(["doGeoLoc"]);
|
||||
|
||||
const EVENT_PAGE_LIMIT = 12;
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
const attrs = useAttrs();
|
||||
|
||||
const userLocation = computed(() => props.userLocation);
|
||||
|
||||
const userLocationName = computed(() => {
|
||||
return userLocation.value?.name;
|
||||
});
|
||||
const suggestGeoloc = computed(() => userLocation.value?.isIPLocation);
|
||||
|
||||
const geoHash = computed(() =>
|
||||
coordsToGeoHash(props.userLocation.lat, props.userLocation.lon)
|
||||
);
|
||||
|
||||
const distance = computed<number>(() => (suggestGeoloc.value ? 150 : 25));
|
||||
|
||||
const now = computed(() => roundToNearestMinute(new Date()));
|
||||
|
||||
const searchEnabled = computed(() => geoHash.value != undefined);
|
||||
|
||||
const {
|
||||
result: eventsResult,
|
||||
loading: loadingEvents,
|
||||
load: load,
|
||||
} = useLazyQuery<{
|
||||
searchEvents: Paginate<IEvent>;
|
||||
}>(
|
||||
SEARCH_EVENTS,
|
||||
() => ({
|
||||
location: geoHash.value,
|
||||
beginsOn: now.value,
|
||||
endsOn: undefined,
|
||||
radius: distance.value,
|
||||
eventPage: 1,
|
||||
limit: EVENT_PAGE_LIMIT,
|
||||
type: "IN_PERSON",
|
||||
}),
|
||||
() => ({
|
||||
enabled: searchEnabled.value,
|
||||
fetchPolicy: "cache-first",
|
||||
})
|
||||
);
|
||||
|
||||
const events = computed(
|
||||
() => eventsResult.value?.searchEvents ?? { elements: [], total: 0 }
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
await load();
|
||||
});
|
||||
|
||||
const loading = computed(() => props.doingGeoloc || loadingEvents.value);
|
||||
</script>
|
||||
116
src/components/Local/CloseGroups.vue
Normal file
116
src/components/Local/CloseGroups.vue
Normal file
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<close-content
|
||||
class="container mx-auto px-2"
|
||||
v-show="loading || selectedGroups.length > 0"
|
||||
@do-geo-loc="emit('doGeoLoc')"
|
||||
:suggestGeoloc="userLocation.isIPLocation"
|
||||
:doingGeoloc="doingGeoloc"
|
||||
>
|
||||
<template #title>
|
||||
<template v-if="userLocationName">
|
||||
{{
|
||||
t("Popular groups nearby {position}", {
|
||||
position: userLocationName,
|
||||
})
|
||||
}}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ t("Popular groups close to you") }}
|
||||
</template>
|
||||
</template>
|
||||
<template #content>
|
||||
<skeleton-group-result
|
||||
v-for="i in [...Array(6).keys()]"
|
||||
class="scroll-ml-6 snap-center shrink-0 w-[18rem] my-4"
|
||||
:key="i"
|
||||
v-show="loading"
|
||||
/>
|
||||
<group-card
|
||||
v-for="group in selectedGroups"
|
||||
:key="group.id"
|
||||
:group="group"
|
||||
:mode="'column'"
|
||||
:showSummary="false"
|
||||
/>
|
||||
|
||||
<more-content
|
||||
v-if="userLocationName"
|
||||
:to="{
|
||||
name: RouteName.SEARCH,
|
||||
query: {
|
||||
locationName: userLocationName,
|
||||
lat: userLocation.lat?.toString(),
|
||||
lon: userLocation.lon?.toString(),
|
||||
contentType: 'GROUPS',
|
||||
distance: `${distance}_km`,
|
||||
},
|
||||
}"
|
||||
:picture="userLocation.picture"
|
||||
>
|
||||
{{
|
||||
t("View more groups around {position}", {
|
||||
position: userLocationName,
|
||||
})
|
||||
}}
|
||||
</more-content>
|
||||
</template>
|
||||
</close-content>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import SkeletonGroupResult from "@/components/Group/SkeletonGroupResult.vue";
|
||||
import sampleSize from "lodash/sampleSize";
|
||||
import { LocationType } from "@/types/user-location.model";
|
||||
import MoreContent from "./MoreContent.vue";
|
||||
import CloseContent from "./CloseContent.vue";
|
||||
import { IGroup } from "@/types/actor";
|
||||
import { SEARCH_GROUPS } from "@/graphql/search";
|
||||
import { useQuery } from "@vue/apollo-composable";
|
||||
import { Paginate } from "@/types/paginate";
|
||||
import { computed } from "vue";
|
||||
import GroupCard from "@/components/Group/GroupCard.vue";
|
||||
import { coordsToGeoHash } from "@/utils/location";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import RouteName from "@/router/name";
|
||||
|
||||
const props = defineProps<{
|
||||
userLocation: LocationType;
|
||||
doingGeoloc?: boolean;
|
||||
}>();
|
||||
const emit = defineEmits(["doGeoLoc"]);
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const userLocation = computed(() => props.userLocation);
|
||||
|
||||
const geoHash = computed(() =>
|
||||
coordsToGeoHash(userLocation.value.lat, userLocation.value.lon)
|
||||
);
|
||||
|
||||
const distance = computed<number>(() =>
|
||||
userLocation.value?.isIPLocation ? 150 : 25
|
||||
);
|
||||
|
||||
const { result: groupsResult, loading: loadingGroups } = useQuery<{
|
||||
searchGroups: Paginate<IGroup>;
|
||||
}>(
|
||||
SEARCH_GROUPS,
|
||||
() => ({
|
||||
location: geoHash.value,
|
||||
radius: distance.value,
|
||||
page: 1,
|
||||
limit: 12,
|
||||
}),
|
||||
() => ({ enabled: geoHash.value !== undefined })
|
||||
);
|
||||
|
||||
const groups = computed(
|
||||
() => groupsResult.value?.searchGroups ?? { total: 0, elements: [] }
|
||||
);
|
||||
|
||||
const selectedGroups = computed(() => sampleSize(groups.value?.elements, 5));
|
||||
|
||||
const userLocationName = computed(() => props?.userLocation?.name);
|
||||
|
||||
const loading = computed(() => props.doingGeoloc || loadingGroups.value);
|
||||
</script>
|
||||
78
src/components/Local/LastEvents.vue
Normal file
78
src/components/Local/LastEvents.vue
Normal file
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<close-content
|
||||
class="container mx-auto px-2"
|
||||
v-show="loadingEvents || (events && events.total > 0)"
|
||||
:suggestGeoloc="false"
|
||||
v-on="attrs"
|
||||
>
|
||||
<template #title>
|
||||
{{ t("Last published events") }}
|
||||
</template>
|
||||
<template #subtitle>
|
||||
<i18n-t
|
||||
class="text-slate-700 dark:text-slate-300"
|
||||
tag="p"
|
||||
keypath="On {instance} and other federated instances"
|
||||
>
|
||||
<template #instance>
|
||||
<b>{{ instanceName }}</b>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</template>
|
||||
<template #content>
|
||||
<skeleton-event-result
|
||||
v-for="i in 6"
|
||||
class="scroll-ml-6 snap-center shrink-0 w-[18rem] my-4"
|
||||
:key="i"
|
||||
v-show="loadingEvents"
|
||||
/>
|
||||
<event-card
|
||||
v-for="event in events.elements"
|
||||
:event="event"
|
||||
:key="event.uuid"
|
||||
/>
|
||||
<more-content
|
||||
:to="{
|
||||
name: RouteName.SEARCH,
|
||||
query: {
|
||||
contentType: 'EVENTS',
|
||||
},
|
||||
}"
|
||||
>
|
||||
{{ t("View more events") }}
|
||||
</more-content>
|
||||
</template>
|
||||
</close-content>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import MoreContent from "./MoreContent.vue";
|
||||
import CloseContent from "./CloseContent.vue";
|
||||
import { computed, useAttrs } from "vue";
|
||||
import { IEvent } from "@/types/event.model";
|
||||
import { useQuery } from "@vue/apollo-composable";
|
||||
import EventCard from "../Event/EventCard.vue";
|
||||
import { Paginate } from "@/types/paginate";
|
||||
import SkeletonEventResult from "../Event/SkeletonEventResult.vue";
|
||||
import { EventSortField, SortDirection } from "@/types/enums";
|
||||
import { FETCH_EVENTS } from "@/graphql/event";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import RouteName from "@/router/name";
|
||||
|
||||
defineProps<{
|
||||
instanceName: string;
|
||||
}>();
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
const attrs = useAttrs();
|
||||
|
||||
const { result: resultEvents, loading: loadingEvents } = useQuery<{
|
||||
events: Paginate<IEvent>;
|
||||
}>(FETCH_EVENTS, {
|
||||
orderBy: EventSortField.INSERTED_AT,
|
||||
direction: SortDirection.DESC,
|
||||
});
|
||||
const events = computed(
|
||||
() => resultEvents.value?.events ?? { total: 0, elements: [] }
|
||||
);
|
||||
</script>
|
||||
93
src/components/Local/MoreContent.vue
Normal file
93
src/components/Local/MoreContent.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<router-link
|
||||
:to="to"
|
||||
class="mbz-card flex flex-col items-center dark:border-gray-700 shadow-md md:flex-col snap-center shrink-0 first:pl-8 w-[18rem] dark:bg-mbz-purple"
|
||||
>
|
||||
<div class="relative w-full group">
|
||||
<img
|
||||
v-if="picture"
|
||||
class="object-cover h-40 w-full rounded-t-lg"
|
||||
:src="picture.url"
|
||||
width="350"
|
||||
alt=""
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="absolute top-0 left-0 h-full w-full">
|
||||
<div
|
||||
class="custom-overlay opacity-0 invisible group-hover:opacity-100 group-hover:visible absolute left-0 h-full w-full transition-opacity"
|
||||
/>
|
||||
<div
|
||||
class="opacity-0 invisible group-hover:opacity-100 group-hover:visible absolute left-0 h-full w-full"
|
||||
>
|
||||
<p class="absolute text-sm text-white left-1 bottom-1.5 px-1">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="inline h-5 w-5 pr-1"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
<span
|
||||
@click="(e) => e.stopPropagation()"
|
||||
class="align-bottom"
|
||||
v-html="
|
||||
$t('Photo by {author} on {source}', {
|
||||
author: imageAuthor,
|
||||
source: imageSource,
|
||||
})
|
||||
"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex h-full justify-between self-end flex-col p-2 pt-1 md:p-4 md:pt-2 leading-normal w-full"
|
||||
>
|
||||
<h2
|
||||
class="mb-2 text-xl font-bold tracking-tight text-violet-title dark:text-white"
|
||||
>
|
||||
<slot name="default" />
|
||||
</h2>
|
||||
</div>
|
||||
</router-link>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import { CategoryPictureLicencing } from "../Categories/constants";
|
||||
|
||||
const props = defineProps<{
|
||||
to: { name: string; query: Record<string, string | undefined> };
|
||||
picture?: CategoryPictureLicencing & { url: string };
|
||||
}>();
|
||||
|
||||
const imageAuthor = computed(
|
||||
() =>
|
||||
`<a target="_blank" class="underline font-medium" href="${props.picture?.author?.url}">${props.picture?.author?.name}</a>`
|
||||
);
|
||||
const imageSource = computed(
|
||||
() =>
|
||||
`<a target="_blank" class="underline font-medium" href="${props.picture?.source?.url}">${props.picture?.source?.name}</a>`
|
||||
);
|
||||
</script>
|
||||
<style>
|
||||
.custom-overlay {
|
||||
background-image: linear-gradient(
|
||||
180deg,
|
||||
rgba(0, 0, 0, 0) 0%,
|
||||
rgba(0, 0, 0, 0) 25%,
|
||||
rgba(2, 0, 36, 0.75) 90%,
|
||||
rgba(2, 0, 36, 0.85) 100%
|
||||
);
|
||||
transition:
|
||||
opacity 0.1s ease-in-out,
|
||||
visibility 0.1s ease-in-out;
|
||||
}
|
||||
</style>
|
||||
75
src/components/Local/OnlineEvents.vue
Normal file
75
src/components/Local/OnlineEvents.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<close-content
|
||||
class="container mx-auto px-2"
|
||||
:suggest-geoloc="false"
|
||||
v-show="loadingEvents || (events?.elements && events?.elements.length > 0)"
|
||||
>
|
||||
<template #title>
|
||||
{{ $t("Online upcoming events") }}
|
||||
</template>
|
||||
<template #content>
|
||||
<skeleton-event-result
|
||||
v-for="i in [...Array(6).keys()]"
|
||||
class="scroll-ml-6 snap-center shrink-0 w-[18rem] my-4"
|
||||
:key="i"
|
||||
v-show="loadingEvents"
|
||||
/>
|
||||
<event-card
|
||||
class="scroll-ml-6 snap-center shrink-0 first:pl-8 last:pr-8 w-[18rem]"
|
||||
v-for="event in events?.elements"
|
||||
:key="event.id"
|
||||
:event="event"
|
||||
mode="column"
|
||||
/>
|
||||
<more-content
|
||||
:to="{
|
||||
name: RouteName.SEARCH,
|
||||
query: {
|
||||
contentType: 'EVENTS',
|
||||
isOnline: 'true',
|
||||
},
|
||||
}"
|
||||
:picture="{
|
||||
url: '/img/online-event.webp',
|
||||
author: {
|
||||
name: 'Chris Montgomery',
|
||||
url: 'https://unsplash.com/@cwmonty',
|
||||
},
|
||||
source: {
|
||||
name: 'Unsplash',
|
||||
url: 'https://unsplash.com/?utm_source=Mobilizon&utm_medium=referral',
|
||||
},
|
||||
}"
|
||||
>
|
||||
{{ $t("View more online events") }}
|
||||
</more-content>
|
||||
</template>
|
||||
</close-content>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import SkeletonEventResult from "@/components/Event/SkeletonEventResult.vue";
|
||||
import MoreContent from "./MoreContent.vue";
|
||||
import CloseContent from "./CloseContent.vue";
|
||||
import { SEARCH_EVENTS } from "@/graphql/search";
|
||||
import EventCard from "@/components/Event/EventCard.vue";
|
||||
import { useQuery } from "@vue/apollo-composable";
|
||||
import RouteName from "@/router/name";
|
||||
import { Paginate } from "@/types/paginate";
|
||||
import { IEvent } from "@/types/event.model";
|
||||
|
||||
const EVENT_PAGE_LIMIT = 12;
|
||||
|
||||
const { result: searchEventResult, loading: loadingEvents } = useQuery<{
|
||||
searchEvents: Paginate<IEvent>;
|
||||
}>(SEARCH_EVENTS, () => ({
|
||||
beginsOn: new Date(),
|
||||
endsOn: undefined,
|
||||
eventPage: 1,
|
||||
limit: EVENT_PAGE_LIMIT,
|
||||
type: "ONLINE",
|
||||
}));
|
||||
|
||||
const events = computed(() => searchEventResult.value?.searchEvents);
|
||||
</script>
|
||||
Reference in New Issue
Block a user