feat(03-06): wire EventDetailPopover Edit/Delete footer and implement DeleteConfirmationDialog
- EventDetailPopover: replace aria-hidden placeholder with Edit2/Trash2 footer buttons - Edit opens EventForm in edit mode and closes popover - Delete opens DeleteConfirmationDialog via setDeleteDialog (T-03-17 two-tap) - DeleteConfirmationDialog: centered modal, max-width 320px, backdrop + focus trap - heading 'Delete event?', Fastmail body copy per UI-SPEC - Cancel/Escape close without deleting; Delete fires mutation - On success: setLastSyncedUid (feeds SyncStateToast), close dialog + popover - TanStack mutation; 48px Delete button (--color-destructive) - CalendarShell: mount DeleteConfirmationDialog in both phone and tablet/desktop layouts
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { MapPin } from 'lucide-react'
|
||||
import { MapPin, Edit2, Trash2 } from 'lucide-react'
|
||||
import { useCalendarStore } from '../store/calendarStore.js'
|
||||
import type { CalendarOccurrence } from '../api/client.js'
|
||||
|
||||
@@ -107,6 +107,8 @@ function formatDateTime(start: string, end: string, allDay: boolean): string {
|
||||
*/
|
||||
export function EventDetailPopover(props: ScheduleXEventModalProps = {}) {
|
||||
const { openEventId, setOpenEventId } = useCalendarStore()
|
||||
const setEventForm = useCalendarStore((s) => s.setEventForm)
|
||||
const setDeleteDialog = useCalendarStore((s) => s.setDeleteDialog)
|
||||
const queryClient = useQueryClient()
|
||||
const dialogRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
@@ -377,14 +379,76 @@ export function EventDetailPopover(props: ScheduleXEventModalProps = {}) {
|
||||
: (occurrence.ownerName ?? occurrence.calendarName)}
|
||||
</div>
|
||||
|
||||
{/* Phase 3 footer action area — Phase 3 adds edit/delete actions here (D-08) */}
|
||||
{/* Phase 3 footer: Edit / Delete actions (D-10) */}
|
||||
<div
|
||||
aria-hidden="true"
|
||||
style={{
|
||||
// Reserved: empty in Phase 2 (read-only); Phase 3 wires edit/delete buttons here
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginTop: 'var(--space-4)',
|
||||
paddingTop: 'var(--space-3)',
|
||||
borderTop: '1px solid var(--color-border-subtle)',
|
||||
}}
|
||||
/>
|
||||
>
|
||||
{/* Edit button — ghost style, left-aligned */}
|
||||
<button
|
||||
aria-label="Edit event"
|
||||
onClick={() => {
|
||||
setEventForm(true, 'edit', occurrence.uid)
|
||||
setOpenEventId(null)
|
||||
}}
|
||||
style={{
|
||||
background: 'none',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
minWidth: '44px',
|
||||
minHeight: '44px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 'var(--space-1)',
|
||||
fontSize: 'var(--text-label-size)',
|
||||
fontWeight: 'var(--text-label-weight)',
|
||||
color: 'var(--color-text-primary)',
|
||||
borderRadius: 'var(--space-1)',
|
||||
padding: '0 var(--space-2)',
|
||||
fontFamily: 'var(--font-family-base)',
|
||||
}}
|
||||
>
|
||||
<Edit2 size={16} aria-hidden="true" />
|
||||
{/* Plain text — XSS guard */}
|
||||
Edit
|
||||
</button>
|
||||
|
||||
{/* Delete button — ghost style, right-aligned, destructive color */}
|
||||
<button
|
||||
aria-label="Delete event"
|
||||
onClick={() => {
|
||||
setDeleteDialog(true, occurrence.uid)
|
||||
}}
|
||||
style={{
|
||||
background: 'none',
|
||||
border: 'none',
|
||||
cursor: 'pointer',
|
||||
minWidth: '44px',
|
||||
minHeight: '44px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 'var(--space-1)',
|
||||
fontSize: 'var(--text-label-size)',
|
||||
fontWeight: 'var(--text-label-weight)',
|
||||
color: 'var(--color-destructive)',
|
||||
borderRadius: 'var(--space-1)',
|
||||
padding: '0 var(--space-2)',
|
||||
fontFamily: 'var(--font-family-base)',
|
||||
}}
|
||||
>
|
||||
<Trash2 size={16} aria-hidden="true" />
|
||||
{/* Plain text — XSS guard */}
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user