- Configure Caddy to proxy /api requests to backend service
- Add favicon_big.png for various icon size needs
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add favicon.ico as site favicon using Trunk asset pipeline
- Remove calendar.db from git tracking (already in .gitignore)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Set all_day flag properly when creating VEvent in series handler
- Improve all-day event detection using VALUE=DATE parameter
- Add RFC-5545 compliance for exclusive end dates (backend adds 1 day)
- Fix end date display in event modal (frontend subtracts 1 day for display)
- Fix recurring all-day event expansion to maintain proper end date pattern
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added intelligent viewport boundary detection that repositions context
menus when they would appear outside the screen:
- Detects right/bottom edge overflow and repositions menus accordingly
- Uses accurate size estimates based on actual menu content
- Event menus: 280×200px (recurring) / 180×100px (non-recurring)
- Calendar/generic menus: 180×60px for single items
- Maintains 5px minimum margins from screen edges
- Graceful fallback to original positioning if viewport detection fails
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
All-day events now have the same right-click context menu functionality
as regular timed events, allowing users to edit, delete, and perform
other actions on all-day events.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously filtered events by start date only, which excluded recurring
events that started in previous months/years but have instances in the
current month.
New logic:
- Non-recurring events: filter by exact month match (unchanged)
- Recurring events: include if they could have instances in requested month
- Check event start date is before/during month
- Parse RRULE UNTIL date to exclude expired recurring events
- Let frontend handle proper RRULE expansion
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add fallback registry to prevent invalid tag format
- Make Docker login conditional on secrets being present
- Make push conditional on registry being configured
- Rename Docker image from calendar to runway
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented clustering algorithm in calculate_event_layout that:
- Only creates column splits for events that actually overlap
- Non-overlapping events maintain full width display
- Uses greedy column assignment for overlapping groups
- Preserves proper column indices for each event
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Backend fixes:
- Fix all-day event creation validation error
- Allow same start/end date for all-day events (single-day events)
- Maintain strict validation for timed events (end must be after start)
Frontend improvements:
- Move all-day events from time grid to day headers
- Add dedicated all-day events container that stacks vertically
- Filter all-day events out of main time-based events area
- Add proper CSS styling for all-day event display and interaction
- Maintain event click handling and color themes
All-day events now appear in the correct location at the top of each
day column and properly stack when multiple events exist.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update project name in Cargo.toml from calendar-app to runway
- Change HTML title and sidebar header to 'Runway'
- Complete README rewrite with new branding and philosophy
- Add 'The Name' section explaining runway metaphor as passive infrastructure
- Update Dockerfile build references to use new binary name
- Maintain all technical documentation with new branding context
The name 'Runway' embodies passive infrastructure that enables coordination
without getting in the way - like airport runways that provide essential
structure for planes but stay invisible during flight.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix drag-to-create being blocked by existing events
- Add creating-event CSS class that disables pointer events on existing events
- Fix single clicks creating temporary event boxes
- Add mouse button state check to prevent post-mouseup movement being treated as drag
- Ensure temp event boxes only appear during actual drag operations (has_moved=true)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add overlap detection algorithm to identify overlapping events
- Implement layout calculation to arrange events in columns
- Update event positioning to use dynamic left/width instead of fixed right
- Events now render side-by-side when they overlap in time
- Maintains proper spacing and margins for all event arrangements
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove unnecessary boundary slot from week view time grid
- Adjust container heights to display full 11 PM - midnight time slot
- Fix timezone issue preventing events at 8 PM or later from rendering
- Update date matching logic to handle UTC-4 timezone offset correctly
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit adds a complete style system alongside the existing theme system, allowing users to switch between different UI styles while maintaining theme color variations.
**Core Features:**
- Style enum (Default, Google Calendar) separate from Theme enum
- Hot-swappable stylesheets with dynamic loading
- Style preference persistence (localStorage + database)
- Style picker UI in sidebar below theme picker
**Frontend Implementation:**
- Add Style enum to sidebar.rs with value/display methods
- Implement dynamic stylesheet loading in app.rs
- Add style picker dropdown with proper styling
- Handle style state management and persistence
- Add web-sys features for HtmlLinkElement support
**Backend Integration:**
- Add calendar_style column to user_preferences table
- Update all database operations (insert/update/select)
- Extend API models for style preference
- Add migration for existing users
**Google Calendar Style:**
- Clean Material Design-inspired interface
- White sidebar with proper contrast
- Enhanced calendar grid with subtle shadows
- Improved event styling with hover effects
- Google Sans typography throughout
- Professional color scheme and spacing
**Technical Details:**
- Trunk asset management for stylesheet copying
- High CSS specificity to override theme styles
- Modular CSS architecture for easy extensibility
- Comprehensive text contrast fixes
- Enhanced calendar cells and navigation
Users can now choose between the original gradient design (Default) and a clean Google Calendar-inspired interface (Google Calendar), with full preference persistence across sessions.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added comprehensive Docker Compose deployment section as recommended method
- Documented automatic database migrations and persistent storage
- Updated architecture section to mention SQLite auth system
- Added new User Experience section highlighting session management
- Reorganized development setup with local database migration instructions
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create /db directory in container
- Ensure database directory exists and has proper permissions in startup script
- Remove problematic conditional COPY command that was causing build failures
This fixes the 'unable to open database file' error by ensuring the
database directory exists before migrations run.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Install sqlx-cli in backend builder stage
- Copy migrations and sqlx binary to runtime image
- Run database migrations automatically on container startup
- Add error handling to prevent startup failure if migrations already applied
This ensures the database schema is always up to date when deploying
with Docker, eliminating manual migration steps.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remember checkboxes now default to checked for better user experience
- Reduced visual prominence with smaller size, lighter colors, and lower opacity
- Users get convenience by default while still being able to opt out
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added SQLite database for session management and user preferences storage,
allowing users to have consistent settings across different sessions and devices.
Backend changes:
- Added SQLite database with users, sessions, and preferences tables
- Implemented session-based authentication alongside JWT tokens
- Created preference storage/retrieval API endpoints
- Database migrations for schema setup
- Session validation and cleanup functionality
Frontend changes:
- Added "Remember server" and "Remember username" checkboxes to login
- Created preferences service for syncing settings with backend
- Updated auth flow to handle session tokens and preferences
- Store remembered values in LocalStorage (not database) for convenience
Key features:
- User preferences persist across sessions and devices
- CalDAV passwords never stored, only passed through
- Sessions expire after 24 hours
- Remember checkboxes only affect local browser storage
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Moved event fetching logic from CalendarView to Calendar component to properly
use the visible date range instead of hardcoded current month. The Calendar
component already tracks the current visible date through navigation, so events
now load correctly for August and other months when navigating.
Changes:
- Calendar component now manages its own events state and fetching
- Event fetching responds to current_date changes from navigation
- CalendarView simplified to just render Calendar component
- Fixed cargo fmt/clippy formatting across codebase
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Removed Obsolete Environment Variables:
- `CALDAV_SERVER_URL` - provided by user login
- `CALDAV_USERNAME` - provided by user login
- `CALDAV_PASSWORD` - provided by user login
- `CALDAV_TASKS_PATH` - not used in any features
## Kept with Intelligent Discovery:
- `CALDAV_CALENDAR_PATH` - optional override, defaults to smart discovery
## Changes:
### Backend
- Remove `CalDAVConfig::from_env()` method (not used in main app)
- Add `CalDAVConfig::new()` constructor with credentials
- Remove `tasks_path` field from CalDAVConfig
- Update auth service to use new constructor
- Update tests to use hardcoded test values instead of env vars
- Update debug tools to use test credentials
### Frontend
- Remove unused `config.rs` file entirely (frontend uses backend API)
## Current Authentication Flow:
1. User provides CalDAV credentials via login API
2. Backend creates CalDAVConfig dynamically from login request
3. Backend tests authentication via calendar discovery
4. Optional `CALDAV_CALENDAR_PATH` env var can override discovery
5. No environment variables required for normal operation
This simplifies deployment - users only need to provide CalDAV
credentials through the web interface, no server-side configuration required.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The modal update flow was calling the regular event update endpoint
instead of the series endpoint, preventing proper handling of the
three edit types (this event, this and future, all events).
## Changes:
- Add logic to detect when edit_scope is set for recurring events
- Route to update_series() when edit_scope is present and event has RRULE
- Map EditAction enum to backend update_scope strings:
- EditThis → "this_only" (creates exception + EXDATE)
- EditFuture → "this_and_future" (new series + UNTIL on original)
- EditAll → "all_in_series" (update existing series)
- Pass occurrence date for single/future edits using original event date
- Fall back to regular update_event() for non-recurring events
Now the modal properly leverages the existing robust series endpoint
that handles RFC 5545 compliant recurring event modifications.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Frontend Changes:
- Add EditAction enum (EditThis, EditFuture, EditAll) to event context menu
- Update context menu to show 3 edit options for recurring events
- Enhance EventCreationData with edit_scope and changed_fields tracking
- Update app component to handle EditAction types and pass to modal
- Add field change tracking infrastructure to CreateEventModal
## Backend Changes:
- Add changed_fields parameter to UpdateEventSeriesRequest for optimization
- Existing series endpoint already supports the three update types:
- "this_only" - creates exception with EXDATE
- "this_and_future" - creates new series with UNTIL on original
- "all_in_series" - updates existing series in-place
## Implementation Details:
- Event context menu shows single edit option for non-recurring events
- Recurring events get three options: "Edit This Event", "Edit This and Future Events", "Edit All Events in Series"
- Modal tracks which fields user actually changed for efficient updates
- Backend series endpoint already has the logic for all three update scenarios
- Full RFC 5545 compliance with proper EXDATE and UNTIL handling
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Builds and pushes Docker image on main branch commits
- Tags with both latest and commit SHA
- Uses build cache for faster builds
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add multi-stage Dockerfile with dependency caching for both frontend and backend
- Implement Docker Compose configuration with separate frontend/backend services
- Configure Caddy as reverse proxy with proper WASM and static file serving
- Add volume mounting for frontend assets shared between containers
- Optimize build process with staged compilation and workspace handling
- Add debug logging and WASM initialization tracking for production deployment
- Update README with project motivation and "vibe coded" disclaimer
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated CLAUDE.md with current architecture and recent improvements
- Removed from git tracking to keep as local development resource
- Added to gitignore to prevent future commits
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add project motivation highlighting gap in quality CalDAV web clients
- Expand feature list with advanced recurring event and drag-drop capabilities
- Detail architecture with frontend/backend technical implementation
- Include comprehensive project structure and CalDAV server compatibility
- Note current testing status (Baikal tested, others planned)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed unused functions and variables identified after RRULE parameter fix:
- Remove unused build_series_rrule function from backend series handler
- Remove unused RecurrenceType::from_rrule and helper functions from frontend
- Prefix unused state variables with underscores to suppress warnings
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Clean up extensive console logging that was added during RRULE debugging.
Removed debug logs from:
- Frontend RRULE generation in create event modal
- Frontend RRULE parsing in calendar service
- Weekly/monthly/yearly occurrence generation functions
- Backend RRULE processing in events and series handlers
The core functionality remains unchanged - this is purely a cleanup
of temporary debugging output that is no longer needed.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit fixes a critical bug where INTERVAL and COUNT parameters
were being stripped from recurring events during backend processing.
Frontend was correctly generating complete RRULE strings like:
FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,FR;COUNT=6
But backend was ignoring the complete RRULE and rebuilding from scratch,
resulting in simplified RRULEs like:
FREQ=WEEKLY;BYDAY=TU,FR (missing INTERVAL and COUNT)
Changes:
- Modified both events and series handlers to detect complete RRULE strings
- Added logic to use frontend RRULE directly when it starts with "FREQ="
- Maintained backwards compatibility with simple recurrence types
- Added comprehensive debug logging for RRULE generation
- Fixed weekly BYDAY occurrence counting to respect COUNT parameter
- Enhanced frontend RRULE generation with detailed logging
This ensures all RFC 5545 RRULE parameters are preserved from
frontend creation through CalDAV storage and retrieval.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit resolves a significant bug where weekly recurring events with multiple selected days (BYDAY parameter) were only displaying the first 2 chronologically selected days instead of all selected days.
## Root Cause:
The `next_weekday_occurrence` function was designed for single-occurrence processing, causing it to:
- Find the first matching weekday in the current week
- Return immediately, skipping subsequent selected days
- Repeat this pattern across weeks, showing only the same first day repeatedly
## Solution:
- **New Function**: `generate_weekly_byday_occurrences()` handles multiple days per week
- **Week-by-Week Processing**: Generates events for ALL selected weekdays in each interval
- **Comprehensive Logic**: Properly handles INTERVAL, COUNT, UNTIL, and EXDATE constraints
- **Performance Optimized**: More efficient than single-occurrence iteration
## Technical Details:
- Replaced linear occurrence processing with specialized weekly BYDAY handler
- Added comprehensive debug logging for troubleshooting
- Maintains full RFC 5545 RRULE compliance
- Preserves existing functionality for non-BYDAY weekly events
## Expected Result:
Users creating weekly recurring events with multiple days (e.g., Mon/Wed/Fri/Sat) will now see events appear on ALL selected days in each week interval, not just the first two.
Example: "Every week on Mon, Wed, Fri, Sat" now correctly generates 4 events per week instead of just Monday events.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit enhances the professional appearance of the calendar application by removing all user-facing emojis while preserving debug logging functionality. Additionally, includes modal layout and styling improvements for better usability.
## Changes Made:
### Emoji Removal:
- **Event creation modal tabs**: Removed emojis from all 6 tab buttons (📅 Basic Details → Basic Details, etc.)
- **Modal content**: Removed emojis from alarm types, attachment types, pattern examples, and completion status
- **Theme picker**: Removed emojis from all 8 theme options (🌊 Ocean → Ocean, etc.)
- **Context menus**: Removed emojis from event context menu (edit/delete actions) and calendar context menu
### Modal Styling Improvements:
- **Width expansion**: Increased modal max-width from 500px to 900px (80% wider)
- **Enhanced padding**: Added more padding to modal header (2rem 3rem 1.5rem) and tab content areas
- **Responsive design**: Improved mobile adjustments while maintaining desktop experience
- **Checkbox fix**: Override width inheritance for "All Day" checkbox with auto width and inline-block display
### Form Layout Enhancement:
- **Field reordering**: Moved Repeat and Reminder options above date/time pickers for better workflow
- **Visual consistency**: Maintained clean, professional appearance throughout the interface
The application now presents a clean, professional interface suitable for business environments while retaining full functionality. Debug logging with emojis is preserved for development purposes.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>