Enhance month view overlay with preview, auto-scroll, and 1s delay

- Fix backend type comparison in AvailabilityService (int vs string)
- Add durationMinutes to month overlay drop to fix end_time calculation
- Add live preview of dragged appointment in overlay with lane splitting
- Implement horizontal auto-scroll when dragging to overlay edges
- Add 1-second delay before overlay appears for easier date navigation
- Remove redundant drop zone highlight (preview shows position)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
poduck
2025-11-27 21:48:34 -05:00
parent 2a95b007e2
commit 86a4e87ed6
4 changed files with 625 additions and 157 deletions

View File

@@ -82,7 +82,7 @@ class ResourceSerializer(serializers.ModelSerializer):
fields = [
'id', 'name', 'type', 'description', 'max_concurrent_events',
'buffer_duration', 'is_active', 'capacity_description',
'created_at', 'updated_at',
'saved_lane_count', 'created_at', 'updated_at',
]
read_only_fields = ['created_at', 'updated_at']
@@ -196,16 +196,28 @@ class EventSerializer(serializers.ModelSerializer):
def validate(self, attrs):
"""
Validate event timing and resource availability.
Checks:
1. end_time > start_time
2. start_time not in past (for new events)
3. Resource availability using AvailabilityService
"""
# For partial updates, get existing values from instance if not provided
start_time = attrs.get('start_time')
end_time = attrs.get('end_time')
resource_ids = attrs.get('resource_ids', [])
# If this is a partial update, fill in missing values from existing instance
if self.instance:
if start_time is None:
start_time = self.instance.start_time
if end_time is None:
end_time = self.instance.end_time
# Skip validation if we still don't have both times (shouldn't happen for valid requests)
if start_time is None or end_time is None:
return attrs
# Validation 1: End must be after start
if end_time <= start_time:
raise serializers.ValidationError({

View File

@@ -48,7 +48,8 @@ class AvailabilityService:
event = participant.event
# Skip if this is the event being updated
if exclude_event_id and event.id == exclude_event_id:
# CRITICAL: Convert exclude_event_id to int for comparison (frontend may send string)
if exclude_event_id and event.id == int(exclude_event_id):
continue
# CRITICAL: Skip cancelled events (prevents ghost bookings)