- Name: Morgan
- Role: Knowledge worker / student
- Environment: Distracted, task-heavy days
- Pain: Too many tasks lead to paralysis
- Motivation: End the day feeling accomplished
OneThing is a minimalist daily focus app that forces users to commit to one meaningful task per day. By removing choice overload, it helps users regain clarity and build consistency. The app uses local storage for persistence, with no server-side components.
“OneThing helps you commit to the single task that matters most today.”
Each day, the user:
- Chooses one task via input.
- Sees it displayed prominently all day.
- Marks it complete or incomplete at day's end.
No multiple tasks, lists, or extras. Task resets automatically at midnight.
- As a user, I want to set one task so I don’t feel overwhelmed.
- As a distracted person, I want a visible reminder of my focus.
- As a reflective user, I want to mark my day as a win or not.
- As a consistency-driven person, I want progress saved automatically.
- User can enter a single task description in a text input (up to 100 characters).
- Only one active task allowed per day; attempting a second prompts to clear first.
- Task persists across page refreshes using localStorage.
- Task is tied to the current date (UTC for simplicity).
- At the end of the day, task can be marked: Completed (green check), Not completed (red X).
- Task is displayed prominently (large text, centered).
- Completion state is visually obvious (e.g., icons or color changes).
- User cannot add a second task without clearing the first (clear button appears).
- New day resets task automatically (checks date on load).
- No task lists, priorities, or subtasks.
- No user accounts or cloud sync.
- No notifications or reminders.
- No streaks or gamification in MVP.
- No editing of past days.
- App loads instantly into “today’s focus” view.
- No navigation needed (single-page app).
- Minimal text on screen (e.g., just task input/display and buttons).
- Clear emotional feedback: Success (e.g., confetti animation), Miss (e.g., subtle gray-out).
- Responsive on desktop/mobile; calm color scheme (e.g., blues/grays).
- HTML: Single input field, one primary display area (h1 for task), one or two action buttons (set/clear, complete/incomplete).
- CSS: Calm, focused visual style with large typography (4em for task). Clear success/failure states via classes (e.g., .completed { color: green; }).
- JavaScript: Modular, adhering to SOLID principles.
- DateService: Determines current day and handles reset logic.
- TaskStateManager: Manages task text + completion state.
- StorageService: Abstracts localStorage get/set (keyed by date, e.g., 'task-YYYY-MM-DD').
- UIRenderer: Handles all DOM updates only (no business logic).
- Each module has a single responsibility; use ES6 modules.
- Does one-task restriction resonate or frustrate? (User interviews post-MVP.)
- Is daily reset helpful or stressful? (Track abandonment rates.)
- Would users want streaks—or does that add pressure? (Feature flag for optional streaks in v2.)
The implementation is broken into Epics (high-level themes), Features (user-facing capabilities), and Subtasks (actionable steps). This structure ensures modularity, allowing a human or LLM to implement incrementally while keeping the stack (HTML/CSS/JS) unchanged for future refinements (e.g., adding frameworks).
This epic covers setting and viewing the daily task.
-
Feature 1.1: Task Entry
- Subtask 1.1.1: Create HTML input field (id="task-input", placeholder="What’s your one thing today?").
- Subtask 1.1.2: Add "Set Task" button; on click, call TaskStateManager.setTask(input.value).
- Subtask 1.1.3: Validation: Prevent empty tasks; show error if input is blank.
-
Feature 1.2: Prominent Display
- Subtask 1.2.1: Create HTML element for display (id="task-display", h1 tag).
- Subtask 1.2.2: In UIRenderer, define renderTask(text, state) to update display with text and apply state classes.
- Subtask 1.2.3: On load, check StorageService for today's task and render if exists.
This epic handles daily resets and completion marking.
-
Feature 2.1: Daily Reset
- Subtask 2.1.1: In DateService, define getCurrentDate() using new Date().toISOString().slice(0,10).
- Subtask 2.1.2: On app init, compare stored date with current; if different, clear task via TaskStateManager.reset().
- Subtask 2.1.3: Handle edge cases: Midnight refresh simulates new day.
-
Feature 2.2: Completion Marking
- Subtask 2.2.1: Add HTML buttons: "Completed" and "Not Completed" (visible only if task set).
- Subtask 2.2.2: On click, update TaskStateManager.setCompletion(true/false) and save to StorageService.
- Subtask 2.2.3: Provide UX feedback: Simple CSS animation (e.g., scale up on complete).
-
Feature 2.3: Single Task Enforcement
- Subtask 2.3.1: If task exists, hide input and show "Clear Task" button.
- Subtask 2.3.2: On clear, reset state and show input again.
This epic ensures minimalism and usability.
-
Feature 3.1: Calm Visual Style
- Subtask 3.1.1: Use CSS for large typography and centered layout (flexbox).
- Subtask 3.1.2: Define state classes: .completed { border: green; }, .incomplete { opacity: 0.5; }.
-
Feature 3.2: Instant Load and Feedback
- Subtask 3.2.1: Ensure app init in main.js calls UIRenderer on DOMContentLoaded.
- Subtask 3.2.2: Test mobile responsiveness (media queries for font scaling).
This epic enforces SOLID principles across the app.
- Feature 4.1: Module Separation
- Subtask 4.1.1: Create separate JS files: dateService.js, taskStateManager.js, storageService.js, uiRenderer.js.
- Subtask 4.1.2: Use import/export; main.js initializes and subscribes to events if needed.
- Subtask 4.1.3: Isolate logic: StorageService only handles persistence; no UI in TaskStateManager.