Replaces custom expand/collapse with Collapsible
Migrates ScheduledEventCard to use the Collapsible component from the UI library. This simplifies the component's structure and improves accessibility by leveraging the built-in features of the Collapsible component. Removes custom logic for managing the expanded/collapsed state.
This commit is contained in:
parent
abaf7f2f5b
commit
9aa8c28bef
1 changed files with 68 additions and 90 deletions
|
|
@ -10,6 +10,11 @@ import {
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
} from '@/components/ui/dialog'
|
} from '@/components/ui/dialog'
|
||||||
|
import {
|
||||||
|
Collapsible,
|
||||||
|
CollapsibleContent,
|
||||||
|
CollapsibleTrigger,
|
||||||
|
} from '@/components/ui/collapsible'
|
||||||
import { Calendar, MapPin, Clock, CheckCircle } from 'lucide-vue-next'
|
import { Calendar, MapPin, Clock, CheckCircle } from 'lucide-vue-next'
|
||||||
import type { ScheduledEvent, EventCompletion } from '../services/ScheduledEventService'
|
import type { ScheduledEvent, EventCompletion } from '../services/ScheduledEventService'
|
||||||
|
|
||||||
|
|
@ -33,9 +38,6 @@ const emit = defineEmits<Emits>()
|
||||||
// Confirmation dialog state
|
// Confirmation dialog state
|
||||||
const showConfirmDialog = ref(false)
|
const showConfirmDialog = ref(false)
|
||||||
|
|
||||||
// Collapsed state (collapsed by default)
|
|
||||||
const isExpanded = ref(false)
|
|
||||||
|
|
||||||
// Event address for tracking completion
|
// Event address for tracking completion
|
||||||
const eventAddress = computed(() => `31922:${props.event.pubkey}:${props.event.dTag}`)
|
const eventAddress = computed(() => `31922:${props.event.pubkey}:${props.event.dTag}`)
|
||||||
|
|
||||||
|
|
@ -116,81 +118,56 @@ function confirmMarkComplete() {
|
||||||
function cancelMarkComplete() {
|
function cancelMarkComplete() {
|
||||||
showConfirmDialog.value = false
|
showConfirmDialog.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle expanded/collapsed state
|
|
||||||
function toggleExpanded() {
|
|
||||||
isExpanded.value = !isExpanded.value
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="border-b md:border md:rounded-lg bg-card transition-all"
|
<Collapsible class="border-b md:border md:rounded-lg bg-card transition-all"
|
||||||
:class="{ 'opacity-60': isCompletable && isCompleted }">
|
:class="{ 'opacity-60': isCompletable && isCompleted }">
|
||||||
|
<!-- Collapsed View (Trigger) -->
|
||||||
<!-- Collapsed View (Default) -->
|
<CollapsibleTrigger as-child>
|
||||||
<div v-if="!isExpanded"
|
<div class="flex items-center gap-3 p-3 md:p-4 cursor-pointer hover:bg-accent/50 transition-colors">
|
||||||
class="flex items-center gap-3 p-3 md:p-4">
|
<!-- Time -->
|
||||||
<!-- Time -->
|
<div class="flex items-center gap-1.5 text-sm text-muted-foreground shrink-0">
|
||||||
<div @click="toggleExpanded" class="flex items-center gap-1.5 text-sm text-muted-foreground shrink-0 cursor-pointer">
|
<Clock class="h-3.5 w-3.5" />
|
||||||
<Clock class="h-3.5 w-3.5" />
|
<span class="font-medium">{{ formattedTimeRange || formattedDate }}</span>
|
||||||
<span class="font-medium">{{ formattedTimeRange || formattedDate }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Title -->
|
|
||||||
<h3 @click="toggleExpanded"
|
|
||||||
class="font-semibold text-sm md:text-base flex-1 truncate cursor-pointer hover:text-foreground/80 transition-colors"
|
|
||||||
:class="{ 'line-through': isCompletable && isCompleted }">
|
|
||||||
{{ event.title }}
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<!-- Badges and Actions -->
|
|
||||||
<div class="flex items-center gap-2 shrink-0">
|
|
||||||
<!-- Mark Complete Button (for uncompleted tasks) -->
|
|
||||||
<Button
|
|
||||||
v-if="isCompletable && !isCompleted"
|
|
||||||
@click.stop="handleMarkComplete"
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
class="h-7 w-7 p-0"
|
|
||||||
>
|
|
||||||
<CheckCircle class="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<!-- Completed Badge -->
|
|
||||||
<Badge v-if="isCompletable && isCompleted" variant="secondary" class="text-xs">
|
|
||||||
✓
|
|
||||||
</Badge>
|
|
||||||
|
|
||||||
<!-- Admin Badge -->
|
|
||||||
<Badge v-if="isAdminEvent" variant="secondary" class="text-xs">
|
|
||||||
Admin
|
|
||||||
</Badge>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Expanded View -->
|
|
||||||
<div v-else class="p-4 md:p-6">
|
|
||||||
<!-- Event Details -->
|
|
||||||
<div class="flex-1 min-w-0">
|
|
||||||
<!-- Title and badges with close button -->
|
|
||||||
<div class="flex items-start gap-2 mb-2 flex-wrap">
|
|
||||||
<h3 class="font-semibold text-base md:text-lg flex-1"
|
|
||||||
:class="{ 'line-through': isCompletable && isCompleted }">
|
|
||||||
{{ event.title }}
|
|
||||||
</h3>
|
|
||||||
<Badge v-if="isAdminEvent" variant="secondary" class="shrink-0">
|
|
||||||
Admin
|
|
||||||
</Badge>
|
|
||||||
<Button
|
|
||||||
@click="toggleExpanded"
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
class="h-6 w-6 p-0 shrink-0"
|
|
||||||
>
|
|
||||||
✕
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Title -->
|
||||||
|
<h3 class="font-semibold text-sm md:text-base flex-1 truncate"
|
||||||
|
:class="{ 'line-through': isCompletable && isCompleted }">
|
||||||
|
{{ event.title }}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<!-- Badges and Actions -->
|
||||||
|
<div class="flex items-center gap-2 shrink-0">
|
||||||
|
<!-- Mark Complete Button (for uncompleted tasks) -->
|
||||||
|
<Button
|
||||||
|
v-if="isCompletable && !isCompleted"
|
||||||
|
@click.stop="handleMarkComplete"
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
class="h-7 w-7 p-0"
|
||||||
|
>
|
||||||
|
<CheckCircle class="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<!-- Completed Badge -->
|
||||||
|
<Badge v-if="isCompletable && isCompleted" variant="secondary" class="text-xs">
|
||||||
|
✓
|
||||||
|
</Badge>
|
||||||
|
|
||||||
|
<!-- Admin Badge -->
|
||||||
|
<Badge v-if="isAdminEvent" variant="secondary" class="text-xs">
|
||||||
|
Admin
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CollapsibleTrigger>
|
||||||
|
|
||||||
|
<!-- Expanded View (Content) -->
|
||||||
|
<CollapsibleContent class="p-4 md:p-6 pt-0">
|
||||||
|
<!-- Event Details -->
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
<!-- Date/Time -->
|
<!-- Date/Time -->
|
||||||
<div class="flex items-center gap-4 text-sm text-muted-foreground mb-2 flex-wrap">
|
<div class="flex items-center gap-4 text-sm text-muted-foreground mb-2 flex-wrap">
|
||||||
<div class="flex items-center gap-1.5">
|
<div class="flex items-center gap-1.5">
|
||||||
|
|
@ -238,22 +215,23 @@ function toggleExpanded() {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</CollapsibleContent>
|
||||||
|
|
||||||
<!-- Confirmation Dialog -->
|
</Collapsible>
|
||||||
<Dialog :open="showConfirmDialog" @update:open="(val: boolean) => showConfirmDialog = val">
|
|
||||||
<DialogContent>
|
<!-- Confirmation Dialog -->
|
||||||
<DialogHeader>
|
<Dialog :open="showConfirmDialog" @update:open="(val: boolean) => showConfirmDialog = val">
|
||||||
<DialogTitle>Mark Event as Complete?</DialogTitle>
|
<DialogContent>
|
||||||
<DialogDescription>
|
<DialogHeader>
|
||||||
This will mark "{{ event.title }}" as completed by you. Other users will be able to see that you completed this event.
|
<DialogTitle>Mark Event as Complete?</DialogTitle>
|
||||||
</DialogDescription>
|
<DialogDescription>
|
||||||
</DialogHeader>
|
This will mark "{{ event.title }}" as completed by you. Other users will be able to see that you completed this event.
|
||||||
<DialogFooter>
|
</DialogDescription>
|
||||||
<Button variant="outline" @click="cancelMarkComplete">Cancel</Button>
|
</DialogHeader>
|
||||||
<Button @click="confirmMarkComplete">Mark Complete</Button>
|
<DialogFooter>
|
||||||
</DialogFooter>
|
<Button variant="outline" @click="cancelMarkComplete">Cancel</Button>
|
||||||
</DialogContent>
|
<Button @click="confirmMarkComplete">Mark Complete</Button>
|
||||||
</Dialog>
|
</DialogFooter>
|
||||||
</div>
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue