feat: Enhance dashboard with stats cards and task filtering

- Added stats cards to display active, completed, overdue, and due-today tasks on the dashboard.
- Implemented search functionality to filter tasks in real-time based on user input.
- Introduced quick-pick date buttons for easier task date selection.
- Updated task rendering logic to handle empty states for task lists.
- Improved overall user interface with new CSS styles for stat cards and buttons.

chore: Update environment variables and backend error handling

- Fixed formatting in the .env file for consistency.
- Enhanced error handling in the backend API for better debugging.

feat: Revamp frontend pages with new features and pricing sections

- Redesigned the index.html page to include a hero section and feature highlights.
- Created a new features page with dynamic loading of features from JSON.
- Implemented a pricing page that loads plans from JSON and highlights the featured plan.
- Added support and FAQ sections with dynamic content loading and contact form functionality.
- Introduced JSON files for FAQs, features, and pricing to allow easy updates without code changes.
This commit is contained in:
Tim Basten
2026-04-23 16:29:52 +08:00
parent e50a6c91e6
commit 63070fd90c
15 changed files with 743 additions and 71 deletions

View File

@@ -51,31 +51,72 @@
<div class="rounded shadow bg-translucent p-3 p-lg-5 col-12">
<form id="taskForm" class="mb-5 text-white">
<h1 id="greeting" class="mb-5 display-3">Your Dashboard</h1>
<!-- Stats cards: populated by updateStats() in api.js. -->
<div class="row g-3 mb-5">
<div class="col-6 col-md-3">
<div class="stat-card">
<div id="statActive" class="stat-value">0</div>
<div class="stat-label">Active</div>
</div>
</div>
<div class="col-6 col-md-3">
<div class="stat-card">
<div id="statCompleted" class="stat-value">0</div>
<div class="stat-label">Completed</div>
</div>
</div>
<div class="col-6 col-md-3">
<div class="stat-card">
<div id="statOverdue" class="stat-value">0</div>
<div class="stat-label">Overdue</div>
</div>
</div>
<div class="col-6 col-md-3">
<div class="stat-card">
<div id="statDueToday" class="stat-value">0</div>
<div class="stat-label">Due Today</div>
</div>
</div>
</div>
<h2 class="mb-3">New Task</h2>
<input id="taskName" name="taskName" placeholder="Task Name" class="mb-2 form-control shadow-sm" type="text"
required />
<textarea id="taskDescription" name="taskDescription" placeholder="Task Description"
class="mb-2 form-control shadow-sm" rows="8" required></textarea>
<input id="dueDate" name="dueDate" type="date" class="mb-3 form-control shadow-sm" required
<input id="dueDate" name="dueDate" type="date" class="mb-2 form-control shadow-sm" required
placeholder="Due Date" />
<!-- Quick-pick date buttons: handler in api.js writes the
chosen date into the #dueDate field above. -->
<div class="d-flex gap-2 flex-wrap mb-3">
<button type="button" class="btn btn-outline-light quick-date-btn" data-quick="today">Today</button>
<button type="button" class="btn btn-outline-light quick-date-btn" data-quick="tomorrow">Tomorrow</button>
<button type="button" class="btn btn-outline-light quick-date-btn" data-quick="nextWeek">Next week</button>
</div>
<button type="submit" class="btn btn-primary shadow-sm px-5">
Create Task
</button>
<div class="d-flex align-items-center gap-3 my-5">
<label for="sortSelect" class="text-white">Sort by:</label>
<div class="d-flex align-items-center gap-3 flex-wrap mt-5 mb-3">
<label for="sortSelect" class="text-white mb-0">Sort by:</label>
<select name="sortSelect" id="sortSelect" class="form-select w-auto shadow-none">
<option value="default" selected>Default</option>
<option value="dueDate">Due Date</option>
<option value="dateCreate">Date Created</option>
</select>
<!-- Search: filters the lists below live via api.js (no API call). -->
<input id="searchInput" type="search" placeholder="Search tasks..."
class="form-control shadow-sm flex-grow-1" style="max-width: 320px;" />
</div>
<div class="row text-white">
<div class="col-12 col-lg-6 mb-4 mb-lg-0">
<h2>To Do</h2>
<p id="toDoEmpty" class="text-white-50 d-none">No matching tasks.</p>
<ul id="toDoList" class="list-group"></ul>
</div>
<div class="col-12 col-lg-6">
<h2>Completed</h2>
<p id="completedEmpty" class="text-white-50 d-none">No matching tasks.</p>
<ul id="completedList" class="list-group"></ul>
</div>
</div>