Skip activities with invalid dates in calendar view
Prevents RangeError from format() on activities with unparseable start timestamps. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4926c3a313
commit
8a3ff14568
3 changed files with 20 additions and 3 deletions
|
|
@ -37,6 +37,7 @@ const calendarDays = computed(() => {
|
||||||
const activityDayMap = computed(() => {
|
const activityDayMap = computed(() => {
|
||||||
const map = new Map<string, Activity[]>()
|
const map = new Map<string, Activity[]>()
|
||||||
for (const activity of props.activities) {
|
for (const activity of props.activities) {
|
||||||
|
if (!activity.startDate || isNaN(activity.startDate.getTime())) continue
|
||||||
const key = format(activity.startDate, 'yyyy-MM-dd')
|
const key = format(activity.startDate, 'yyyy-MM-dd')
|
||||||
if (!map.has(key)) map.set(key, [])
|
if (!map.has(key)) map.set(key, [])
|
||||||
map.get(key)!.push(activity)
|
map.get(key)!.push(activity)
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ export const activitiesModule = createModulePlugin({
|
||||||
component: () => import('./views/ActivitiesFavoritesPage.vue'),
|
component: () => import('./views/ActivitiesFavoritesPage.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Favorites',
|
title: 'Favorites',
|
||||||
requiresAuth: true,
|
requiresAuth: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { computed, onMounted } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { Heart } from 'lucide-vue-next'
|
import { Heart } from 'lucide-vue-next'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { toast } from 'vue-sonner'
|
||||||
import { useAuth } from '@/composables/useAuthService'
|
import { useAuth } from '@/composables/useAuthService'
|
||||||
import { useBookmarks } from '../composables/useBookmarks'
|
import { useBookmarks } from '../composables/useBookmarks'
|
||||||
import { useActivitiesStore } from '../stores/activities'
|
import { useActivitiesStore } from '../stores/activities'
|
||||||
|
|
@ -20,6 +22,17 @@ const favoriteActivities = computed(() => {
|
||||||
function handleSelect(activity: Activity) {
|
function handleSelect(activity: Activity) {
|
||||||
router.push({ name: 'activity-detail', params: { id: activity.id } })
|
router.push({ name: 'activity-detail', params: { id: activity.id } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (!isAuthenticated.value) {
|
||||||
|
toast.info('Log in to save favorites', {
|
||||||
|
action: {
|
||||||
|
label: 'Log in',
|
||||||
|
onClick: () => router.push('/login'),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -29,7 +42,10 @@ function handleSelect(activity: Activity) {
|
||||||
<!-- Not authenticated -->
|
<!-- Not authenticated -->
|
||||||
<div v-if="!isAuthenticated" class="flex flex-col items-center justify-center py-16 text-center">
|
<div v-if="!isAuthenticated" class="flex flex-col items-center justify-center py-16 text-center">
|
||||||
<Heart class="w-16 h-16 text-muted-foreground/30 mb-4" />
|
<Heart class="w-16 h-16 text-muted-foreground/30 mb-4" />
|
||||||
<p class="text-muted-foreground">Log in to save your favorite activities</p>
|
<p class="text-muted-foreground mb-3">Log in to save your favorite activities</p>
|
||||||
|
<Button variant="outline" size="sm" @click="router.push('/login')">
|
||||||
|
Log in
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Loading -->
|
<!-- Loading -->
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue