All notable changes to Better Todo will be documented in this file.
The format is based on Keep a Changelog.
-
Weekly Recap - Automated and manual weekly productivity summaries
- Hourly cron job checks each user's timezone for Friday 2pm
- AI-generated summary of completed todos (Saturday through Friday 2pm)
- Creates a dated full-page note with bullet-point accomplishments and original todo text
- Manual trigger via CalendarCheck button on empty full-page notes
- Supports both Claude and OpenAI for AI summaries, with plain-text fallback
- Per-user IANA timezone stored in userPreferences (synced from browser on first load)
completedAttimestamp on todos for accurate weekly trackingweeklyRecapRunsdedupe table prevents duplicate recap notes- New files:
convex/weeklyRecap.ts,convex/weeklyRecapQueries.ts,convex/crons.ts
-
convex-doctor integration - Static analysis for Convex backend health
- Installed
convex-doctoras devDependency with npm script - Created
convex-doctor.tomlconfiguration with justified rule suppressions - Score improved from 43 to 100 out of 100
- Cursor skill (
.cursor/skills/convex-doctor/SKILL.md) and rule (.cursor/rules/convex-doctor.mdc) created
- Installed
- Weekly recap blank note - Backfilled
completedAton 237 existing completed todos so the recap query finds historical data - Recap fallback query -
getCompletedTodosInRangenow falls back to_creationTimescanning when nocompletedAtindex hits exist - Recap error resilience -
generateRecapIntoNotewrapped in top-level try/catch so the note always gets content (error message if something fails, never blank) - Backfill mutation - Added
backfillCompletedAtinternal mutation for one-time or re-runnable data repair - Recap loading spinner - CalendarCheck button shows a spinning Loader2 icon while AI generates the recap, stops when content arrives via Convex reactivity (15s fallback timeout)
- Re-generate on delete - Deleting a recap note and clicking the button on a new empty note creates a fresh recap (manual path has no dedupe check)
convex/schema.ts- AddedcompletedAtfield andby_user_and_completedAtindex to todos,timezoneto userPreferences, newweeklyRecapRunstableconvex/todos.ts-updateTodonow sets/clearscompletedAton completion toggleconvex/users.ts- AddedsetTimezoneIfMissingmutation,timezoneingetUserPreferencesreturnconvex/stats.ts- ChangedgetUserCountFromClerkfrom publicactiontointernalActionconvex/pomodoro.ts- ChangedupdateBackgroundImagefrom publicmutationtointernalMutationconvex/unsplash.ts- Usesinternal.pomodoro.updateBackgroundImageinstead ofapi.*convex/http.ts- Added CORS OPTIONS handler for/meta/shareconvex/fullPageNotes.ts- AddedgenerateWeeklyRecapIntoNotepublic mutationsrc/App.tsx- Added timezone sync on auth, weekly recap mutation wiringsrc/components/FullPageNoteTabs.tsx- Added CalendarCheck button for empty notes
- Security:
ctx.runActioncalls now useinternal.*references instead ofapi.*for server-to-server calls - Configuration: Added
convex.jsonand CORS preflight handler
-
Executable Notes (Run Note) - Turn notes into executable programs with AI tool use
- New "Run" task type that interprets natural language instructions and executes them
- AI agent loop pattern with multi-step tool execution
- Run Note button on full-page notes and inline notes
- Execution log showing all tool calls with inputs, results, and status
- Collapsible execution log with scroll support for long tool chains
- Support for both Claude and OpenAI providers
-
AI Agent Tools - Comprehensive tool set for note execution
createTodo- Create new todos with optional date/folder/pinnedupdateTodo- Update existing todo content or pinned statuscompleteTodo- Mark a todo as completeddeleteTodo- Remove a todocreateNote- Create new full-page notesupdateNote- Update note title or contentmoveTodosToDate- Move multiple todos to a target datesearchTodos- Search todos by query with date/completion filterssearchNotes- Search full-page notes by querygetTodosForDate- Get all todos for a specific datearchiveDate- Archive a date and all its todos
-
Schema (
convex/schema.ts)- Added
runtotaskTypeunion for agent tasks - Added
executionLogfield toagentTaskstable for tracking tool calls - Execution log entries include toolName, toolInput, toolResult, status, timestamp
- Added
-
Agent Tools Module (
convex/agentTools.ts) - New file- Centralized tool definitions for AI agent
AGENT_TOOLSarray with tool schemas (name, description, parameters)getClaudeTools()- Format tools for Anthropic APIgetOpenAITools()- Format tools for OpenAI function calling APIEXECUTABLE_NOTE_SYSTEM_PROMPT- System prompt for run task execution
-
Agent Tool Mutations (
convex/agentToolMutations.ts) - New file- Internal mutations for each tool action (secure, not exposed to client)
- Uses indexed queries for ownership checks
- Idempotent mutations with early returns
- Parallel operations where possible
-
Agent Task Actions (
convex/agentTaskActions.ts)- Added
processExecutableNoteinternal action for run tasks runClaudeAgentLoop- Multi-step execution with Claude tool userunOpenAIAgentLoop- Multi-step execution with OpenAI function callingexecuteAgentTool- Dispatcher for tool execution- Real-time execution log updates via
appendExecutionLogEntry - Max 10 iterations to prevent runaway execution
- Added
-
Agent Tasks Module (
convex/agentTasks.ts)- Updated
taskTypeValidatorto includerun - Added
appendExecutionLogEntryinternal mutation for real-time log updates - Added
updateTaskWithExecutionLoginternal mutation for final status update createAgentTaskschedulesprocessExecutableNotefor run tasks
- Updated
-
FullPageNoteTabs.tsx - Run Note button added
- Play icon button in note tab menu
- Triggers
onRunNotecallback with note data
-
NotesSection.tsx - Run Note for inline notes
- Play icon button on each note item
- Triggers
onRunNotewith note content and context
-
AgentTaskModal.tsx - Run task type option
- Added "Run" option with Play icon
- Description: "Execute this note as instructions"
-
AgentTasksView.tsx - Execution log display
- Collapsible execution log section for run tasks
- Shows tool calls with name, input, result, and status
- Visual indicators for pending (yellow), success (green), error (red)
- Chevron toggle for collapse/expand
- Scrollable entries container (max-height 300px)
-
App.tsx - Run Note integration
onRunNotecallback for FullPageNoteTabs creates run taskonRunNotecallback for TodoList (inline notes) creates run task- Navigates to Agent Tasks view after triggering run
- global.css - Execution log and run button styles
.agent-task-execution-logcontainer styles.agent-task-execution-log-headerclickable button with hover state.agent-task-execution-log.collapsedhides entries.agent-task-execution-log-entriesscrollable container.agent-task-execution-log-entrywith status-based backgrounds.run-note-buttonhover styles for all themes- Mobile responsive styles for execution log
- Follow-up Processing Panel - Fixed duplicate "thinking" panels
- Processing panel only shows during initial task processing (no result yet)
- Follow-up processing uses inline "Thinking..." indicator in conversation
- Prevents two processing indicators showing simultaneously
- Persistent Navigation Icons - All view icons now always visible in header
- Todos (checkbox), Notes (file), Chat (message), and Agent (sparkles) icons always visible
- Icons toggle their respective views when clicked
- Active view indicated with accent color highlight
- Clicking an active icon returns to todos view
- Removed conditional visibility logic for cleaner UX
- Icons still contextually hidden on pinned/backlog views where not applicable
- App.tsx - Navigation icon behavior update
- All nav icons visible simultaneously on regular date/folder pages
- Each icon toggles its view (click to open, click again to close)
- Added
nav-icon-activeclass for visual feedback on current view - Simplified header icon rendering logic
- global.css - Navigation icon active state
- Added
.search-button:hoverbackground color - Added
.nav-icon-activeclass with accent color and background - Consistent hover states across all nav icons
- Added
- Per-User API Keys - Users can now add their own API keys for AI features
- New "API Keys" section in Keyboard Shortcuts Modal (press ?)
- Support for both Claude (Anthropic) and OpenAI API keys
- Keys stored securely in Convex database (encrypted at rest)
- Masked key display in UI (only last 4 characters visible)
- Help links to get API keys from console.anthropic.com and platform.openai.com
- Save and delete functionality per provider
- Show/hide password toggle for key input
- Each user must provide their own API keys to use AI features
-
Schema (
convex/schema.ts)- Added
userApiKeystable withanthropicKeyandopenaiKeyfields - Index on
userIdfor efficient lookups
- Added
-
User API Keys Module (
convex/userApiKeys.ts) - New filegetUserApiKeysquery returns masked keys for UI displaygetApiKeyInternalinternal query returns full key for actions (not exposed to client)setApiKeymutation to save/update API keysdeleteApiKeymutation to remove API keys
-
AI Chat Actions (
convex/aiChatActions.ts)- Updated
generateResponseto use user's Anthropic key (required) - Clear error message directing users to Settings if no key configured
- Updated
-
Agent Task Actions (
convex/agentTaskActions.ts)- Updated
processAgentTaskandprocessFollowUpto use user API keys (required) - Helper functions
processWithClaude,processWithClaudeConversation,processWithOpenAI,processWithOpenAIConversationrequire user API key - Clear error messages directing users to Settings if no key configured
- Updated
- KeyboardShortcutsModal.tsx - API Keys management UI
- New "API Keys" section (authenticated users only)
- Key icon header with section title
- Input fields for Anthropic and OpenAI keys (password type)
- Show/hide toggle for each key input
- Save button per provider
- Masked display when key is saved with delete button
- Help links to provider API key pages
- Error handling with inline error display
- global.css - API Keys section styles
.api-keys-sectioncontainer with top border separator.api-key-errorerror message styling.api-key-fieldfor each provider's key input area.api-key-labelwith saved badge indicator.api-key-input-rowand.api-key-input-wrapperfor input layout.api-key-inputwith monospace font for key display.api-key-toggle-visibilityshow/hide button.api-key-save-btnand.api-key-delete-btnbutton styles.api-key-maskedfor displaying saved keys.api-key-help-linkfor external links to provider consoles- Mobile responsive styles for API key inputs
- Full API keys only accessible via internal Convex queries (not exposed to client)
- Client only sees masked versions of keys
- Keys scoped to authenticated user via userId index
- Convex provides encryption at rest and HTTPS transport
-
AI Chat Clear and Delete Commands - Manage chat history with commands or buttons
- Type
/clearto clear all messages (keeps the chat, removes messages) - Type
/deleteto permanently delete the chat from the database - Header buttons for Clear and Delete appear when chat has messages
- Confirmation dialogs before destructive actions
- Delete removes chat from sidebar automatically (Convex reactivity)
- Chat view closes after deletion and returns to todos
- Type
-
Agent Tasks Delete All - Bulk delete agent tasks
- New "Delete All" button in agent tasks header
- Deletes all tasks filtered by current date or folder context
- Confirmation dialog shows count of tasks to be deleted
- Uses parallel deletion with
Promise.all()for efficiency
-
AI Chats Module (
convex/aiChats.ts)clearChatmutation now properly resets messages arraydeleteChatmutation removes entire chat document from database
-
Agent Tasks Module (
convex/agentTasks.ts)- Added
deleteAllAgentTasksmutation for bulk deletion - Supports optional date and folder filtering
- Returns count of deleted tasks
- Added
-
AIChatView.tsx - Chat management UI
- Added header with Clear and Delete buttons (visible when chat has messages)
/clearcommand clears messages with confirmation/deletecommand deletes chat with warning dialog- Updated hint text to show available commands
- Chat view closes after deletion via
onClosecallback - Uses ConfirmDialog for consistent UI
-
AgentTasksView.tsx - Bulk delete functionality
- Added "Delete All" button in header (visible when tasks exist)
- Confirmation dialog with task count
- Resets selected task state after deletion
- global.css - New styles for chat and agent task controls
.ai-chat-header-title,.ai-chat-header-actions,.ai-chat-header-actionstyles.ai-chat-header-action.dangeroushover state with red styling.agent-tasks-delete-allbutton styles with danger hover state- Mobile responsive styles for new controls
-
Markdown Download for Full-Page Notes - Download any note as a markdown file
- New download button in full-page notes toolbar (Download icon)
- Downloads note content as
.mdfile with sanitized filename - Client-side download (no server required)
-
Create Todos from Agent Results - Turn AI agent output into actionable todos
- New "Create Todos" button on completed agent tasks
- Parses markdown lists (checkboxes, bullets, numbered) into individual todos
- Todos created in same date/folder context as the original task
- Shows count of todos created with success feedback
-
Save Agent Results as Notes - Preserve AI agent output as full-page notes
- New "Save as Note" button on completed agent tasks
- Saves entire conversation (including follow-ups) to a new full-page note
- Note created in same date/folder context as the original task
- Success feedback when note is saved
-
Persistent Agent Tasks Icon - Access agent tasks from any view
- Sparkles icon now visible when in full-page notes or AI chat views
- Allows switching to Agent Tasks without returning to todos first
- Closes current view (notes/chat) when switching to agent tasks
- ESC Key Behavior in Full-Page Notes - Smarter escape key handling
- First ESC press exits fullscreen mode (if active)
- Second ESC press closes the full-page notes view
- Allows exiting fullscreen without losing your place
- Agent Tasks Module (
convex/agentTasks.ts)- Added
createTodosFromAgentmutation - Parses agent results into todos - Added
saveResultAsNotemutation - Saves agent results as full-page note - Both mutations use indexed queries for ownership verification
- Parallel todo creation with
Promise.all()for efficiency
- Added
-
AgentTasksView.tsx - Action buttons for completed tasks
- Added action bar with "Create Todos" and "Save as Note" buttons
- Loading states and success feedback for actions
- Sparkles icon in header for navigation
-
FullPageNoteTabs.tsx - Download button added to toolbar
- New
handleDownloadMarkdownfunction for client-side downloads
- New
-
App.tsx - Updated header icon visibility and ESC handling
- Agent Tasks icon visible when in notes or chat views
- ESC key exits fullscreen before closing notes view
- Full mobile optimization for agent task action bar
- Responsive button sizing and spacing
- Touch-friendly targets on all new UI elements
-
AI Agent Tasks - Send todos and notes to Claude or OpenAI for AI-powered processing
- Send any todo or full-page note to AI agents via menu option or keyboard shortcut
- Choose between Claude (Anthropic) or OpenAI as your AI provider
- Five task types: Expand (brainstorm), Code (generate), Summarize, Analyze, or Other (custom instructions)
- Per-date and per-folder agent task views (contextual to your current location)
- Conversation threads with follow-up questions in the same chat
- Real-time status indicators (pending, processing, completed, failed)
- Markdown rendering with syntax-highlighted code blocks in results
- Copy results to clipboard with one click
- Delete tasks when no longer needed
-
Agent Tasks Keyboard Shortcut - Quick access to send focused todo to AI
- Press
Shift + Awhen a todo is focused to open the Agent Task modal - Added to keyboard shortcuts modal under Todo Management
- Press
-
Agent Tasks Header Icon - Access agent tasks from any date or folder view
- Sparkles icon in header toolbar to toggle Agent Tasks view
- Works alongside existing full-page notes and AI chat icons
- Checkbox icon to return to todos from Agent Tasks view
- Added
agentTaskstable with fields for userId, sourceId, sourceType, sourceContent, provider, taskType, status, result, messages, folderId, and date - Indexes:
by_user,by_user_and_status,by_user_and_date,by_user_and_folder - Messages array stores conversation history with role, content, and timestamp
-
Agent Tasks Module (
convex/agentTasks.ts)getAgentTasks- Query tasks filtered by date or foldercreateAgentTask- Create task and schedule processingdeleteAgentTask- Remove task with ownership verificationaddFollowUpMessage- Add follow-up to existing conversationupdateTaskStatus- Internal mutation for status updatesappendAssistantMessage- Internal mutation for AI responsesgetTaskForProcessing- Internal query for action processing
-
Agent Task Actions (
convex/agentTaskActions.ts)processAgentTask- Process initial task with Claude or OpenAIprocessFollowUp- Process follow-up messages with conversation context- Task-specific system prompts for expand, code, summarize, analyze, and other
- Full conversation history support for multi-turn interactions
-
AgentTaskModal.tsx - Modal for configuring and sending agent tasks
- Provider selection (Claude/OpenAI)
- Task type selection with descriptions
- Custom instructions textarea for "Other" task type
- Source content preview
-
AgentTasksView.tsx - View for displaying agent tasks and results
- Task list with status indicators and task type icons
- Conversation thread display with user/assistant message styling
- Markdown rendering with syntax highlighting
- Follow-up chat input for continuing conversations
- Copy and delete actions
-
App.tsx - Integration and state management
- Agent tasks state and modal data management
- Header icon for toggling agent tasks view
- Keyboard shortcut handler for Shift+A
-
KeyboardShortcutsModal.tsx - Added Shift+A shortcut documentation
-
TodoItem.tsx - Added "Send to Agent" menu option
-
FullPageNoteTabs.tsx - Added agent tasks button to toolbar
- Added
openaipackage (^4.79.0) for OpenAI API integration
- Inline Todo Notes in Project Folders - Fixed bug where inline notes on todos were showing up across different projects
- Notes in one project folder no longer appear in other project folders
- Each project folder now has its own isolated inline notes
- Notes are properly scoped to either a date OR a folder (not both)
- Inline Notes Support for Projects - Inline todo notes now work fully in project folders
- Create inline notes directly in project folder views
- Notes created in folders are associated with that folder (not a date)
- Pin notes to top within project folders
- Drag and drop reorder notes within project folders
- All note features (collapse, edit, delete, copy) work in folder context
- Updated
notestable withfolderIdfield (optional) for folder association - Made
datefield optional (notes can belong to a folder instead of a date) - Added
by_user_and_folderindex for efficient folder-based note queries
- Notes Module (
convex/notes.ts)- Added
getNotesByFolderquery for fetching notes by folder - Updated
getNotesByDateto filter out folder-associated notes - Updated
createNotemutation to accept optionalfolderIdparameter - Updated
reorderNotesmutation to support both date and folder-based reordering
- Added
-
NotesSection.tsx - Added folder support
- Added
folderIdprop toNotesSectionandPinnedNotesSectioncomponents - Components now query either by date or folder based on props
- Reorder operations pass correct parameters for folder context
- Added
-
TodoList.tsx - Folder-aware note creation
- Passes
folderIdtoNotesSectionandPinnedNotesSectionwhen in folder view - Note creation uses
folderIdinstead ofdatewhen in folder context
- Passes
-
Shareable URLs for Dates and Projects - Copy link to navigate directly to dates and projects
- Copy Link option in sidebar date menu copies shareable URL (e.g.,
/d/2026-01-02) - Copy Link option in sidebar project menu copies shareable URL with short slug (e.g.,
/p/ork88fqr) - Short NanoID-style slugs (8 alphanumeric characters) for project URLs
- Backwards compatible - supports both new slugs and legacy full Convex IDs
- Auto-generates slugs for existing folders without slugs when copying link
- URL navigation auto-expands and highlights the selected folder in sidebar
- Active folder header styling with theme-aware colors
- Copy Link option in sidebar date menu copies shareable URL (e.g.,
-
Sidebar Collapse Keyboard Shortcut - Quick toggle for sidebar visibility
- Press Cmd+. (Mac) or Ctrl+. (Windows/Linux) to toggle sidebar collapse
- Added to keyboard shortcuts modal (press
?to view)
- Added
slugfield to folders table for short URL slugs - Added
by_slugindex for efficient slug lookups
- Folders Module (
convex/folders.ts)- Added
generateSlug()helper function for 8-character alphanumeric slugs - Updated
createFoldermutation to auto-generate unique slugs - Added
getFolderBySlugquery (handles both slugs and full IDs for backwards compatibility) - Added
generateFolderSlugmutation for existing folders without slugs
- Added
-
App.tsx - URL routing and state management
- Changed route from
/p/:folderIdto/p/:folderSlug - Added
folderFromSlugquery to resolve folder by slug - Added URL sync guards to prevent race conditions during navigation
- Changed route from
-
Sidebar.tsx - Copy link and auto-expand functionality
- Added Copy Link to date and project menus
- Auto-expands folder when selected via URL navigation
- Added active class styling to folder headers
- Infinite Re-render Loop Fix - Fixed app crash when left open in browser
- Added refs to track Clerk modal state transitions (profile, sign-up, sign-in)
- User reload now only triggers when modal transitions from open to closed
- Prevents continuous re-render cycle that caused browser tab crashes
- No longer causes "Code 5" or similar runtime errors on live site
- Added
prevProfileModalRef,prevSignUpModalRef,prevSignInModalRefrefs - Modified useEffect hooks to check previous state before calling
user?.reload?.() - Refs update after each effect run to track current state
- Fix applies to all three authentication modal close handlers
-
AI Chat Image and Link Support - Upload images and attach links for AI analysis
- Upload up to 3 images per message (PNG, JPEG, GIF, WebP, max 3MB each)
- Attach up to 3 links per message to scrape web content
- Auto-detects URLs in message text and scrapes them automatically
- Claude vision analyzes uploaded images for questions and context
- Firecrawl integration for scraping tweets, LinkedIn posts, blogs, PDFs
- Image preview thumbnails before sending
- Link preview pills with remove functionality
- Link attach modal with URL validation
- Image upload button with file picker
- Mobile-responsive attachment UI
- Images stored in Convex file storage
-
Streaks Icon Inline SVG - Replaced external SVG file with inline component
- Uses currentColor for theme-aware styling
- Removes dependency on external image file
- Better performance and consistency
-
Schema (
convex/schema.ts)- Updated
aiChatsmessages to includeattachmentsfield - Attachments support images (storageId) and links (url, scrapedContent, title)
- Updated
-
AI Chats Module (
convex/aiChats.ts)- Added
generateUploadUrlmutation for image uploads - Added
getStorageUrlandgetStorageUrlInternalqueries for image URLs - Added
addUserMessageWithAttachmentsmutation for messages with attachments - Updated validators to support attachment types
- Added
-
AI Chat Actions (
convex/aiChatActions.ts)- Integrated Firecrawl SDK for URL scraping
- Added Claude vision support for image analysis
- Auto-detect URLs in messages (max 3 per message)
- Parallel URL scraping for performance
- Truncate scraped content to 8000 chars to avoid token limits
- Added
@mendable/firecrawl-jsfor web scraping
- Added
FIRECRAWL_API_KEYrequirement for link scraping functionality
- AI Writing Assistant - Built-in AI chat for writing assistance on each date
- Access AI chat from the MessageCircle icon in the header on any date page
- Each date has its own separate chat session with full conversation history
- Powered by Claude (claude-opus-4-5) for high-quality writing assistance
- Chat sessions persist in the database and maintain context across conversations
- Real-time message updates with Convex subscriptions
- Markdown rendering for AI responses with full syntax support
- Copy button on each AI message for easy content extraction
- Auto-expanding textarea input with smart height adjustment
- Press "/" key to quickly focus the chat input from anywhere
- Enter to send, Shift+Enter for new lines
- Input position toggle (centered or left-aligned) with preference saved to localStorage
- Mobile-optimized interface with responsive design
- Chat indicator appears in sidebar under dates that have active conversations
- Authentication required - only authenticated users can access AI chat
- Full conversation context maintained (last 20 messages sent to Claude for context)
- Searchable chat content indexed for future search capabilities
The AI chat feature provides writing assistance for each date in your todo list. Here's how it works:
- Access: Click the MessageCircle icon in the header on any date page to open the AI chat
- Chat Sessions: Each date has its own separate chat session, so conversations are organized by date
- Conversation History: All messages are stored in the database and maintain full context
- AI Processing: When you send a message, it's processed by Claude with the last 20 messages as context
- Real-time Updates: Messages appear instantly via Convex real-time subscriptions
- Markdown Support: AI responses render with full markdown support including code blocks, lists, and formatting
- Schema:
aiChatstable stores chat sessions with userId, date, messages array, and searchable content - Queries:
getAIChatByDatefetches chat history for a specific date - Mutations:
getOrCreateAIChat,addUserMessage,addAssistantMessagemanage chat data - Actions:
generateResponsecalls Claude API with conversation context and system prompts - Indexes: Optimized queries with
by_user_and_dateandby_userindexes - Search: Full-text search index on
searchableContentfield for future search capabilities
-
Pomodoro Duration Toggle While Paused - Change timer duration (25, 50, 90 min) while paused
- Available in both modal and full-screen views when timer is paused
- Cycles through: 25 min focus → 50 min steady → 90 min flow state
- Uses icons: Waves (25 min), Activity (50 min), Clock (90 min)
- Smooth transition with single database patch (no flickering)
- Timer resets to new duration and stays paused
- Tooltip shows duration label on hover
-
Move to Next Day - New option in date menu to move incomplete todos to the next day
- Copies all non-completed, non-archived todos from source date to the next day
- Archives the original todos after moving (keeps history clean)
- Idempotent mutation with early returns (no duplicate operations)
- Uses timestamp-based ordering for new todos (avoids write conflicts)
- Parallel operations with
Promise.all()for efficient processing - Located in sidebar date menu alongside existing copy options
-
Query Guards - Added authentication guards to all Convex queries in Sidebar
- Prevents unnecessary subscriptions when user is not authenticated
- Uses
isAuthenticated ? undefined : "skip"pattern for all sidebar queries - Reduces memory pressure and potential race conditions
-
Page Crash Error - Fixed page crashing error when navigating between dates
-
Pomodoro Module (
convex/pomodoro.ts)- Added
updatePomodoroPresetmutation for changing duration while paused - Single patch operation (no stop/start cycle) for smooth UI transitions
- Uses indexed queries for ownership checks
- Idempotent with early return if session not found
- Added
-
Todos Module (
convex/todos.ts)- Added
moveTodosToNextDaymutation for moving todos between dates - Follows Convex best practices: idempotent, indexed queries, parallel operations
- Uses timestamp-based ordering for new todos to avoid write conflicts
- Added
-
AI-Free Streaks - Removed all AI functionality from the app
- Removed OpenAI dependency and badge generation
- Streaks now work completely without AI - pure JavaScript date calculations
- Removed
badgestable from schema - Removed
getBadges,generateBadge,saveBadge, andmarkBadgesAsSeenfunctions - Removed
hasUnseenBadgesfield from streaks table - Streaks feature remains fully functional with all tracking capabilities
-
Streamlined Streaks Page - Simplified layout with focus on your data
- Moved "Your Stats" section to right column (where badges were)
- Removed badges grid and year selector
- Two-column layout now shows: left = streak stats, right = your personal stats
- All sections align at the top for cleaner visual hierarchy
- Maintains responsive design for mobile, tablet, and desktop
- Light Mode Delete Button - Added proper theme-aware dangerous button borders
- Fixed missing border color on delete confirmation buttons in light mode
- Added explicit dangerous button styling for all themes (dark, light, tan, cloud)
- Consistent red (#e16d76) color across all themes for destructive actions
- Badge System - Complete removal of AI-generated badges
- Deleted
convex/badgeTest.tstest file - Deleted
src/pages/BadgeTest.tsxpage component - Deleted
src/components/BadgeModal.tsxmodal component - Deleted
BADGE_IMPLEMENTATION_SUMMARY.mddocumentation - Removed
/badgetestroute from App.tsx - Updated app descriptions to reflect AI-free status
- Deleted
-
Streaks Module (
convex/streaks.ts)- Removed OpenAI import and all badge generation logic
- Simplified
getStreakStatusreturn type (removedhasUnseenBadges) - Removed badge milestone checks from
updateStreak - Pure JavaScript streak calculations with no AI dependencies
- Maintained all core streak tracking functionality
-
Schema Updates (
convex/schema.ts)- Removed
badgestable definition - Removed
hasUnseenBadgesfield fromstreakstable - Cleaner, simpler schema focused on core features
- Removed
-
Package Updates (
package.json)- Removed
openaipackage dependency - Smaller bundle size and faster builds
- Removed
-
Streaks Page (
src/pages/StreaksPage.tsx)- Removed badge-related state and functions
- Simplified imports (removed BadgeModal, useEffect, useMutation)
- Moved stats section to right column
- Removed year selector and badge modal rendering
- Cleaner, more focused component
-
App Component (
src/App.tsx)- Removed BadgeTest import and route
- Updated feature descriptions: "Streak tracking for daily todo completion"
- Removed mentions of "AI-generated badges"
-
Styles (
src/styles/global.css)- Added theme-specific dangerous button styling for all themes
- Improved visual consistency across light, dark, tan, and cloud modes
- Mini Stats Section on Streaks Page - Personal statistics overview below streak cards
- Displays user-specific statistics (excludes total users from global stats)
- Stats shown: Todos Created, Completed, Active, Pinned, Archived, Full-Page Notes, Todo Notes, Pomodoro Sessions, Folders
- Completion rate percentage with subtitle on "Completed" stat
- Responsive grid layout: auto-fit columns on desktop, single column on mobile, 2 columns on tablet
- Matches streaks page theme and UI with icon-based cards
- Same width as two-column layout above it
- Hover effects with subtle transform animation
- Stats Module Updates (
convex/stats.ts)- Added
getUserStatsquery: Returns user-specific statistics for authenticated user- Uses indexed queries (
by_user,by_user_and_date) for efficient lookups - Queries:
todos,notes,fullPageNotes,pomodoroSessions,folders - Returns counts for all stat categories
- Returns null if user not authenticated
- Uses indexed queries (
- Added
- Streaks Page Updates (
src/pages/StreaksPage.tsx)- Added
userStatsquery integration - Added lucide-react icons for stat cards
- Added
formatNumberhelper for number formatting with commas - Added
calculatePercentagehelper for completion rate - Created mini stats grid with 9 stat cards
- Positioned below two-column layout, above year selector
- Added
- Global CSS Updates (
src/styles/global.css)- Added
.streaks-mini-statscontainer styles - Added
.streaks-mini-stats-titlefor section heading - Added
.streaks-mini-stats-gridwith responsive grid - Added
.streaks-mini-stat-cardwith hover effects - Added icon and content layout styles
- Mobile responsive: single column, reduced padding
- Tablet responsive: auto-fit 180px columns
- Added
- Streaks Feature - Track your todo completion momentum with streaks and badges
- Streak Tracking - Automatic tracking of consecutive days completing all regular date-based todos
- Current streak counter showing ongoing consecutive days
- Longest streak counter showing personal best
- Total todos completed counter
- Weekly progress visualization showing 7-day completion status
- Completion rate percentage based on tracked days
- Next milestone progress bar with target goals (3, 5, 7, 10, 30, 60, 90, 365 days)
- Streaks Page - Dedicated streaks dashboard at
/streaksroute- Two-column layout: left shows stats, right shows earned badges
- Takes up 80% of page width (90% on tablet, 100% on mobile) for optimal viewing
- HUD-inspired sci-fi tech interface with corner decorations
- Weekly calendar visualization with day indicators (past, today, future)
- Theme switcher in top right corner (matches sidebar theme toggle)
- App name "better todo" in top left serves as back button to home
- Real-time sync with Convex for instant updates
- Mobile responsive with single-column stacked layout
- Streaks Header Button - Quick access from main app header
- Fire icon (rise.svg) with 7-bar weekly progress indicator
- Bars disappear as you complete todos for each day of the week
- Bars reset every Sunday at 12:01 am
- Bar color matches active date theme color for each theme (green/dark, blue/light, orange/tan, black/cloud)
- Only visible for authenticated users
- AI-Generated Badges - Unique achievement badges using OpenAI DALL-E 3
- "First Step" badge: Complete your first todo
- "Day One Done" badge: Complete all todos for a single day
- Streak milestone badges: 3-day, 5-day, 7-day, 10-day, 30-day, 60-day, 90-day, 365-day streaks
- All badges are grayscale with transparent backgrounds
- Fortnite-style geometric designs with 3D metallic rendering
- Each badge is unique with randomized silhouettes, symbols, and finishes
- Badges grid displays all earned badges with larger images (96px)
- Year selector dropdown to view badges from previous years
- Smart Todo Filtering - Only tracks regular date-based todos
- Excludes full-page notes (from fullPageNotes table)
- Excludes todo page notes (from notes table)
- Excludes folder todos (todos with folderId)
- Excludes backlog todos (todos with backlog: true)
- Excludes pinned todos (todos with pinned: true)
- Excludes archived todos (todos with archived: true)
- Only counts todos with a date field (YYYY-MM-DD format)
- User-Scoped Data - Complete data isolation and privacy
- All queries use indexed lookups with userId
- Each user only sees their own streak data and badges
- No cross-user data leakage
- Streak Tracking - Automatic tracking of consecutive days completing all regular date-based todos
-
Schema Updates (
convex/schema.ts)- Added
streakstable with fields:userId: User identifier (indexed)currentStreak: Current consecutive days streaklongestStreak: Personal best streaklastCompletedDate: Last date all todos were completed (YYYY-MM-DD)weeklyProgress: Record of daily completion status (dynamic date keys)totalTodosCompleted: Count of all completed regular todos
- Added
badgestable with fields:userId: User identifier (indexed)slug: Unique badge identifier (e.g., "first-todo", "3-day-streak")name: Display name (e.g., "First Step", "3 Day Streak")description: Badge descriptionimageUrl: URL to stored badge image in Convex storageearnedAt: Timestamp when badge was earned
- Added
-
Streaks Module (
convex/streaks.ts)getStreakStatusquery: Fetches current user's streak data with defaultsgetBadgesquery: Gets all earned badges for user in descending orderupdateStreakinternal mutation: Updates streak on todo completion/deletion- Filters todos to only track regular date-based todos
- Checks if all todos for a date are completed
- Calculates consecutive day streaks
- Updates weekly progress record
- Triggers badge generation for milestones
- Idempotent with early returns to prevent write conflicts
generateBadgeinternal action: Calls OpenAI DALL-E 3 to create badge images- Uses environment variable OPENAI_API_KEY for authentication
- Generates grayscale geometric badge designs
- Stores image in Convex storage
- Comprehensive console logging for debugging
saveBadgeinternal mutation: Saves badge metadata to database
-
Todos Module Updates (
convex/todos.ts)- Updated
updateTodomutation to trigger streak updates- Only triggers for regular date-based todos (excludes folder/backlog/pinned)
- Checks if todo has date, not in folder, not backlog, not pinned
- Schedules streak update on completion or archive status change
- Updated
deleteTodomutation to trigger streak updates- Recalculates streak when regular date-based todo is deleted
- Ensures streak stays accurate after deletions
- Updated
-
StreaksHeader Component (
src/components/StreaksHeader.tsx)- Displays fire icon (rise.svg) in app header
- Shows 7-bar weekly progress indicator
- Bars use theme-specific colors matching active date colors
- Navigates to
/streaksroute on click - Only visible for authenticated users
-
StreaksPage Component (
src/pages/StreaksPage.tsx)- Dedicated streaks dashboard with two-column layout
- Left column displays:
- Current streak number with "Day Streak" label
- Longest streak and total completed stats
- Weekly calendar with Sun-Sat day indicators
- Completion rate percentage with progress bar
- Next milestone progress with target goal
- Right column displays:
- Earned badges grid with larger images (96px)
- Badge name and description for each
- "Complete todos to earn badges" message when empty
- Year selector dropdown for viewing previous years' badges
- Theme switcher button in top right
- App name "better todo" in top left serves as back button
- HUD-style corner decorations on main streak card
- Mobile responsive with single-column stacked layout
-
App Component Updates (
src/App.tsx)- Added
/streaksroute for StreaksPage component - Integrated StreaksHeader in main header next to search button
- Added
-
Styling Changes (
src/styles/global.css)- Added
.streaks-header-buttonstyles for header button - Added
.streaks-iconstyles with theme-specific filters - Added
.streaks-bar-containerand.streaks-barfor weekly progress - Bar colors match theme: green (dark), blue (light), orange (tan), black (cloud)
- Added
.streaks-pagecontainer with 80% width on desktop - Added
.streaks-two-columngrid layout (360px + 1fr on desktop) - Added
.streaks-currentcard with HUD corner decorations - Added
.streaks-week-cardfor weekly calendar display - Added
.streaks-week-daywith day labels and indicators - Added
.streaks-metric-cardfor completion rate and milestone progress - Added
.streaks-badges-gridwith auto-fill columns (minmax(160px, 1fr)) - Added
.streaks-badgestyles with larger images (96px) and padding (20px) - Mobile responsive: 100% width, single column, adjusted sizes
- Tablet responsive: 90% width, adjusted column sizes
- Added
| Badge | Milestone |
|---|---|
| First Step | Complete 1 todo (ever) |
| Day One Done | Complete ALL todos for a single day |
| 3 Day Streak | Complete ALL todos for 3 consecutive days |
| 5 Day Streak | Complete ALL todos for 5 consecutive days |
| 7 Day Streak | Complete ALL todos for 7 consecutive days |
| 10 Day Streak | Complete ALL todos for 10 consecutive days |
| 30 Day Streak | Complete ALL todos for 30 consecutive days |
| 60 Day Streak | Complete ALL todos for 60 consecutive days |
| 90 Day Streak | Complete ALL todos for 90 consecutive days |
| 365 Day Streak | Complete ALL todos for 365 consecutive days (1 year!) |
- OpenAI API Key: Set
OPENAI_API_KEYin Convex environment variables (both production and development)- Used by
generateBadgeaction to call DALL-E 3 API - Required for badge generation to work
- Console logging helps debug API connection issues
- Used by
- Streaks only track regular date-based todos (not notes, folder todos, backlog, or pinned todos)
- Badge generation is asynchronous using Convex scheduled functions
- All streak operations are user-scoped with indexed queries for performance
- Mutations are idempotent with early returns to prevent write conflicts
- Weekly progress uses dynamic date keys (YYYY-MM-DD format)
- Badge images stored in Convex storage with permanent URLs
- Real-time sync ensures instant updates across all devices
- Shareable Full-Page Notes - Share read-only links to your notes with custom URL slugs
- Share button in full-page note tabs to generate shareable links
- Custom URL slugs (alphanumeric, hyphens, underscores, 3-50 characters)
- Random slug generation if no custom slug provided
- Reserved slugs protection (api, admin, share, etc.)
- Public
/share/:slugroute accessible without authentication - Share modal with copy-to-clipboard functionality
- Optional hide title on shared note setting
- Ability to edit custom slugs after creating share link
- Revoke share link to make note private again
- Open shared note in new tab from share modal
- Theme-aware shared note viewer with theme toggle
- Copy note content from shared view
- Real-time Open Graph meta tags for social sharing
- First image from note used as preview image
- Instant loading with Convex real-time sync (no loading states)
- Footer with link back to better-todo
- Works with markdown, code blocks, and images
-
Full-Page Notes Schema (
convex/schema.ts)- Added
shareSlugfield with index for efficient lookup - Added
isSharedboolean field - Added
hideHeaderOnShareoptional field - Added
imageIdsarray for tracking uploaded images
- Added
-
Full-Page Notes Module (
convex/fullPageNotes.ts)- Added
generateShareLinkmutation for creating shareable links - Added
revokeShareLinkmutation to make notes private - Added
updateShareSlugmutation to edit custom slugs - Added
updateHideHeadermutation for title visibility - Added
checkSlugAvailabilityquery (public, no auth) - Added
getNoteBySlugquery (public, no auth) with image URLs - Added
getSharedNoteMetadatainternal query for Open Graph tags - All mutations are idempotent with early returns
- Slug validation with reserved words protection
- Random 8-character slug generation with uniqueness checks
- Added
-
HTTP Routes (
convex/http.ts)- Added
/meta/share/:slugendpoint for bot metadata - Serves Open Graph tags to social media crawlers
- Returns 404 for non-shared or missing notes
- Added
-
ShareLinkModal Component (
src/components/ShareLinkModal.tsx)- New modal for managing shareable links
- Custom slug input with validation and availability checking
- Copy to clipboard with visual confirmation
- Hide title on share toggle
- Edit custom slug functionality
- Revoke share link button
- Open shared note in new tab
- Theme-aware styling matching app design
- Mobile responsive with proper spacing
-
SharedNoteView Page (
src/pages/SharedNoteView.tsx)- Public shared note viewer at
/share/:slug - Instant loading with Convex real-time sync
- Renders markdown with full syntax highlighting
- Displays images with proper sizing and alignment
- Theme toggle (dark, light, tan, cloud)
- Copy note content button
- Footer with link back to better-todo
- Dynamic Open Graph meta tags
- Uses first image as preview for social sharing
- Error handling for invalid/missing notes
- Mobile responsive design
- Public shared note viewer at
-
FullPageNoteTabs Component (
src/components/FullPageNoteTabs.tsx)- Added share icon button for authenticated users
- Opens share modal for generating links
- Visual indicator if note is already shared
- Open shared note in new tab button
- Share button only visible when authenticated
-
App Component (
src/App.tsx)- Added
/share/:slugroute for public shared notes - Share modal state management
- Proper routing with React Router
- Added
-
Netlify Configuration (
netlify.toml)- Edge function route for bot detection
- Serves meta tags to social media crawlers
- Client-side routing for shared notes
- Global CSS (
src/styles/global.css)- Added
.shared-note-viewcontainer styles - Added
.shared-note-headerand.shared-note-titlestyles - Added
.shared-note-contentmarkdown rendering styles - Added
.shared-note-imagewith size and alignment classes - Added
.shared-note-textfor text block rendering - Added
.shared-note-errorand.shared-note-loadingstates - Added
.shared-note-footerwith theme toggle and copy button - Added
.shared-note-footer-linkwith theme-aware colors - Added
.shared-note-theme-togglebutton styles - Theme-specific styling for all four themes (dark, light, tan, cloud)
- Mobile responsive with proper spacing and font sizes
- Added
- Pomodoro Timer Keyboard Shortcut - Quickly access timer with Shift + F
- Opens Pomodoro timer modal from anywhere in the app
- Listed in keyboard shortcuts modal (press ? to view all shortcuts)
- Works alongside existing "f" shortcut to enter full-screen mode when timer is open
- Keyboard shortcut works whether timer is idle, running, or paused
- Phase Badge Theming - Phase badges now match your selected theme
- Focus and Break badges use theme variables for consistent colors across all themes
- Background uses
var(--bg-secondary) - Text color uses
var(--text-primary) - Border uses
var(--border-color) - Adapts seamlessly to dark, light, tan, and cloud themes
- Glass effect phase badges (when background image is enabled) remain white for readability
- Full-Screen Timer Flash - Eliminated flash when entering full-screen Pomodoro mode
- Timer now appears centered immediately without flashing in corner first
- Removed fade-in animations that caused layout calculation delays
- Removed pulse animation that changed opacity
- All elements pre-positioned with proper flexbox centering
- Smoother, more professional transition to full-screen mode
-
PomodoroTimer Component (
src/components/PomodoroTimer.tsx)- Removed unused
startPomodoromutation import from TodoItem - Updated
useEffectdependencies for proper effect tracking - Fixed modal trigger logic to work with or without todo context
- Removed unused
-
App Component (
src/App.tsx)- Added Shift + F keyboard shortcut handler for opening Pomodoro timer
- Keyboard shortcut respects text input focus (won't trigger while typing)
-
KeyboardShortcutsModal Component (
src/components/KeyboardShortcutsModal.tsx)- Added "Shift + F" to Pomodoro Timer shortcuts section
-
Global CSS (
src/styles/global.css)- Updated
.phase-focusand.phase-breakto use CSS variables - Added flexbox centering to
.pomodoro-fullscreen-content - Added width constraints to prevent layout shifts
- Removed problematic animations causing flash
- Updated
- Todo Input UI Redesign - Refined the todo composer with a modern, compact interface
- New rounded container (650px max width on desktop) with background matching
var(--bg-secondary) - Added ArrowUp icon submit button (24px) from Radix UI for one-click todo creation
- Removed box shadows for cleaner visual design
- Responsive sizing across all breakpoints (22px on tablet, 20px on mobile, 18px on small devices)
- Button integrates seamlessly with existing keyboard shortcuts (Enter/Shift+Enter)
- Disabled state (55% opacity) when input is empty
- New rounded container (650px max width on desktop) with background matching
-
Todos in Project Folders - Projects can now contain todos directly
- Todos can be moved to project folders and disconnected from dates
- Each project can have multiple dateless todos organized independently
- Todos show in expandable "Todos" section within project folders in sidebar
- Todos moved to project remove date association, todos moved to date remove folder association
- Project folder todos support all features: drag-and-drop reordering, subtasks, headers, completion, archiving
- Creating new todos within a project folder automatically makes them dateless todos for that project
- Paste multiple todos at once in project folders
-
Full-Page Notes Back Navigation - Added back button next to View full-page notes icon
- Back button returns to appropriate location (date or today) depending on where user was
- Shows only when viewing full-page notes
- Uses CheckboxIcon from Radix UI
-
Empty Project Folders Visible - Project folders now show immediately when created
- Empty folders appear in sidebar even without content
- Allows better organization and planning
-
Project Folder Organization - Improved project folder display and organization in sidebar
- Removed "Manage Projects" section - all project folders now appear in main Folders section
- Project folders are sorted alphabetically for easier navigation
- Folders appear below dates and above "+ Add Project" button
- Removed "(empty)" label from folder display
- Count badges show next to "Todos" and "Notes" toggles within folders, not on folder name
- Clicking "Todos" in a folder directly shows todos (no "View all todos" dropdown)
-
Full-Page Note Navigation - Improved note selection and folder highlighting
- Opening a note from a folder now selects and expands that folder in sidebar
- Auto-expands folder and notes section when note is selected
- Consistent sidebar highlighting across all navigation paths
-
TypeScript Build Errors - Fixed type compatibility issues in TodoList component
- Converted
nulltoundefinedwhen passingfolderIdprop to TodoItem components - Ensures proper type safety for folder associations
- Added explicit types to
existingTodosandexistingSubtasksin createTodo and createSubtask mutations
- Converted
-
Todo Deletion Robustness - Improved todo deletion handling
- Made deleteTodo mutation idempotent (safe to call multiple times)
- Returns null instead of throwing error if todo doesn't exist
- Automatically deletes all subtasks when header is deleted (cascading delete)
- Prevents orphaned subtasks and race condition errors
-
Todos Schema (
convex/schema.ts)- Added
folderIdfield to todos table for folder associations - Added
by_user_and_folderindex for efficient folder-based queries
- Added
-
Todos Module (
convex/todos.ts)- Added
getTodosByFolderquery to fetch todos for specific folder (including subtasks) - Added
getTodoCountsByFolderquery to get uncompleted todo counts per folder - Added
moveTodoToFoldermutation to move todos to project folders - Added
moveTodoFromFolderToDatemutation to move todos back to dates - Updated
createTodoto support both date and folderId parameters - Updated
createSubtaskto inherit folderId from parent todo - Updated
deleteTodoto be idempotent and cascade delete subtasks - Updated all date-based queries to exclude folder-associated todos
- Added
-
Sidebar Component (
src/components/Sidebar.tsx)- Added
TodosForFoldercomponent to display todos within folders - Removed expand/collapse dropdown for folder todos
- Updated
NotesForFolderto always fetch notes for count display - Added count badges to "Todos" and "Notes" toggles within folders
- Updated
onOpenFullPageNotecallback to accept optionalfolderIdparameter - Added auto-expansion logic for folders when notes are selected
- Updated folder filtering to show all active folders (including empty ones)
- Removed "Manage Projects" section completely
- Added
-
App Component (
src/App.tsx)- Added
selectedFolderstate for folder-based navigation - Added
folderTodosquery to fetch todos for selected folder - Updated
displayTodoslogic to show folder todos when folder is selected - Updated header to show folder name when viewing folder todos
- Added back button with CheckboxIcon next to View full-page notes icon
- Updated back button logic to handle both date and folder contexts
- Updated
onOpenFullPageNotehandler to set folder selection for folder notes
- Added
-
TodoList Component (
src/components/TodoList.tsx)- Added
folderIdprop support - Updated
handleAddTodoto create dateless todos in folders - Updated paste handler to support creating folder todos
- Passes
folderIdto TodoItem components with proper type conversion
- Added
-
TodoItem Component (
src/components/TodoItem.tsx)- Added "Move to Project..." menu option
- Added "Move to Date..." menu option (when todo is in folder)
- Added folder selector modal for moving todos to projects
- Context-aware menu based on whether todo is in folder or date
- Pomodoro Timer Duration Toggle - Switch between 25-minute focus sessions and 90-minute flow state sessions
- Waves icon to switch from 25 minutes to 90-minute flow state mode
- Clock icon to switch back from 90 minutes to 25-minute focus mode
- Duration toggle button appears next to Start button in timer modal (only visible when timer is idle)
- All timer features work identically for both durations (audio, fullscreen, pause, resume, reset, stop)
- Selected duration persists when starting new timer sessions
- Display time updates immediately when switching durations
- Pomodoro Timer Sound Auto-Play - Fixed sounds playing automatically when timer session is restored from previous page load
- Sounds now only play when user explicitly clicks Start or Reset button in current session
- Countdown sound (5-second warning) only plays if user started timer in current session
- Completion sound only plays if user started timer in current session
- All sounds respect mute state regardless of when timer was started
- Prevents unexpected audio interruptions when navigating to app with active timer
- Pomodoro Module (
convex/pomodoro.ts)- Updated
startPomodoromutation to accept optionaldurationMinutesparameter (defaults to 25 if not provided) - Supports flexible duration settings while maintaining backward compatibility
- Updated
- PomodoroTimer Component (
src/components/PomodoroTimer.tsx)- Added
durationMinutesstate to track selected duration (25 or 90 minutes) - Added
userStartedInThisSessionref to track if timer was started in current browser session - Added
handleToggleDurationfunction to switch between 25 and 90 minute durations - Updated
handleStartandhandleResetto pass duration to mutation - Added Waves and Clock icons from lucide-react for duration toggle
- Duration toggle button only visible when timer is idle (not running or paused)
- Updated sync effect to use
durationMinutesfor display time when no session exists - Sounds only play when
userStartedInThisSessionis true (prevents auto-play on page reload)
- Added
-
Full-Page Notes in Projects - Projects (folders) can now contain full-page notes
- Full-page notes can be moved to projects and disconnected from dates
- Each project can have multiple full-page notes with their own tabs
- Notes show "Notes" folder in sidebar when project is expanded
- Notes moved to project remove date association, notes moved to date remove folder association
- Archive support: archived projects show their notes but prevent creating new ones
-
Project Deletion Warnings - Added confirmation dialog when deleting projects
- Shows count of full-page notes that will be deleted
- Warning message: "This will permanently delete all X full-page note(s) in this project..."
- Matches existing confirmation dialog design system
-
Archive Support for Project Notes - Full-page notes archive with their projects
- When archiving a project, all notes in it are archived
- When unarchiving a project, all notes are unarchived
- Archived projects show their notes in read-only mode
- Cannot create new notes in archived projects
-
Line Breaks in Notes - Fixed line breaks in full-page notes and todo notes
- Added
remark-breaksplugin to preserve single line breaks in markdown - Line breaks now render correctly in plain/normal mode and all mode
- Added
-
Tab Switching for Folder Notes - Fixed content not updating when switching between full-page note tabs from projects
- Added
getFullPageNotesByIdsquery to fetch notes for all open tabs - Tab switching now works for both date-based and folder-based notes
- Added key prop to
FullPageNoteViewto force remount on tab switch
- Added
-
Archived Dates in Sidebar - Fixed bug where archived dates appeared in both active and archived sections
- Active folders now filter out archived dates
- Active month groups now filter out archived dates
- Archived dates only show in "Archived" section
- Full-Page Note Creation - Updated note creation to support both dates and projects
createFullPageNotemutation now accepts eitherdateorfolderId(not both)- Create button detects current context and creates note in same folder or date
- Notes in projects maintain proper order within their folder
-
Schema Updates (
convex/schema.ts)- Added
archived: v.optional(v.boolean())field tofullPageNotestable - Notes can be archived independently or with their parent project
- Added
-
Full-Page Notes Module (
convex/fullPageNotes.ts)- Added
getFullPageNotesByIdsquery for fetching notes by ID array - Updated
getFullPageNotesByDateto filter out archived notes - Updated
getFullPageNotesByFolderto acceptincludeArchivedparameter - Updated
createFullPageNoteto support both date and folderId creation - Added
archivedfield to all query return validators - Count queries now exclude archived notes from active counts
- Added
-
Folders Module (
convex/folders.ts)- Updated
deleteFolderto delete all full-page notes in the folder - Updated
archiveFolderto archive all notes in parallel - Updated
unarchiveFolderto unarchive all notes in parallel
- Updated
-
App Component (
src/App.tsx)- Added
getFullPageNotesByIdsquery for open tabs - Combined date-based and tab-based note fetching
- Updated note creation to detect folder context
- Blocks creating new notes in archived folders
- Added
-
Sidebar Component (
src/components/Sidebar.tsx)- Added
NotesForFoldercomponent withisArchivedFolderprop - Updated folder deletion confirmation to show note count
- Added filtering of archived dates from active folders/month groups
- Archived folders show notes with
includeArchived: true
- Added
-
Full-Page Note View (
src/components/FullPageNoteView.tsx)- Added
remark-breaksplugin for line break preservation - Removed code block headers (language label and copy button)
- Added
-
Notes Section (
src/components/NotesSection.tsx)- Added
remark-breaksplugin for todo note line breaks
- Added
- Added
remark-breakspackage for markdown line break support
- Simplified Full-Page Notes - Streamlined full-page notes interface for better focus and performance
- Removed format toggle dropdown (format selection feature)
- Removed markdown split-screen preview (edit and preview side-by-side)
- Removed image upload functionality
- Removed hide/show preview toggle
- Full-page notes now focus on core editing and markdown rendering
- Instant loading with Convex real-time sync (no loading states)
- Instant Note Loading - Full-page notes now load instantly without showing "Loading note..." message
- Leverages Convex real-time synchronization for instant data display
- Improved user experience with seamless note loading
- FullPageNoteView Component (
src/components/FullPageNoteView.tsx)- Removed format toggle UI and related state management
- Removed split-screen preview functionality
- Removed image upload handlers and file input
- Removed preview visibility toggle
- Simplified component to focus on core editing and markdown rendering
- Removed unused imports (TriangleRightIcon, TriangleDownIcon, ImageIcon, EyeNoneIcon, EyeOpenIcon, Keyboard)
- Removed format-related mutations (generateUploadUrl, getImageUrl)
- Changed loading state to return
nullinstead of loading message for instant display
- Stats Page User Count - Fixed stats page to read total user count from Clerk instead of Convex database
- Updated
getStatsquery to call Clerk's backend API viagetUserCountFromClerkaction - Added
getUserCountFromClerkaction that fetches user count from Clerk API - Now shows accurate count of all registered users from Clerk authentication system
- Requires
CLERK_SECRET_KEYenvironment variable in Convex settings
- Updated
- Stats Module (
convex/stats.ts)- Added
getUserCountFromClerkaction to fetch user count from Clerk API - Updated
getStatsquery to use Clerk API instead of querying local users table - Added proper error handling for missing API keys or failed requests
- Added
- Full Markdown Support in Notes - Comprehensive markdown rendering in notes and full-page notes
- All text content now supports markdown formatting (bold, italic, headers, lists, links, tables, blockquotes)
- Works automatically without needing to type ````md` - just write markdown and it renders
- Code blocks continue to work with triple backticks (
js`,css`, etc.) - Preserves existing code block syntax highlighting functionality
- Added
react-markdownandremark-gfmfor GitHub Flavored Markdown support - Markdown renders in display mode, edit mode shows plain text with markdown syntax
-
NotesSection Component (
src/components/NotesSection.tsx)- Replaced plain text rendering with ReactMarkdown component
- Added remarkGfm plugin for enhanced markdown features (tables, task lists, strikethrough)
- Updated placeholder text to mention markdown support
- Text blocks now use
.note-markdown-blockclass for styling - Exit edit mode on blur or ESC - Clicking outside note or pressing ESC now renders markdown immediately
-
FullPageNoteView Component (
src/components/FullPageNoteView.tsx)- Replaced plain text rendering with ReactMarkdown component
- Added remarkGfm plugin for enhanced markdown features
- Updated placeholder text to mention markdown support
- Text blocks now use
.note-markdown-blockclass for styling - Exit edit mode on blur or ESC - Clicking outside note or pressing ESC now renders markdown immediately
-
KeyboardShortcutsModal Component (
src/components/KeyboardShortcutsModal.tsx)- Added
md` andmarkdown` to code blocks section - Updated section title to "Markdown & Code Blocks in Notes"
- Updated description to mention default markdown support
- Added
-
Launch Page (
src/pages/Launch.tsx)- Updated "Key features" list to mention full markdown support
- Enhanced "Full-page notes" section with detailed markdown capabilities (bold, italic, headers, lists, links, tables, blockquotes)
- Expanded "Built for developers" section with comprehensive markdown and code block details
- Listed supported languages (JavaScript, TypeScript, CSS, HTML, Python, Go, Rust)
- Global CSS (
src/styles/global.css)- Added comprehensive
.note-markdown-blockstyling for all markdown elements - Styled headers (h1-h6) with proper sizing and borders
- Styled lists (ul, ol) with proper indentation and bullet styles
- Styled links with accent color and hover effects
- Styled blockquotes with left border and italic text
- Styled inline code with background and monospace font
- Styled tables with borders and header background
- Styled images with max-width and border-radius
- Styled horizontal rules with border styling
- All styles respect theme variables (light, dark, tan, cloud)
- Added comprehensive
- Added
react-markdown@^9.0.1for markdown parsing and rendering - Added
remark-gfm@^4.0.0for GitHub Flavored Markdown support (tables, task lists, strikethrough)
Users can now write notes with markdown syntax naturally:
**bold text**renders as bold*italic text*renders as italic# Headerrenders as header- list itemrenders as bullet list[link](url)renders as clickable link- Tables, blockquotes, and more all supported
- Code blocks continue using triple backticks with language tags
No need to wrap content in ````md` blocks - markdown works by default for all text content!
- Cloud Theme - Fourth theme option with minimal grayscale design
- Primary background: #EDEDED (light gray)
- Secondary background: #E8E8E8 (slightly darker gray)
- Text colors: #171717 (near black)
- Interactive accent: #171717 (consistent dark gray)
- Minimal color palette for distraction-free focus
- Cycle through all four themes with half-moon icon in sidebar
- Theme persists across sessions and devices
- Radix Half2 icon for cloud theme indicator
- Full support for all app features including Clerk modals
- Mobile responsive with consistent design
- Theme Context (
src/context/ThemeContext.tsx)- Added "cloud" to Theme type union
- Updated meta theme color for cloud theme (#171717)
- Extended toggleTheme rotation to include cloud theme
- Sidebar Component (
src/components/Sidebar.tsx)- Imported Half2Icon from @radix-ui/react-icons for cloud theme
- Updated theme icon conditional to display half-moon for cloud theme
- Updated tooltip text to cycle through all four themes
- Syntax Highlighting (
src/components/FullPageNoteView.tsx,src/components/NotesSection.tsx)- Added cursorCloudTheme syntax highlighting color scheme
- Grayscale code highlighting matching cloud theme palette
- App Component (
src/App.tsx)- Extended Clerk appearance customization for cloud theme
- Color primary, background, and text values for cloud theme
- Global CSS (
src/styles/global.css)- Added
:root[data-theme="cloud"]CSS variable block - Cloud theme colors throughout app components
- Clerk modal overrides for cloud theme
- Interactive accent color overrides for checkboxes, buttons, and active states
- Mobile responsive styles for cloud theme
- Added
- Full-Page Notes - Dedicated note-taking workspace for each date
- Create unlimited full-page notes per date with Chrome-style tabbed interface
- FileText icon in header to access full-page notes view
- FilePlus icon to create new notes within full-page notes page
- Checkbox icon to return to todos from full-page notes
- Single-click to start typing with automatic edit mode
- Double-click tab titles to rename notes
- Line numbers that scale with font size
- Markdown rendering and syntax highlighting for code blocks
- Auto-save on content changes
- Copy button for note content
- X button closes tab without deleting note from database
- Notes folder in sidebar shows all note titles for each date
- Click sidebar note title to open that note
- Active state indicator for currently selected notes
- Three-dot menu for rename and delete actions
- Font size integration with Todo Text Font Size setting
- Mobile-optimized with responsive design
- ESC key closes note menus
- Real-time sync across devices
- Schema update (
convex/schema.ts)- Added
fullPageNotestable with fields: userId, date, title, content, order, collapsed, pinnedToTop - Indexed by
by_user_and_datefor efficient querying - Search indexes on
search_contentandsearch_titlefields
- Added
- New Convex file (
convex/fullPageNotes.ts)getFullPageNotesByDatequery: fetches all full-page notes for a dategetFullPageNotequery: fetches single note by IDgetFullPageNoteCountsquery: returns count of notes per date for sidebarcreateFullPageNotemutation: creates new note with auto-orderingupdateFullPageNotemutation: updates title or content (idempotent, no pre-read)deleteFullPageNotemutation: permanently removes notereorderFullPageNotesmutation: updates order with parallel updates
- New Components
FullPageNoteView.tsx: Note editing/display with line numbers and syntax highlightingFullPageNoteTabs.tsx: Chrome-style tab interface with scrolling support
- App component (
src/App.tsx)- Added full-page notes state management
- FileText icon navigation to full-page notes view
- Context-aware copy button (todos vs full-page notes)
- Checkbox icon to return to todos page
- Hidden footer on full-page note pages
- Font size application includes full-page notes and line numbers
- Mobile date format optimization (10/28/25)
- Sidebar component (
src/components/Sidebar.tsx)- Collapsible "Notes" folder under dates with full-page notes
- Note titles clickable to open that note
- Three-dot menu for rename and delete actions
- Active state with dark transparent overlay for selected notes
- ESC key support for closing note menus
- Haptic feedback when clicking note links
- Launch page (
src/pages/Launch.tsx)- Added full-page notes section with description
- Three screenshot images in gallery
- Updated navigation to include full-page notes link
- Global CSS (
src/styles/global.css)- Full-page note tabs with horizontal scrolling
- Tab styling: 120-200px width (desktop), 80-120px (mobile)
- Notes folder styling in sidebar
- Active note state with rgba(0, 0, 0, 0.2) overlay
- Three-dot menu always visible with opacity transitions
- Mobile-responsive padding and font sizes
- Line number scaling with font size
- PRDs folder
- Added
full-page-notes-feature.plan.mdwith comprehensive feature documentation
- Added
- Updated files
files.md: Added full-page notes components and backend functionsREADME.md: Updated with full-page notes featurechangelog.md: This entry
- Folders renamed to Projects - Updated terminology throughout the app
- "Folders" now called "Projects" in UI and documentation
- "+ Add Folder" button changed to "+ Add Project"
- "Manage Folders" section renamed to "Manage Projects"
- Menu options updated: "Add to Project...", "Remove from Project", "Rename Project", "Archive Project", "Delete Project"
- More intuitive naming for organizing dates by project context
- Backend table name remains "folders" for database compatibility
- Launch page route at
/launchand/about - Custom 404 Not Found page component
- Netlify build configuration optimized for SPA routing
- Public
_redirectsfile for Netlify deployment - Demo video (
demo-video-v1.mp4) on Launch page intro section - Pomodoro timer mute/unmute controls
- Volume button in modal (top right) and full-screen mode
- Mute all timer sounds (start, countdown, completion, pause)
- Stops all currently playing audio when muting
- State persists during timer session
- Works in both modal and full-screen modes
- Updated
netlify.tomlfor proper SPA fallback routing - All routes now properly fallback to React Router
- 404 page handled by React Router with custom NotFound component
- Pomodoro timer click behavior - Timer icon now opens modal instead of auto-starting
- Users must explicitly click "Start" button to begin Pomodoro session
- Prevents accidental timer starts when navigating from Launch page
- Fixed typo in git commit command documentation (TASKS.md)
- Netlify routing configuration for Launch page
- Build process now includes all necessary static assets
- Launch images properly copied to dist during build
- Delete date functionality now works for authenticated users
- Fixed
deleteDatemutation to use proper authentication viagetUserId(ctx) - Removed hardcoded "demo-user" that was preventing authenticated users from deleting dates
- Mutation now properly throws error for unauthenticated users
- Fixed
- Sidebar date deletion menu options cleaned up for better UX
- Removed "Delete Date" option from dates inside folders (only show "Remove from Folder" and "Archive Date")
- Removed "Delete Date" option from archived dates (only show "Unarchive Date")
- Removed "Delete Date" option from dates inside archived folders
- Dates only show in sidebar when they have uncompleted todos, so deletion is not needed in these contexts
- Pomodoro timer auto-start issue - Fixed timer auto-starting when navigating from Launch page
- Timer now requires explicit user action to start (clicking timer icon opens modal)
- No accidental timer starts when accessing home page from Launch page
- ArchiveSection TypeScript error - Fixed missing
onMoveToTodayprop in archived todos- Added empty function handler for onMoveToToday prop in ArchiveSection
- Resolves TypeScript build error for production deployment
- Dark Mode Accent Color - Updated from blue (#0076C6) to green (#27A561)
- All interactive elements now use green accent in dark mode
- Checked checkboxes: green background and border (#27A561)
- Active states: green background (#27A561)
- Focused elements: green border (#27A561)
- Menu hover states: green background (#27A561)
- Primary buttons: green background (#27A561)
- Font size option active: green background and border (#27A561)
- Search highlights: green background (#27A561)
- Date picker button: green background (#27A561)
- Confirm dialog buttons: green background (#27A561)
- Feature showcase buttons: green background (#27A561)
- Clerk sign-in/sign-up buttons: green background (#27A561)
- Add folder save button: green background (#27A561)
- Add folder input focus: green border (#27A561)
- Collapsed/expanded active dates: green background (#27A561)
- CSS variable
--mobile-add-button-bgupdated to #27a561 in dark mode - CSS variable
--mobile-add-button-hoverupdated to #229350 in dark mode - Light mode (#0076C6) and tan mode (#EB5601) remain unchanged
- Theme Color Reference in documentation
- Dark mode: Green (#27A561)
- Light mode: Blue (#0076C6)
- Tan mode: Orange (#EB5601)
- Added comprehensive documentation for future theme development
-
Tan Mode Theme - Third theme option with warm, document-focused design
- Warm tan background (#faf8f5) for ecosystem strain reduction
- Orange accent color (#EB5601) for interactive elements and primary actions
- Comprehensive color overrides for checkboxes, buttons, active states, and focus indicators
- Theme-aware styling for Clerk authentication modals
- Cloud icon (☁️) from Lucide React for theme toggle button
- Default theme set to "tan" for better first-time user experience
- Theme switching rotates: dark → light → tan → dark
-
Logged Out Demo Mode - Feature showcase and demo functionality for unauthenticated users
- Feature showcase box explaining app benefits and key features
- Try-before-you-buy: Create up to 3 todos without signing up
- Demo todos saved in local state (lost on page refresh)
- Seamless transition from demo to authenticated account
- Feature showcase includes Sign Up and Sign In buttons
- Clean, modern welcome screen for first-time visitors
- Demo mode banner explaining the 3-todo limit
-
iOS home screen app UI mismatch resolved for Progressive Web App (PWA) functionality
- Added inline script in
index.htmlto prevent theme flash when launching from home screen - Theme now applies immediately before React renders (eliminates white flash on dark mode)
- Meta theme-color tag now updates dynamically based on user's selected theme
- Added comprehensive CSS for standalone mode (display-mode: standalone)
- Proper safe area handling for iPhone notch and home indicator using env() CSS
- Fixed viewport height calculation for iOS standalone mode using -webkit-fill-available
- Prevented rubber band bounce scroll effect in standalone mode
- Theme loads consistently whether accessed via browser or home screen icon
- Background color matches theme immediately on app launch
- Added inline script in
-
Build configuration errors fixed for production deployment
- Removed unused imports from Sidebar component (SunIcon, MoonIcon)
- Removed unused onOpenSignIn prop from Sidebar and App components
- Build now completes successfully with no TypeScript errors
- Ready for Netlify deployment with proper dist folder generation
- Theme initialization improved for faster load times
- ThemeContext now applies theme synchronously before React mounts
- Theme color in manifest and meta tags updates dynamically
- localStorage theme preference loads instantly
- Three-way theme rotation instead of two-way (dark ↔ light)
- Pomodoro button order in modal and fullscreen mode
- Fullscreen/minimize button now appears first for quicker access
- Modal: Fullscreen, Play/Pause, Reset, Stop
- Fullscreen: Minimize, Image toggle, Play/Pause, Reset, Close
- Pomodoro background image loading delay in full-screen mode
- Background images now pre-fetch when timer starts instead of when entering full-screen
- Image icon button appears immediately in full-screen (no delay)
- Improves user experience by preparing background while timer runs
- Images ready when user wants to toggle background display
-
Progressive Web App (PWA) support
public/manifest.jsonwith complete PWA configuration- iOS splash screen image (1170x2532px) for iPhone Pro devices
- App is now installable on iOS via "Add to Home Screen"
- App is installable on Android with native app experience
- Standalone display mode for immersive full-screen app feel
- Customizable theme colors and app metadata
- Proper app icons for all device types
- Enables offline-first capabilities for future enhancements
-
Haptics library (
src/lib/haptics.ts)- New utility for haptic feedback on touch devices
- Provides tactile feedback for user interactions
- Supports iOS and Android devices with haptics capabilities
- Graceful fallback for devices without haptic support
- Lightweight implementation for minimal performance impact
- Ready to integrate into components for enhanced UX
- Todo text font size customization
- User-specific font size settings for todo text (authenticated users only)
- Font size options: 10px, 12px (default), 14px, 16px, 18px, 24px
- Settings accessible via Keyboard Shortcuts Modal (press
?) - Real-time preview showing how todo text will appear
- Font size persists across sessions and devices per user account
- Works in both light and dark themes
- Schema update (
convex/schema.ts)- Added
userPreferencestable withtodoFontSizefield - Indexed by
userIdfor fast lookups
- Added
- User preferences functions (
convex/users.ts)getUserPreferencesquery: fetches user's font size preferencesetTodoFontSizemutation: updates font size for authenticated user
- KeyboardShortcutsModal component (
src/components/KeyboardShortcutsModal.tsx)- Added font size customization section at bottom of modal
- Only visible to authenticated users
- Interactive buttons for each font size option
- Active state highlighting for current selection
- Real-time preview text showing selected font size
- App component (
src/App.tsx)- Fetches user preferences on authentication
- Dynamically injects CSS style tag for
.todo-textelements - Applies font size globally to all todo items
- Defaults to 12px for logged out users
- Global styles (
src/styles/global.css)- New styles for font size option buttons
- Active state styling with accent color
- Preview container with themed background
- Mobile-responsive button layout
- Unsplash background images in Pomodoro full-screen mode
- Optional beautiful nature images from Unsplash as full-screen backgrounds
- Random search queries: "landscape nature", "cities", "ocean", "sky"
- New image fetches each time full-screen mode opens for variety
- Toggle button with ImageIcon to show/hide background
- Apple-style glass morphism overlay when background is enabled
- Semi-transparent background with backdrop blur
- White glass effect in light mode, dark glass in dark mode
- Readable text with subtle shadows over images
- Glassmorphic control buttons with hover effects
- Responsive design with adjusted padding and border-radius for mobile
- Image toggle state resets to OFF on each full-screen open
- Secure API key management via Convex environment variables
- Images hotlinked from Unsplash CDN following API guidelines
- Schema update (
convex/schema.ts)- Added
backgroundImageUrloptional field topomodoroSessionstable
- Added
- New Convex file (
convex/unsplash.ts)fetchBackgroundImageaction: fetches random images from Unsplash API- Separated into its own file with
"use node"directive (actions only) - Secure access to
UNSPLASH_ACCESS_KEYenvironment variable
- Updated Convex functions (
convex/pomodoro.ts)updateBackgroundImagemutation: updates session with image URL- Removed
"use node"directive (mutations/queries run in V8, not Node.js)
- PomodoroTimer component (
src/components/PomodoroTimer.tsx)- Added
showBackgroundImagestate (defaults to false) - Added
hasFetchedImageref to prevent duplicate fetches - Imported
ImageIconfrom@radix-ui/react-icons - Added
useActionhook forfetchBackgroundImage - Image fetches when entering full-screen mode
- Toggle handler for showing/hiding background
- Conditional rendering of background image container
- Dynamic className for glass effect styling
- Image button only shows when image URL is available
- Added
- Global CSS (
src/styles/global.css).pomodoro-fullscreen-background: full-screen image container with cover fit.pomodoro-fullscreen-content.with-glass-effect: glass morphism overlay- Dark mode specific glass styling with adjusted transparency
- Text shadows on message and timer for readability over images
- Glassmorphic button styling with backdrop blur
- Responsive adjustments for tablets (768px) and mobile (480px)
- Smaller border-radius and adjusted padding on smaller screens
- TypeScript config (
tsconfig.json,convex/tsconfig.json)- Added
"node"to types in root tsconfig for Node.js type support - Added
"convex"to exclude list in root tsconfig - Added
"types": ["node"]to Convex tsconfig for action support
- Added
- To change background image categories, update the
queriesarray inconvex/unsplash.tsline 15 - Requires
UNSPLASH_ACCESS_KEYenvironment variable in Convex dashboard - Uses Unsplash
urls.regular(1080px) for optimal quality and performance - Node.js actions must be in separate files from V8 queries/mutations
Better Todo v1.0 is now feature-complete and ready for production use!
This release marks the completion of the core todo application with all essential features:
- Real-time synchronization with Convex
- Clerk authentication with private user data
- Notion-style inline input and editing
- Drag-and-drop reordering for todos and notes
- Daily organization with custom date labels
- Archive system with auto-archiving
- Full-text search across todos and notes
- Pomodoro timer with audio notifications and Unsplash backgrounds
- Custom folders and auto-grouped months
- Pinned todos for quick access
- Multiple notes per date with syntax highlighting
- Mobile-optimized responsive design
- Dark/light theme support
- Keyboard shortcuts and accessibility
- Production deployment on Netlify
The application is now stable, feature-rich, and ready for users to manage their daily tasks and notes effectively.
- Menu button alignment consistency - Fixed three-dot menu button alignment across all todo states
- Menu buttons now properly align to the right edge of todos in all states (default, hover, focused)
- Used pseudo-element approach to constrain focused background to 90% width while keeping menu button aligned
- Added
margin-left: autoto.todo-menuto ensure right-edge alignment - Prevents menu button from shifting left when todo item is focused or hovered
- Documentation added in
prds/menu-button-alignment-fix.mdexplaining the solution
- Menu button hover styling - Updated hover background colors to match app theme
- Light mode:
var(--bg-secondary)(matches menu dropdown items) - Dark mode:
var(--bg-secondary)(matches menu dropdown items) - Consistent visual feedback across all interactive elements
- Light mode:
- Cursor rule for preventing write conflicts in Convex with React
- Comprehensive guide located at
.cursor/rules/convex-write-conflicts.mdc - Backend patterns:
- Idempotent mutations with early returns
- Patch directly without reading first (most common fix)
- Minimal data reads with indexed queries
- Parallel updates with Promise.all
- Event records pattern for high-frequency counters
- Authorization patterns (user-scoped queries and internal mutations)
- Frontend patterns:
- Refs for tracking one-time calls
- Debouncing rapid inputs (300-500ms recommended)
- Mutation status checks before calling
- Avoiding loops and batching updates
- Schema design best practices to minimize conflicts
- Monitoring section for dashboard insights
- Complete checklists for both backend and frontend
- Priority actions summary with key takeaways
- References Convex documentation on optimistic concurrency control
- Applicable to this app and all future Convex projects
- Comprehensive guide located at
- Note creation focus behavior - Cursor now placed in content textarea instead of title input
- When using Shift+ keyboard shortcut or clicking "Add Note" button, cursor focuses content area
- Note automatically enters edit mode and expands if collapsed
- Title remains "Untitled" by default, allowing immediate content entry
- Improved workflow for quick note-taking
- Pomodoro timer write conflict issue resolved
- Added idempotency check in
completePomodoromutation to prevent duplicate updates - Mutation now exits early if session is already completed or doesn't exist
- Added
hasCalledCompleteref in component to track completion calls per session - Prevents multiple concurrent calls to
completePomodorothat were causing database write conflicts - Improved reliability when timer completes or during rapid state changes
- Added idempotency check in
- Pomodoro timer audio notifications with MP3 file-based sounds
- Start sound (
timer-start.mp3) plays once when timer begins at full 25 minutes - 5-second countdown sound (
5-second-coutdown.mp3) plays when 5 seconds remain - Completion sounds rotate through 11 different MP3 files:
- end-synth.mp3, end-epicboom.mp3, end-epci.mp3, end-deep.mp3, end-horns.mp3
- end-computer.mp3, end-flute.mp3, pause.mp3, end-whoa.mp3, end-waves.mp3, done.mp3
- Pause sound (
pause.mp3) plays when user clicks pause button in modal or full-screen mode - All sounds play at 70% volume for comfortable listening
- Replaced Web Audio API oscillators with simple MP3 file loading
- Sound state properly resets on timer stop/reset
- Each sound plays only once per trigger event
- Start sound (
- Audio system replaced - Switched from Web Audio API to MP3 files
- Removed
audioContextRefand oscillator-based sound generation - Added refs for tracking sound playback state (
hasPlayedStartSound,hasPlayedCountdownSound) - Cleaner, more maintainable audio implementation
- Better quality sounds with actual audio files
- Removed
- Cursor Dark Theme syntax highlighting for code blocks in notes
- Exact color matching with Cursor editor's Dark+ theme
- Custom CSS rules with
!importantto override default styles - Theme-aware colors for both dark and light modes
- Comprehensive token support (comments, keywords, strings, functions, variables, types, etc.)
- Enhanced placeholder text showing all supported languages
- Code Blocks section in Keyboard Shortcuts modal:
- Copyable language syntax buttons for CSS, JavaScript, TypeScript, HTML, JSON, Python, Go, Rust
- Alternative syntax options (e.g.,
js vsjavascript) - Click-to-copy functionality with visual feedback
- Mobile-responsive grid layout
- Accessible via ? key or keyboard shortcuts button
- Updated syntax highlighting implementation:
- Replaced oneDark/oneLight themes with custom Cursor Dark Theme colors
- Added comprehensive CSS token styling for accurate color reproduction
- Improved language detection and tokenization
- Enhanced user experience with better color contrast and readability
- Code syntax highlighting in notes with markdown-style code blocks
- Write code blocks using triple backticks with language identifiers (e.g., ````js`)
- Supports JavaScript, TypeScript, CSS, HTML, JSON, Python, Go, and Rust
- Display mode shows syntax-highlighted code with proper theme support
- Edit mode provides plain textarea for writing markdown-style code blocks
- Individual copy buttons for each code block
- Copy all button copies entire note content as plain text
- Click anywhere in display mode to enter edit mode
- Edit button in note header for quick access
- Line numbers in code blocks for easy reference
- Theme-aware syntax highlighting (oneDark for dark mode, oneLight for light mode)
- Clean code block headers showing language name
- Security-first approach with plain text storage and client-side rendering only
-
Improved subtask creation workflow
- New subtasks now start empty instead of pre-filled with "New subtask" text
- Empty subtasks automatically enter edit mode for immediate typing
- Keyboard shortcut "s" creates a subtask for the currently focused/selected todo
- Auto-focus on new empty subtasks for faster workflow
-
Keyboard shortcut to open todo menu
- Keyboard shortcut "m" opens the context menu for the currently focused/selected todo
- Provides quick access to all todo actions without using mouse
- Menu opens at the proper position for the selected todo
- Updated keyboard shortcuts help modal to include "s" and "m" shortcuts
-
Todo count badges in sidebar
- Shows count of uncompleted todos next to each date in sidebar
- Real-time sync - counts update automatically when todos are completed/uncompleted
- Displays in all sections: active dates, folders, and month groups
- Simple number display with theme-aware colors (no background box)
-
Pin icon for pinned todos
- Drawing pin filled icon from Radix UI appears before checkbox for pinned todos
- Only shows on date pages (not in pinned section)
- Uses theme-aware colors that adapt to light/dark mode
- Clean visual indicator without borders or background
-
Pinned todos sorted to top
- Pinned todos automatically appear at the top of each date page
- Maintains original order within pinned and unpinned groups
- Consistent sorting across App.tsx and TodoList.tsx
- Fixed keyboard shortcuts for all todos - Keyboard shortcuts now work correctly for all todos, not just pinned ones
- Fixed index mismatch between keyboard navigation and rendered todos
- Arrow key navigation properly highlights the correct todo
- Space/e and p key shortcuts work on any highlighted todo
- Removed borders from pinned todos for cleaner appearance
- Fixed archive section visibility - Archive section now shows when folders or month groups are archived, not just dates
- Fixed empty folders appearing in sidebar - Folders without dates now hide from active view until dates are added
- Fixed "Add to Folder..." menu option - Menu option now appears even for newly created empty folders, allowing you to add dates to them
- Fixed three-dot menu contrast in folders and archive - Menu dropdowns now have better contrast and visibility when appearing over folders or archived sections in both light and dark modes
- Changed dropdown background from secondary to primary background for better separation
- Increased shadow from 0.15 to 0.25 opacity for more depth
- Improved hover states with clearer backgrounds (#f0f0f0 in light mode)
- Added specific danger item hover styling with subtle red tint
- Applied same improvements to folder selector modals
- Fixed opacity inheritance issue - removed opacity from parent containers so dropdowns render at full opacity
- Date items now brighten on hover (0.7 to 0.9 opacity) for better interactivity
- Three-dot buttons in folders now have proper opacity (0.6 normal, 1.0 on hover)
- Fixed three-dot menu alignment for folders - Menu buttons for folder headers now perfectly centered vertically using CSS transform, matching date menu button alignment
- Updated folder hover highlight - Folders now use light blue hover color (rgba(86, 181, 219, 0.15)) instead of grey to match date hover styling
- Creates consistent visual language across all sidebar items
- Light mode uses slightly lighter blue (0.1 opacity) for better contrast
- Applied same light blue hover to regular date items for perfect consistency
- Fixed folder rename modal positioning - Rename folder input now appears above the folder section instead of below, preventing it from being clipped or appearing off-screen
- Fixed folder menu behavior - Three-dot menu now properly closes when clicking "Rename Folder" option, preventing menu from staying open during rename operation
- Fixed three-dot menu alignment for folders - Three-dot buttons now perfectly align with folder names by using full height alignment instead of transform-based centering
- Added Manage Folders section - New collapsible section below archived items shows all folders (including empty ones) for easy management
- Shows folder name with date count badge (if folder has dates)
- Provides access to rename, archive, and delete options for all folders
- Allows users to delete empty folders that don't appear in main sidebar
- Count badge shows number of non-archived folders
- Improved unarchive date behavior - When unarchiving a date that's inside a folder, the date is automatically removed from the folder and moved to active dates list
- Matches the existing "Remove from Folder" behavior
- Provides cleaner UX by eliminating extra step to remove from folder first
- Date appears in main active dates section after unarchiving
-
Keyboard shortcut "p" to pin/unpin todos
- Press "p" key while hovering over any todo to toggle pin state
- Works on active, uncompleted todos
- Added to keyboard shortcuts modal (?-key menu)
- No need to click three-dot menu for quick pinning
-
Smart todo selection for keyboard shortcuts
- When not typing in a note or todo input, keyboard shortcuts automatically work
- Hovering over a todo auto-selects it for keyboard shortcuts
- Arrow keys (↑/↓) navigate todos even without explicit focus
- Spacebar/e marks todo as done even without clicking
- "p" key pins/unpins hovered todo
- Seamless keyboard-first workflow
-
Auto-focus note content after naming
- After naming a note, pressing Enter or Tab automatically focuses the note content area
- Automatically expands collapsed notes when focusing
- Smooth workflow for creating and writing notes without clicking
- Keyboard shortcuts work more intelligently based on hover and typing state
- Todo hover tracking enables seamless keyboard navigation
- Added "Rename Folder" option to archived folders menu (was only available for active folders)
- Fixed three-dot menu positioning for folders and month groups - now properly displays on the right side of headers like the Archive section
- Fixed three-dot menu visibility on folders and month groups - now matches date items with proper colors in both dark and light modes
- Fixed "Add Folder" input positioning - now appears inline next to the "+ Add Folder" button instead of at the bottom of sidebar
- Fixed subtasks not appearing on pinned page -
getPinnedTodosquery now includes subtasks (children) of pinned todos, so you can now add and view subtasks for pinned todos on the pinned page - Fixed three-dot menu alignment - All three-dot menu buttons now have consistent width (30px min-width) and alignment across todo pages, sidebar dates, folders, and month groups
- Fixed subtask three-dot menu alignment - Subtask menu buttons now align perfectly with parent todo menu buttons using negative margin compensation for the indentation
-
Custom folders for organizing dates
- Create unlimited folders with custom names via "+ Add Folder" button
- Collapsible folders with arrow icon and folder icon
- Dates within folders are not grayed out (active state)
- Add dates to folders via three-dot menu on any date
- "Add to Folder..." shows list of available folders
- Click folder to add date to it
- "Remove from Folder" option when date is already in a folder
- Manage dates within folders via three-dot menu
- Remove dates from folders
- Archive dates
- Delete dates
- Works for both active and archived folders
- Rename folders via three-dot menu
- Archive folders to hide from main view
- Unarchive folders when needed
- Delete folders and all associations
- Three-dot menu for each folder (Rename, Archive, Delete)
- Folders appear between active dates and archived section
- Archived folders appear within the archived section
- Mint green hover state on "Add Folder" button
- Folder selector modal with clean, minimal design
-
Auto-group completed months into collapsible toggles
- Automatically groups dates from completed months (not current month)
- Named by month and year (e.g., "January 2025")
- Collapsible with arrow icon like folders
- Archive month groups to hide from view
- Unarchive month groups when needed
- Delete month groups and all date associations
- Three-dot menu for each month (Archive Month, Delete Month)
- Only displays after a full month has passed
- Month groups appear between active dates and folders
- Archived month groups appear within the archived section
-
Delete all archived dates functionality
- Three-dot menu on archived section header
- Permanently deletes all archived dates at once
- Confirmation dialog shows count of archived dates
- Clean, danger-styled confirmation
- Active dates now exclude dates in folders or month groups
- Archived section now includes archived folders and month groups
- ESC key now closes folder and month group menus and inputs
- Mobile UserProfile modal responsiveness - Fixed text cutoff and signout button visibility issues on mobile devices
- Updated
.clerk-modal-containerto use flexbox layout for better mobile handling - Added mobile-specific CSS for Clerk components to prevent text cutoff
- Fixed signout button positioning and visibility on mobile screens
- Improved touch targets and font sizes for better mobile usability
- Added proper scrolling behavior for UserProfile content on mobile
- Changed from full-screen to responsive modal layout on mobile (95vw width, max 500px)
- Added X close button in top-right corner for better UX
- Applied same responsive layout and close button to SignIn and SignUp modals
- Added mobile-specific CSS for SignIn/SignUp forms to prevent text cutoff
- Updated
-
Clerk authentication integration - Replaced WorkOS with Clerk for user authentication
- Added
@clerk/clerk-reactpackage for React integration - Created
convex/auth.config.tsfor Clerk authentication with Convex - Uses
ConvexProviderWithClerkfromconvex/react-clerkfor proper integration - Integrated ClerkProvider in
src/main.tsxwith Convex token sync viauseAuthhook - Uses
useConvexAuth()hook for reliable authentication state across app - Added SignIn and UserProfile modals with theme-aware appearance customization
- Theme-aware user profile icons (
user-light.svg,user-dark.svg) - Automatic JWT token synchronization between Clerk and Convex
- Added
-
Ephemeral mode for unsigned users - Work without account, data lost on refresh
- Created
src/lib/localData.tsin-memory storage for todos and notes - Unsigned users can create, edit, delete, and organize todos locally
- All CRUD operations work identically for signed and unsigned users
- Warning banner displays when not signed in
- Search feature gated behind sign-in requirement
- Created
-
Enhanced security and data isolation
- All Convex queries/mutations require authentication (return empty if not signed in)
- Replaced hardcoded demo user with
identity.subjectfrom Clerk JWT - Each signed-in user sees only their own data
- Mutations throw "Not authenticated" error when called without auth
-
UI improvements for authentication
- Clerk button styling: white text in light mode, black text in dark mode
- OTP code field styling with blue accent border
- Authentication popup for "+ add note" button when not signed in
- Custom confirmation dialogs for sign-in prompts
- Removed "Don't have an account?" links from Clerk modals (sidebar has dedicated buttons)
- Authentication flow completely redesigned
- Sidebar login button shows SignIn modal when signed out
- Sidebar login button becomes user profile button when signed in
- User can view/edit profile and sign out via UserProfile modal
- All modals match site UI theme (dark/light mode)
- Search functionality gated by authentication
- Search button shows "Sign In to Search" modal when not signed in
- Search only works for authenticated users with persisted data
- Keyboard shortcut (Cmd+K) respects authentication state
- WorkOS AuthKit removed - Replaced entirely with Clerk
- Removed
@workos-inc/authkit-reactand@convex-dev/workospackages - Removed Netlify Functions for WorkOS OAuth (
auth-callback.ts,auth-me.ts,auth-logout.ts) - Removed WorkOS-specific environment variables and configuration
- Removed
netlify.tomlandnetlify/folder (no longer needed)
- Removed
- Users will need to sign up again with Clerk (WorkOS sessions are incompatible)
- Environment variables changed from
VITE_WORKOS_*toVITE_CLERK_* - Required environment variables:
VITE_CLERK_PUBLISHABLE_KEY(frontend)CLERK_SECRET_KEY(Convex backend)VITE_CLERK_FRONTEND_API_URL(Convex auth config)
- Production authentication with Netlify Functions - Resolved WorkOS session authentication failure
- WorkOS OAuth succeeded but frontend couldn't access session cookies (SPA limitation)
- Implemented Netlify Functions for server-side OAuth callback handling
- Created
/api/auth/callbackendpoint to exchange OAuth code for tokens and set HTTP-only cookies - Created
/api/auth/meendpoint to retrieve current user from session cookies - Created
/api/auth/logoutendpoint to clear authentication cookies - Added
netlify.tomlconfiguration for function routing - Installed
@workos-inc/nodepackage for server-side WorkOS SDK - Updated WorkOS redirect URI from
/callbackto/api/auth/callback - Fixed production Convex deployment URL configuration (was using dev URL)
- Set
WORKOS_CLIENT_IDon production Convex deployment to match frontend - Deployed Convex auth config to production with
npx convex deploy -y
- Netlify Functions for WorkOS authentication - Server-side OAuth handling
netlify/functions/auth-callback.ts- Handles OAuth callback and sets session cookiesnetlify/functions/auth-me.ts- Returns current user from sessionnetlify/functions/auth-logout.ts- Clears authentication cookiesnetlify.toml- Routes/api/auth/*to Netlify Functions- Debug logging for environment variables and auth state in browser console
- Environment variables configuration updated for production deployment
- Added
WORKOS_API_KEY(server-side, required for OAuth token exchange) - Changed
VITE_WORKOS_REDIRECT_URIto point to/api/auth/callbackendpoint - Ensured
VITE_CONVEX_URLuses production deployment URL, not development - Production Convex deployment now has correct
WORKOS_CLIENT_IDenvironment variable
- Added
- Production deployment issues - Resolved Netlify build failures
- Fixed TypeScript error in NotesSection.tsx onClick handler for WorkOS signIn function
- Added @types/node package to devDependencies for process.env support in Convex backend
- Updated WorkOS AuthKit integration guide with comprehensive Netlify deployment steps
- Documented environment variable configuration for production deployment
- Added troubleshooting section for common deployment issues
- Production deployment documentation - Complete Netlify setup guide
- Step-by-step environment variable configuration
- WorkOS dashboard settings for production domains
- Build command optimization with Convex deployment integration
- Common deployment issues and solutions
- Security best practices for environment variables
- WorkOS AuthKit Integration - Complete authentication system
- User login/logout with WorkOS AuthKit
- Private user data (each user sees only their own todos and notes)
- Theme-aware login/user icons (user-dark.svg/user-light.svg, login-dark.svg/login-light.svg)
- "Sign In Required" modal for unauthenticated users attempting to create todos/notes
- Automatic user data storage in Convex database upon first login
- Proper JWT token validation with correct aud/iss claims
- Redirect handling from /callback to / after successful login
- Conditional query execution based on authentication state
- Error handling for authentication failures
- Authentication flow - App now requires login to create todos and notes
- User data isolation - Each user has completely private data
- Login UI - Theme-aware icons for login/logout buttons
- Query optimization - Queries skip execution when unauthenticated
- JWT token validation - Corrected WorkOS JWT configuration with proper aud/iss claims
- Authentication state management - Proper handling of login/logout states
- User data persistence - Automatic storage of WorkOS user data in Convex
- Pinned todos for quick access to important tasks
- Pin any active todo from the three-dot menu (excludes completed todos)
- Pinned section appears at top of sidebar before dates
- Only shows when at least one todo is pinned
- Click "Pinned" in sidebar to view all pinned todos on dedicated page
- Pinned todos display with blue border (#0076C6) on original page
- Border only shows on original date page, not on pinned view
- Unpin option available in three-dot menu
- Works like a normal today page with full functionality
- Collapsed sidebar shows Pin icon for pinned section
- Supports drag-and-drop reordering within pinned view
- Three-dot menu click handling for all todos
- Menu items now properly execute before menu closes
- Added dropdown refs to prevent premature menu closure on click
- Fixes pin/unpin and move to date functionality
- Fixes unarchive functionality in done section
- Applied fix to both regular and archived todo menus
- Pinned section styling improved for consistency
- Replaced emoji with Lucide Pin icon in collapsed sidebar
- Pin icon works in both light and dark modes
- Padding and sizing now matches other dates in both desktop and mobile views
- Proper touch targets (44px minimum) on mobile for better tap experience
- Dedicated CSS class (
.pinned-section) with unique styling - Visual separator with bottom border and spacing to distinguish from dates
- Medium font weight (500) to make pinned section stand out
- Pinned view simplified for focused task management
- Hides bulk actions (Archive All, Delete All) on pinned view
- Hides add todo input on pinned view (pin existing todos from other dates)
- Hides notes section on pinned view (notes are date-specific)
- Individual todo actions (delete, unpin, move to date) still work normally
-
Unarchive option for unchecked archived todos
- New "Unarchive" option appears in three-dot menu for archived todos that are not completed
- Quickly move accidentally archived todos back to active list
- Only shows when todo is in archive section and checkbox is unchecked
- Seamlessly restores todo to main list without moving dates
-
Tooltip portal rendering for proper display
- Tooltips now render using React Portal at document body level
- Prevents clipping by sidebar or parent container overflow properties
- Tooltips positioned to the right with 8px offset from trigger elements
- Full text always visible (no more cut-off tooltip text)
- Applied to all sidebar footer icons (login, theme toggle, GitHub, Convex)
- Uses Radix UI TooltipPortal component for reliable positioning
-
Auto-delete on clear text
- Todos are automatically deleted when text is edited and cleared
- Works when editing a todo and removing all text content
- No confirmation dialog needed for intentional text clearing
- Helps keep todo list clean and removes accidental empty items
-
Collapsible sidebar with compact date view
- New collapse button next to "better todo" in sidebar header
- Click to toggle between full and collapsed sidebar views
- Collapsed view shows dates in compact MM/DD format (e.g., 10/22)
- Sidebar width adjusts from 260px to 60px when collapsed
- Active date remains highlighted with blue background
- Hover tooltips show full date labels in collapsed view
- Smooth transition animation between states
- Main content area automatically adjusts width
- Independent from mobile sidebar hide/show functionality
- Icons for theme toggle and GitHub remain visible when collapsed
- Uses PanelLeft icon for collapse button (same as previous sidebar toggle)
- Sidebar toggle removed from todos page header for cleaner layout
-
Todo three-dot menu clipping in archive section
- Menus now render using React Portal at document body level
- Prevents clipping by archive container overflow
- Menu positioned dynamically based on button location
- Proper z-index ensures menu appears above all content
- Click outside menu to close (in addition to ESC key)
-
Light mode date menu contrast improved for better readability
- Three dots button (⋯) now darker in light mode (#3d3d3d)
- Menu items text now darker in light mode (#1d1d1f)
- Delete action text adjusted for better visibility in light mode (#d5495d)
- All menu elements maintain excellent contrast in light mode
-
Mobile add button for iPhone and mobile devices
- Visible "+" button appears when typing on mobile devices
- Detects iPhone, iPad, Android, and screens ≤768px
- Button only shows when there's text to add
- Touch-optimized size (36x36px minimum)
- Mint green color (#80cbae) matching app design
- Desktop users can still use Shift+Enter shortcut
- Simplified placeholder text on mobile (no Shift+Enter mention)
- Button positioned to the right of the input field
-
Custom Date Labels allowing you to rename dates with any text
- Add custom labels like "Project Planning", "Meeting Notes", etc.
- Click the menu button (⋯) next to any date
- Select "Add Label" to give a date a custom name
- Labels replace the default date format in the sidebar
- Date flow remains chronological based on actual dates
- "Edit Label" option appears for dates that already have labels
- "Remove Label" option to restore default date display
- Text input with Enter to save, Escape to cancel
- Labels are preserved when archiving/unarchiving dates
- Labels are automatically cleaned up when dates are deleted
-
Line numbers in notes for easier reference and navigation
- Each line in a note displays a line number on the left
- Line numbers use monospace font for clean alignment
- Line numbers are not copyable (user-select: none)
- Numbers update automatically as you type
- Styled to match code editor aesthetic
-
Bulk actions for todos allowing you to archive or delete all todos on a date
- "Archive All" button to archive all active todos at once
- "Delete All" button to permanently delete all active todos
- Both actions require confirmation with custom dialogs matching app style
- Buttons only appear when there are active todos
- Clean, borderless button design matching the app aesthetic
- Archive All uses default styling, Delete All uses danger color (#e16d76)
- Confirmation messages show the count of todos being affected
-
Delete button for archived todos with X icon
- Hover over archived todos to reveal X delete button on the right
- Button appears only on hover to keep UI clean
- Click X to delete with confirmation dialog
- Uses app's standard ConfirmDialog component
- Danger red color (#e16d76) on hover
- Smooth fade-in transition for better UX
-
Delete All button for archived todos
- "Delete All" button in the archive header next to the count
- Permanently deletes all archived todos at once
- Requires confirmation dialog showing count of archived todos
- Clean, borderless design matching app style
- Danger red color (#e16d76) on hover
- Only appears when archive section has items
- Theme switcher repositioned to bottom of sidebar
- Moved from top right (next to "better todo" title) to sidebar footer
- Now positioned above the login link for easier access
- More intuitive placement at the bottom of the navigation
- Label save button color updated to #80cbae (mint green) instead of blue accent
- Delete button and link colors updated to #e16d76 (softer red) instead of bright red
- Menu item danger links now use #e16d76
- Confirmation dialog dangerous buttons now use #e16d76
- Hover state uses slightly darker #c95c64
- Confirmation dialog default buttons updated to #80cbae (mint green)
- Archive All and other non-dangerous confirmations now use mint green
- Dangerous actions still use red (#e16d76)
- Creates visual distinction between safe and destructive actions
- Bulk action buttons repositioned to bottom of page (footer style)
- Moved Archive All and Delete All buttons below the archive section
- Clean footer positioning with top margin and padding
- No border lines for cleaner appearance
- Updated button labels to "Archive All (active todos)" and "Delete All (active todos)" for clarity
- Archive section auto-collapses when adding new todos
- Adding a todo via input collapses the archive section
- Pasting multiple todos also collapses the archive section
- Keeps focus on active todos when creating new items
- TodoList syntax error resolved incomplete React component wrapper
- Missing todoInputRef causing blank screen error - added useRef for textarea element
- Simplified handleAddNote removed unnecessary dynamic import
- Archived date menu overlap fixed by positioning dropdown menus above the button for archived dates instead of below, preventing overlap with other dates
- Delete confirmation keyboard shortcuts
- Press Enter to confirm delete
- Press Escape to cancel
- Works on all delete confirmation dialogs (todos, notes, dates)
- Add Note button styling matches Archive toggle
- Reduced size with smaller padding (8px 0) and font size (13px)
- Left-aligned instead of centered
- Simpler hover effect (opacity change)
- Smaller icon (14px) to match compact design
- Notes themselves remain full-size and unchanged
- Cleaner UI with removed divider lines
- Removed border above Archive section in sidebar
- Removed border below date header in main content
- Removed border at bottom of notes section
- Creates more seamless, modern appearance
- Notes typing sync issue resolved by implementing local state with debouncing
- Notes now use local state and debounce database updates (500ms after user stops typing)
- Updates save immediately when user clicks away (blur)
- Eliminates lag and cursor jumping while typing in notes
- Smooth typing experience with proper autosave
- Full-text search across todos and notes using Convex text search
- Search icon in top right of header
- Keyboard shortcut: Cmd+K (Mac) or Ctrl+K (Windows/Linux)
- Real-time search with instant results
- Search across todo content and note titles/content
- Keyboard navigation with arrow keys
- Press Enter to navigate to selected result
- Search term highlighting in results
- Shows result type (Todo/Note), date, and status badges
- Beautiful modal UI matching the app theme
- Top 30 most relevant results displayed
- Automatically navigates to the date of selected result
- Works in both light and dark themes
- Header layout now has left section for toggle/date and right section for search button
- Added search indexes to database schema for efficient full-text search
- Todos: indexed on content field
- Notes: indexed on both title and content fields
- Custom confirmation dialog replaces browser default popups
- Matches site design system with consistent colors, borders, and shadows
- Styled delete confirmation with red dangerous button
- Professional modal with backdrop overlay centered on entire page
- Follows existing UI patterns and design language
- Added confirmation for deleting todos
- Added confirmation for deleting notes
- Added confirmation for deleting dates in sidebar
- Browser default confirm dialog replaced with custom styled modal
- Confirmation dialog now centered on viewport using React Portal
- Dialog renders at document.body level, ensuring proper centering regardless of parent container
- Higher z-index ensures dialog appears above all other content
- Fixed sidebar delete confirmation appearing within sidebar instead of centered on page
- Multiple notes system with drag-and-drop reordering
- Add unlimited notes per date with plus button
- Each note has its own title and collapsible state
- Edit/Preview tabs for markdown rendering
- Copy button per note
- Delete button per note
- Archive dates feature in sidebar
- Archive dates using three-dot menu
- Collapsible archived section in sidebar
- Unarchive dates when needed
- Scrollable sidebar dates with custom scrollbar styling
- Favicon - checkmark emoji favicon
- Twitter Card meta tags with large summary format
- Open Graph meta tags for social sharing
- Notes moved to top of page (above todos)
- Notes now support multiple items instead of single note per date
- Sidebar dates scroll when list is full
- Updated schema to support new notes and archived dates tables
- Notes positioning and organization
- Sidebar overflow handling
- Removed markdown rendering from todos - todos now display as plain text for simplicity
- Markdown support remains available in the notes section
- Cleaner, faster rendering for todo items
- Reduced header font sizes for more compact layout
- App name: 16px → 14px
- Current date: 18px → 14px
- Creates more space for content
- Mobile optimizations for native iPhone app feel:
- Sidebar width increased to 280px on mobile
- Touch-friendly tap targets (44x44px minimum)
- Smooth cubic-bezier transitions (0.3s)
- Sticky header with border on mobile
- iOS-style momentum scrolling (
-webkit-overflow-scrolling: touch) - Disabled text selection on interactive elements
- Larger checkboxes (20x20px) for easier tapping
- Proper viewport height handling (100vh)
- Improved overlay with no tap highlight
- Todo checkbox hover now shows golden border (#e6cd6a) before checking
- Mobile sidebar properly works as hamburger menu
- All UI elements now meet iOS touch target guidelines (44px)
- Notes section now supports markdown code blocks with syntax highlighting
- Edit/Preview tabs for notes section with live markdown preview
- Copy button to copy all notes content to clipboard
- Mobile overlay that closes sidebar when clicked
- Reversed keyboard shortcuts: Enter for new lines, Shift+Enter to create/save
- Applies to both creating new todos and editing existing todos
- More intuitive for multi-line content
- Sidebar now auto-collapses on mobile by default
- Notes section positioned right above archive section
- Mobile sidebar now properly auto-hides and shows overlay when open
- Fixed keyboard navigation in todos and notes for better UX
- Removed toggle functionality from h1, h2, h3 markdown headers in todos
- All todo items now display with checkbox only (full markdown support maintained)
- Notes textarea now auto-expands as you type (up to 600px max height)
- Notes font size matches todo font size for consistency
- Removed focus ring from notes textarea in both light and dark modes
- Fixed markdown header rendering - headers no longer try to create collapsible sections
- Improved notes section UX with seamless auto-expansion
- Notes section with toggle (closed by default) above archive
- Separate notes database table for free-form daily notes
- Login link at bottom of sidebar (auth not yet implemented)
- Browser/OS spell check enabled for todos and notes
- Grammarly explicitly disabled for better native experience
- Lucide React icon library for cleaner iconography
- Changed active date color to #0076C6 in both light and dark modes
- Reduced sidebar date padding from 8px to 6px for more compact layout
- Removed border line between sidebar header and dates section
- Fixed sidebar collapse behavior on mobile resize
- Code blocks now always display on separate lines with proper margins
- Replaced custom sidebar toggle icon with Lucide's PanelLeft icon
- Notes auto-save on blur for seamless experience
- Mobile sidebar now properly collapses with transform animation
- Improved mobile responsiveness with fixed positioning
- Multi-line note support with Shift+Enter for line breaks
- Auto-expanding textarea that grows with content (up to 200px max height)
- Line breaks are now preserved in todo content and displayed properly
- Updated placeholder text to mention Shift+Enter for line breaks
- Markdown preview now uses
white-space: pre-wrapto preserve line breaks - Header detection now only checks the first line (allows multi-line headers)
- Date menu with three-dot button next to each date in sidebar
- Copy all non-archived tasks from one date to another
- Copy to Tomorrow, Previous Day, Next Day, or Custom Date options
- Markdown list paste support (creates multiple todos from pasted lists)
- Auto-unarchive functionality when unchecking completed items
- Proper spacing between checkbox and todo content
- Sidebar resizer line is now black, thinner (1px), and more subtle with opacity
- Mobile view now properly supports hamburger menu with slide animation
- Keyboard shortcuts updated: Enter creates todo, Shift+Enter adds new line
- Date menu buttons only visible on hover for cleaner UI
- Improved markdown support with better bullet point formatting
- Fixed mobile sidebar collapse/expand functionality
- Fixed checkbox alignment and spacing
- Fixed sidebar transition animations
- 4 CSS custom properties for font sizes:
--font-app-name,--font-sidebar,--font-todo,--font-archive - Hover-only drag handles and menu buttons for cleaner UI
- Smooth transitions for all interactive elements
- "Move to Tomorrow" option in todo three-dot menu
- Removed boxes around todos in both light and dark mode
- Todos now have minimal spacing (closer together) while remaining draggable
- Made all fonts smaller throughout the app
- Moved archive section to bottom of page
- Removed border lines between dates in sidebar
- Drag handles and menu buttons now only visible on hover
- Improved checkbox styling with better alignment
- Archive section now uses border-top separator instead of box
- Reduced padding and spacing throughout for more compact design
- Reordered menu items: "Move to Tomorrow" appears first
- Resizable sidebar with drag-to-resize functionality (200-500px width range)
- Sidebar toggle button with clean icon design
- Notion-style inline todo input (just start typing to add todos)
- Press Enter to create todo, Shift+Enter for new line
- Half-moon SVG icon for theme switcher (removed emoji)
- Removed "Add Todo" button in favor of inline typing
- All text now uses normal font weight (400) instead of bold (600/700)
- Archive title remains visible at top but not bold
- Removed loading screen flash by using smarter Convex data handling
- Improved date navigation to prevent flashing between dates
- Sidebar toggle now uses SVG icon instead of emoji
- Fixed flashing when switching between dates with Convex
- Improved real-time data loading for smoother transitions
- Initial release of Better Todo app
- Real-time todo synchronization using Convex
- WorkOS AuthKit integration for authentication
- Dark mode (Sublime Text style) with background color #2E3842
- Light mode (Apple Notes style)
- Markdown support with syntax highlighting for code blocks
- Collapsible header sections (h1, h2, h3)
- Drag and drop todo reordering using @dnd-kit
- Daily organization with date-based sidebar navigation
- Archive section that auto-archives completed todos
- Three-dot menu for moving todos between days
- Mobile-friendly responsive design
- Theme toggle with localStorage persistence
- Bold and italic text formatting support
- System font stack for native look and feel
- Convex schema with todos table
- Indexes for efficient querying by user and date
- Queries for fetching todos by date and available dates
- Mutations for creating, updating, deleting, and reordering todos
- Mutation for moving todos between dates
- Auto-archiving on todo completion
- Sidebar with date navigation
- TodoItem with markdown preview and inline editing
- TodoList with drag-and-drop support
- ArchiveSection for completed tasks
- Theme switcher in sidebar header
- Responsive mobile menu toggle
- TypeScript for type safety
- React 18 with hooks
- Vite for fast development
- Convex for real-time backend
- WorkOS AuthKit with auto-provisioning
- date-fns for date manipulation
- react-markdown for markdown rendering
- react-syntax-highlighter for code blocks
- @dnd-kit for drag and drop functionality