This self-hosted calendar provides a simple web dashboard to share your schedule with friends and family. It tracks your upcoming travel plans to keep your personal network informed and displays your availability so others can plan accordingly.
Try it yourself: Live Demo
GitHub: thebronway/calendar-app
Docker Hub: thebronway/calendar-app
Documentation: Read the User Guide for setup, configuration, and feature details.
Roadmap: See planned features in the Project Roadmap.
Changelog: Review past releases in the Changelog.
- Multiple Views: Year, Month, Planner, and List layouts. Dark mode supported.
- Customization: Assign colors to categories and icons to daily activities.
- Data Entry: Multi-day bulk editing, location tagging, and rich-text notes. Live WebSocket sync.
- Sharing & Sync: Filter views via URL parameters. Generate custom iCal feeds for Apple/Google Calendar.
- Access Control: Public read-only or private password-protected modes. Configurable session timeouts.
- Analytics: Built-in tracking support for Google Analytics and Umami (Cloud or self-hosted).
- Data Management: Automated nightly backups, manual snapshots, and full data exports.
This application is designed to be deployed using Docker.
Please refer to the User Guide for the docker-compose.yml configuration and full deployment instructions.
Check out my other projects at brian.conway.im. Find this or any of my other projects useful or helpful? Support my work (Buy me a coffee).
This project was coded with AI assistance, but fully reviewed, tested, and approved by hand. See AIACKNOWLEDGMENT.md for details.
This software is provided "as is", without warranty of any kind, express or implied.
Last updated: 2026-07-02
Calendar-App is a self-hosted, year-at-a-glance dashboard designed to help you track travel, availability, and daily activities, and share them easily with friends and family.
This guide covers everything you need to know to deploy, configure, and use your calendar.
- Introduction & Overview
- Installation & Deployment
- Authentication & Access
- Global Settings & Appearance
- Configuring the "Key" (Categories & Activities)
- Adding and Editing Events
- Navigating the Calendar Views
- Stats, Filters, and Sharing
- Keyboard Shortcuts & Tips
- iCal Subscriptions (Syncing)
- Data Management & Backups
- Acknowledgments
The Calendar App provides a real-time, visual overview of your year. It relies on two main concepts to keep things organized:
- Categories: These dictate the background color of a day on the calendar (e.g., "Vacation" = Orange, "Work Travel" = Purple). A day can only have one Category.
- Activities: These are small icons that appear inside the day cell (e.g., a plane icon for "Flight", a pizza icon for "Food"). A day can have up to four Activities.
This application is designed to be run using Docker.
- Docker and Docker Compose installed on your host machine.
Create a docker-compose.yml file with the following configuration:
version: '3.8'
services:
calendar-app:
image: thebronway/calendar-app:latest
container_name: calendar
restart: unless-stopped
ports:
- "8080:80"
volumes:
- ./calendar_data:/app/data
environment:
# REQUIRED: Set this to a secure password
- ADMIN_PASSWORD=your_secure_password_here
# OPTIONAL: Custom session signing key (auto-generated if left blank)
- JWT_SECRET=your_secure_jwt_secret_here
# OPTIONAL VARIABLES:
- TIMEZONE=America/New_York
- PAGE_BANNER_HTML=<b>Welcome!</b>Run docker-compose up -d to start the application. It will be accessible at http://localhost:8080.
| Variable | Description |
|---|---|
ADMIN_PASSWORD |
(Required) The password assigned to the account username "admin" to manage and edit the calendar. |
JWT_SECRET |
(Optional) Session cookie cryptographic signature string. Automatically fallback-generated if empty. |
DATA_DIR |
(Required) Path where JSON data files are stored. Defaults to /app/data. |
TIMEZONE |
(Optional) Default timezone for the calendar (e.g., UTC, America/Chicago). |
PAGE_BANNER_HTML |
(Optional) Custom HTML banner displayed at the very top of the page. |
The calendar operates on a permission system controlled by global visibility configurations and specific access profiles:
- Public Mode: Anyone who visits the URL can view the calendar dashboard in read-only mode. Administrators authenticate using the username "admin" and the configured password by clicking the Lock icon in the header.
- Private Mode: The entire application is hidden behind a full-screen login screen requiring a valid username and password combination. Master administrators use the username "admin". Guest visitors use the profile Name/Label as their username alongside their designated profile password.
When logged in as an administrator, click the Access Control (shield check) icon on the floating navigation bar to manage visibility restrictions, credentials, and security logs.
-
View Passwords: Admins can generate multiple read-only user credentials for external sharing.
- Uniqueness Constraints: The backend prevents creation of matching names/labels or matching password strings to keep account tracking distinct users.
- Expirations: You can optionally select an expiration date. If no date is selected, access is unlimited.
- Mode Toggling Note: Switching the calendar from Private Mode back to Public Mode automatically deletes all generated guest credentials from the system database.
- Access Logging & Auditing: The panel displays a "Recent Activity" ledger containing the last 500 authentication events. It tracks the exact timestamp, incoming connection IP address, account profile name, and success or failure status of each login attempt.
Note: Active login sessions expire automatically after 24 hours. Users can click the Logout button in the header to terminate a session immediately.
If running the application behind an authentication proxy (such as Authentik), ensure your server configuration route matches the standard login endpoint under this section:
location = /api/auth/login
Once logged in, click the Settings (gear) icon to customize how your calendar looks.
- Main Page Icon: Change the large icon displayed next to your header title.
-
Header Title & Browser Tab Style: Choose between Simple (
2026 Calendar), Possessive (John's Calendar), or Question formats (Where is John in 2026?). - Owner Name: If using a Possessive or Question format, enter your name here.
- Layout Preferences: Toggle auto-scrolling to the current month or hiding the Key/Stats panels on mobile and desktop individually.
- Timezone: Ensure your calendar highlights "Today" correctly based on your location.
- Login Session Timeout: Configurable duration (from 1 hour to 30 days) before users need to re-authenticate.
- Stats & Counters Visibility: Choose who can see the total days traveling, location leaderboards, and category/activity counts (Visible to Everyone, Visible to Admins Only, or Hidden Completely).
-
Tracking Integrations: Add your Google Analytics ID (
G-XXXXXXX) or Umami Website ID. Self-hosted Umami users can also input their custom tracking script URL.
Click the Key icon to define the visual language of your calendar.
- Importing: If you used the calendar last year, you can click "Import from [Previous Year]" at the bottom to instantly copy over your colors and icons.
- You can define up to 5 categories.
- Assign a name and a color.
- Toggle the "Count" switch to display how many days are assigned to this category in the main Key panel.
- Use the up/down arrows to reorder how they appear in the UI.
- Search through hundreds of available icons.
- Assign an icon color and label.
- Toggle the "Count" switch to track how many times you do this activity throughout the year.
Click any day on the calendar to open the Cell Editor.
- Category: Select one category (or "Home" to clear it).
-
Activities: Search and add up to 4 activities.
- Tip: Click the pencil icon next to an added activity to give it a custom display name just for that day (e.g., renaming "Flight" to "JFK -> LHR").
-
Location & Notes: * Add comma-separated locations (e.g., "NYC, London"). These will be tracked in your stats.
- Add rich-text notes (bold, lists, links) to record flight numbers, hotel details, or journaling.
Editor Actions:
- Clear Day: Resets the day's data (clears activities, locations, notes, and resets color).
- Save & Close: Saves your data and returns to the calendar.
- Save & Previous / Save & Next: Saves and opens the adjacent day.
To quickly log long trips:
- Click Bulk Edit in the bottom admin navigation bar.
- Click multiple days on the calendar (they will highlight with a purple ring).
- A floating bar will appear at the bottom. Click Edit to apply changes, or Cancel to exit Bulk Edit mode.
- Any Category, Activity, or Location you apply will be saved to all selected days at once.
Use the navigation toggle in the header (to switch between Year, Planner, and List views) or click a specific month name to change your view:
- Year View (Default): A dense, 12-month grid perfect for seeing your entire schedule at a glance.
- Planner View: A split-screen dashboard showing a single month's grid on the left, and a continuous chronological feed of events for that month on the right.
- List View: A continuous, scrolling timeline aggregating all your active events chronologically by month.
- Single Month View: Clicking a month name (e.g., "July") isolates that month and displays a dynamic mini-key showing only the categories and activities present in that specific month.
Located below the Key, this panel calculates:
- Days Traveling: Total days assigned to a category.
- Time Traveling: The percentage of the year you are away.
- Location Counts: A leaderboard of your most frequent destinations.
Want to see every time you went skiing or visited New York?
- Click any Category or Activity in the Key.
- Click any Location in the Stats panel.
- The calendar will instantly dim unrelated days and highlight your selections.
- Click the Clear Filters button in the main page header at any time to reset active filters and return to the full calendar view.
If you want to share a specific itinerary with someone (e.g., just your "Work Travel" and "Flights"):
- Highlight your desired items in the Key.
- Click View as List or View as Planner in the Key header.
- The URL will update with your filters (e.g.,
?a=flight&c=work-travel). - Copy and share that link! Visitors will only see the days that match those specific filters.
-
Arrow Keys (
←/→): Instantly navigate to the previous or next year when viewing the main dashboards. If a single day cell is open in the viewer/editor, these keys instead step backward or forward to the adjacent day sequentially (and will explicitly warn you if you attempt to leave with unsaved changes). -
EscKey: Close any open modal or cancel out of the day editor without saving. -
DKey: Toggle between Dark and Light mode. -
VKey: Rotate quickly between Year, Planner, and List views. -
Y,P,L,MKeys: Jump instantly to the Year (Y), Planner (P), List (L), or current Month (M) view. -
HorUKeys: Open the Help Modal (H) or jump directly to this User Guide (U). -
AKey: Prompt for Authentication (Log in). -
B,K,F,C,SKeys (Admin Only): Toggle Bulk Edit mode (B), open Key configuration (K), manage Feeds (F), manage Access Control (C) or open Settings (S). - Saving: If you attempt to click away, close a window, or accidentally close the browser tab with unsaved data, a confirmation prompt will appear to prevent accidental data loss.
- Viewing and Editing Details: To view or edit a day's details, simply click on it directly within any of the calendar grid or list views.
You can sync your travel and activities directly to your personal calendar (Apple Calendar, Google Calendar, Outlook) using custom continuous iCal feeds.
- Click the Feeds (RSS) icon in the header to open the Feed Manager.
- Click New Feed and provide a descriptive name.
-
Step 1: The Event Trigger (What creates the block?):
- Choose between Categories / Activities or Geographic Locations to dictate what scans your calendar database.
- Categories / Activities Mode: Select what data elements to look for. If combining both, you can apply strict conditional logic rules (OR means any matching item creates an event; AND requires both to exist on the same day).
- Geographic Locations Mode: Set the feed to match any day containing location entries, or target explicit matching cities/regions.
- Grouping Strategy: Select Separate Events to split items out into independent overlapping calendar entries, or All-in-One Event to combine multiple elements into a single combined calendar block.
-
Step 2: The Event Payload (Sub-categories & Details):
- Toggle Map data to Location field to pass the day's structural geographic data straight into your external calendar's native location text property.
- Check which supplementary contextual layers to append into the event notes box (Rich-Text Notes, List of Activities, Category Display Name, or Location List).
- Click Save Profile Rules.
Note on Filters: The checklist filter items visible inside the builder form are dynamically populated based on active data configurations parsed from the specific calendar Year you are currently viewing.
Once a feed is created, click Copy URL.
-
Apple Calendar: Go to
File > New Calendar Subscription...and paste the URL. -
Google Calendar: Go to
Settings > Add calendar > From URLand paste the URL.
Note: Feeds are continuous and will automatically stitch together data from the previous, current, and next year so your calendar stays perfectly up to date.
If running the application behind an authentication proxy (such as Authentik), you must add an unauthenticated bypass line for the feed extraction route explicitly above your catch-all route:
location /api/feed/
The Calendar App includes a backup engine to protect your data from accidental loss or destructive bulk edits.
Log in as an administrator and click the Settings (gear) icon, then select the Backup tab.
- The system automatically takes a snapshot of your entire database every night at midnight (based on your configured timezone).
- Retention: To prevent disk bloat, all automated backups and manual snapshots are automatically deleted after 7 days.
- Create Backup Now: Click this button to instantly generate a local backup snapshot. This is highly recommended before performing large Bulk Edits.
- Download .zip: Click this button to download a complete copy of your raw JSON data and configuration files directly to your local device.
In the Local Backups table, click the Restore (rewind) icon next to any available backup.
- Safety Feature: The system will automatically take a pre-restore snapshot of your current state before overwriting any files, ensuring you can always undo a restoration.
This project was made possible by the incredible open-source community. Special thanks to the creators and maintainers of:
- React & Node.js for the core framework.
- Tailwind CSS for the styling system.
- Lucide for the beautiful, consistent icon set used throughout the app.
AI Assistance: This project was developed with the assistance of AI tools to brainstorm, generate boilerplate, and refine code. Every line of code has been meticulously reviewed, tested, and approved by hand. For more details, please see the AI Acknowledgment.
Last updated: 2026-07-03
Current Version: v1.0.7
This document tracks past changes starting with v0.7.1.
- Added automated nightly backup engine with 7-day retention
- Added Backup management tab to Settings modal
- Added manual backup snapshots and one-click data restorations
- Reduced Docker production image size significantly
- Added custom app themeing for background and primary accent color
- Restructured admin modals into tabbed layouts
- Updated keyboard shortcuts
- Bugfix: Fixed an issue where the escape key failed to close some modals
- Added Demo Mode with 15-minute data resets
- Implemented seed snapshots to save demo state
- Split Privacy and Analytics settings into separate components
- Added URL validation regex for self-hosted Umami tracking
- Added dynamic first-time launch welcome modal for admins
- Fixed login screen transition timing bug
- Updated .dockerignore to fix markdown build exclusions
- Documentation updates (README Key Features and User Guide)
- Updated Help Modal
- Login page title, icon updates and autofocus updates
- Standardized desktop layout width and styling across admin modals
- Added options to hide stats to non-admin users
- Added session timeout configuration options
- Added Umami and Google Analytics options
- Upgraded authentication to standard Username and Password login
- Implemented secure JWT_SECRET environment configuration with persistent fallback
- Reduced API JSON parsing limit to 2MB to prevent DoS vulnerabilities
- Documentation updates (README and User Guide)
- server.js monolithic breakup
- SettingsModal.tsx monolithic breakup
- KeyConfigModal.tsx monolithic breakup
- AccessControlModal.tsx monolithic breakup
- Added public and private modes
- Added access control modal for admin users
- Implemented view-only password management with unique name/password validation and optional expirations
- Added custom login message configuration for the login screen
- Added login activity logging
- Moved admin navigation to bottom bar
- Hid admin navigation during Bulk Edit and on User Guide
- Added Cancel button to Bulk Edit bar
- Made Save and Cancel buttons sticky in Feed Editor
- Implemented global confirm modal context to replace native browser prompts
- Added hook to prevent browser tab closure with unsaved changes
- Added Clear Day button to Cell Editor
- Adjusted mobile and desktop button layouts in Cell Editor footer
- Added drag-and-drop reordering for Locations, Cell Editor Activities, and Key Config items
- Added day of the week display to the Cell Editor header
- Added inline activity editor Save/Cancel buttons
- Bugfix: Location input saves when clicking away
- Bugfix: PFixed "unsaved changes" warnings when opening days with empty notes
- Added advanced global keyboard shortcuts for navigation and admin actions
- Added Help Modal to UI and app header
- Added open-source and AI Acknowledgments section to the User Guide
- Bugfix: Corrected Unraid Docker health check failures (IPv6 fallback)
- Bugfix: Fixed scroll position resets and User Guide markdown links
- Layout preference settings (Auto-scroll, collapse panels)
- Session & security migration to stateless JWTs
- Secure HttpOnly cookie implementation
- CellEditor monolithic breakup
- CellEditor UI Updates
- App header UI Updates
- Screenshot Updates
- User Guide Updates
- CellEditor Updates on Desktop
- iCal subscription system updates
- After container reboot bugfix
- Location UI updates
- iCal subscription system updates
- Added iCal calendar subscription system
- Implemented 2-step trigger and payload query builder
- Added AND/OR filter logic rules
- Integrated icons into the feed manager UI
- Updated User_guide
- App.tsx monolithic breakup
- Added user guide in code and in app
- Header UI cleanup
- Footer UI cleanup
- Desktop Year View cleanup
- Minor bug fixes
- Planner View: Added a new 3-column dashboard (/planner) combining a calendar grid with a flowing chronological list of events.
- Month View: Redesigned the single-month layout to match the Planner View, dropping the side legend in favor of a unified full-width card.
- List View: Updated the date boxes to display the short day of the week (e.g., 'Mon') instead of redundant month abbreviations.
- Key Filters: Updated selection logic to use 'OR' instead of 'AND' when combining multiple activities/categories, and made categories clickable in the Key.
- Keyboard Navigation: Arrow keys now correctly traverse across year boundaries (e.g., navigating from Dec 2026 to Jan 2027).
- Bugfix: Corrected the active-cell highlight ring getting cut off on expanding rows within the calendar grid.
- Dynamic URL Filtering: Filter and share specific views instantly using paths and query parameters (e.g., ?a=slug).
- List View: Added a continuous timeline layout (/list) aggregating filtered events chronologically by month.
- Month View: View a single month alongside a dynamic side-legend showing only the active keys for that month.
- Inline Editor Auto-Save: Custom display names now auto-save on blur, removing the redundant green checkmark.
- Custom Activities: Added the ability to edit an activity's display name for a specific day (does not affect global filters or counts).
- Desktop UI: Combined the 'Category' and 'Activities' tabs into a single view in the editor.
- Bugfix: Fixed the mobile header layout so the year picker and action icons properly wrap to the next line.
- Bugfix: Improved the visual indicators for when Bulk Edit mode is active on mobile.
- Bugfix: Ensured Bulk Edit mode and active selections are properly cleared when a user logs out.
- Minor bugfixes
- Complete Backend Re-Write to Typescript
- Component Splitting: Extracted
SettingsModal,CellEditor,KeyConfigModal,AuthModal, andIconEditorinto dedicated component files. - UI Abstraction: Extracted the core calendar grid and rendering logic into a new
MonthViewcomponent. - Utility Extraction: Relocated heavy static data (icons, categories) and helper functions into a dedicated
utils/directory.
- Bulk editing for date ranges and multiple days
- UI Polish: Updated "Time Traveling" stat card to purple
- Activities search/sort in day editor
- IconEditor search/sort
- Bottom "Add" buttons for categories/activities
- Key page activities search
- Bug fixes (password input, white screens)
- ESLint + Prettier setup
- Component extraction (Footer, ToggleSwitch)
- Improved error handling
- Structured logging
- JSON response standardization
- Dependency separation
- .dockerignore improvements
- File locking
- DATA_DIR fix
- Node 20 upgrade
- Version standardization
Last updated: 2026-07-03
Current Version: v1.0.7
This document tracks planned improvements, enhancements, and technical debt for the calendar-app.
-
Dedicated Route Architecture: Introduce a formal standalone
/loginpath to replace the legacy conditional inline layout components. - Unified Route Interceptor: Implement automated routing rules that cleanly forward unauthenticated visitors to the secure login route whenever Private Mode is active.
- Decoupled Auth Provider Framework: Refactor the backend authentication engine to support a pluggable architecture capable of dynamically switching validation sources.
- Universal Local Admin Precedence: Establish a hard hard priority filter ensuring the local master admin credentials always intercept and override external directory matches as an automatic fallback backdoor.
- switching from private to local or to futre sso/ldap requires confirmation and admin to input their password again (to prevent accidental switching) and keep local db, but just dont use it, dont auto clear (specify that in the pop-up)
- Centralized Network Logins: Implement real-time network credential validation against centralized LDAP directories (e.g., Active Directory, FreeIPA).
- Hybrid Configuration Architecture: Support non-sensitive configuration parameters (Server URLs, Base DNs) directly within the UI settings while isolating sensitive bind username and passwords strictly to container environment variables.
- Dynamic Group Permission Mapping: Provide text controls within the UI to map specified directory group strings directly to internal application roles (admin or view).
- Global Session Cleansing: Automatically invalidate all active view credentials and sessions whenever the primary authentication provider mode is toggled.
- Still need to add login failures/suceess to the activity log
- local admin overides and ldap admin with the same username
- isolate the upcoming identity modules into a its own directory, keeping routes/auth.js perfectly lean and clean.
- Federated Authentication Handshake: Integrate standard OpenID Connect protocol options to offload identity verification to modern identity providers (e.g., Authentik, Keycloak).
- Automated Frontend Handshake Redirection: Implement automatic visitor forwarding straight to the configured external single sign-on screen upon landing on the root path.
-
Bypass Redirection Backdoor: Restrict automatic token redirection loops exclusively to the root path (
/), allowing direct browser navigation to/loginto bypass the loop for local master emergency access.
- Historically Aware Key Parsing: Load and map key item definitions on a per-year basis during feed generation.
- Structural Fallback Mapping: Implement matching rules using raw icon strings and color properties if unique configuration identifiers change across year boundaries.
- Cross-Year Event Preservation: Prevent historical events from disappearing when categories or activities are deleted or modified in later year setups.
- Continuous Rolling Timeline Feeds: Maintain multi-year calendar subscriptions without requiring manual annual URL renewals.
- Webhooks
- Goal: Push real-time calendar modification notifications out to third-party home automation platforms (e.g., Discord, Slack, Umami, or custom web endpoints).
-
Configuration: Add a
webhooksarray to the coreAppConfigtype mapping unique webhook IDs, payload destination URLs, and a toggleable active state flag. -
Diff Engine: Intercept
POST /api/data/:yearrequests to compute a baseline structural difference, checking if a new entry or activity update occurred to avoid notification spam on simple spelling corrections. - Payload Dispatcher: Asynchronously fire out a standardized JSON POST body payload containing text templates summarizing the modification out to all active webhook endpoints.
- API Keys & REST API
- Goal: Allow external automation setups (e.g., Home Assistant, n8n, Node-RED) to programmatically log categories or activities onto the calendar without utilizing the frontend UI.
-
Token Profiles: Extend the database schema inside
access.jsonand theAccessControlModal.tsxinterface to support generating long-lived, cryptographically secure API tokens distinct from traditional view passwords. -
Ingestion Route: Create a protected REST API endpoint under
POST /api/external/logrequiring authentication passing via standardAuthorization: Bearer <token>header rules. -
Sync Synchronization: Parse incoming JSON payloads containing mandatory parameters for target date strings (
YYYY-MM-DD), optionalcategoryIdtags, locations, andactivityIds, merging updates straight toYYYY_data.jsonwhile instantly triggering frontend UI updates via the serverbroadcastUpdateWebSocket hook.
-
Data Modeling & Storage Mechanics
- Introduce a new backend data store file
data/pto_config.jsonmanaged exclusively by the admin credential tier to store the global bank definitions. - Define each PTO Bank entry structure with fields:
id(UUID string),name(string, e.g., "Vacation"),startingBalance(number in hours),accrualRate(number in hours),accrualFrequency(enum:'none','weekly','biweekly','monthly','annually'), andstartDate(ISO string date template). - Extend the core calendar
DayDatatype definition insrc/types/index.tsto include an optional schema layer:pto?: { bankId: string; hours: number; }[]to allow tracking multiple types of off-time allocations within a single day cell.
- Introduce a new backend data store file
-
Backend API Layer Hardening
- Implement a new protected route
GET /api/pto/configreturning the contents ofdata/pto_config.json(requires valid admin JWT cookie). - Implement a new protected route
POST /api/pto/configto overwrite and update global accrual rules with automated input sanitization and payload structural verification. - Modify the existing payload validation logic inside
POST /api/data/:yearwithinserver.jsto whitelist and parse the new optional day-levelptoarray parameter without triggering schema integrity rejections.
- Implement a new protected route
-
Dynamic Accrual Engine Core Math
- Implement a stateless client-side computation module (
src/utils/ptoMath.ts) to resolve real-time account balances dynamically rather than writing database cron-jobs or mutating active counters. - Compute total earned hours per bank as:
startingBalance+ (accrualRate×elapsedIntervals), where elapsed intervals are determined by calculating time step boundaries between the bank's definedstartDateand the client's localized current timestamp. - Compute remaining balance per bank as:
totalEarnedHours–totalUsedHours, where used hours are solved by aggregating all day-level matchingbankIdlogs parsed across the database history dataset.
- Implement a stateless client-side computation module (
-
Admin Configuration Interface (UI Elements)
- Integrate a new dedicated "Time Off (PTO)" sub-tab panel into the master
SettingsModal.tsxcomponent. - Render an inline data card grid for all active banks, cleanly listing out the profile rules, structural milestones, and configured accrual rates.
- Implement an absolute inline form layout triggered via an "+ Add Bank" button, presenting text inputs for Bank Title, numeric controls for Starting/Accrual hour buckets, a date picker for the activation milestone, and a dropdown select field for the frequency interval rules.
- Integrate a new dedicated "Time Off (PTO)" sub-tab panel into the master
-
Cell Editor Upgrades & Logging UI (UI Elements)
- Inject a new secure, conditionally rendered "Time Off Logs" segment inside the primary desktop and mobile view grids of
CellEditor.tsx, restricted exclusively behind anisAdminauthentication gate check. - Provide a single-click button styled as "+ Log Time Off" that expands smoothly to show an entry configuration layout composed of a select dropdown picking from available active banks and an integer counter box defaulting explicitly to
8hours. - Render saved allocations inside the view window as color-coded standalone data badges embedded with individual quick-delete action parameters (e.g.,
[🌴 Vacation: 8h (x)]).
- Inject a new secure, conditionally rendered "Time Off Logs" segment inside the primary desktop and mobile view grids of
-
Main Dashboard Widgets & Aggregators (UI Elements)
- Integrate a modern "Time Off Balances" visualization matrix directly into the primary main page
StatsSection.tsxblock, hidden completely when the application session role evaluates to'view'. - Design clean horizontal allocation balance progress bars or high-visibility card metrics representing each individual bank pool.
- Highlight the primary real-time remaining balance integer pool as a dominant text anchor (e.g.,
42.5 hrs available), followed closely by secondary explicit string math descriptions in smaller layout font sizes to maintain clarity (e.g.,80h Earned — 37.5h Used).
- Integrate a modern "Time Off Balances" visualization matrix directly into the primary main page
- Security Hardening
- Implement API rate-limiting (especially on the login route), input sanitization, and CSRF protection.
- Bundle Optimization**
- Optimize the dynamic icon imports (
lucide-react) to ensure aggressive tree-shaking, and implement lazy loading for modals. For Faster initial page loads, particularly crucial for mobile users on cellular networks.
- Optimize the dynamic icon imports (
- Standardize and cleanup comments, remove dead code, and clean up inline styles while splitting components.
- Look for monolithic files.
- Reorgainze files (put in folders if needed)
- clean up files (reorangize)
- look for tech debt
- More Screenshots in the User guide
- iCal syncing - how does it deal with activities which only happen in a certain year and not the next year. Should the iCals be confined to a year?
- Establishing test suite of professional-grade foundation for long-term maintenance.
- Introduce Jest and React Testing Library for core utilities (date math, JSON parsing) and component rendering which should prevent regressions during major refactors.
- Package Updates - how to maintain
- Offline Support (PWA)
- Use service workers and Vite's PWA plugin to cache the frontend and allow read/write buffering via
localStoragewhen offline.
- Use service workers and Vite's PWA plugin to cache the frontend and allow read/write buffering via
- Accessibility Improvements -Add ARIA labels to icon-only buttons, trap focus inside modals.





