Updated the task view and backend to handle more like a routine
This commit is contained in:
@@ -75,6 +75,8 @@
|
||||
}
|
||||
|
||||
let isFetching = false;
|
||||
let lastKnownFirmware = null;
|
||||
let lastKnownSlot = null;
|
||||
async function fetchAll(silent = false) {
|
||||
if (isFetching) return;
|
||||
isFetching = true;
|
||||
@@ -85,6 +87,16 @@
|
||||
getOTAStatus(),
|
||||
getUpcomingTasks().catch(() => ({ users: [] }))
|
||||
]);
|
||||
// Detect any OTA update: firmware version change OR www partition flip
|
||||
const fwChanged = lastKnownFirmware && sys.firmware !== lastKnownFirmware;
|
||||
const slotChanged = lastKnownSlot !== null && ota.active_slot !== lastKnownSlot;
|
||||
if (fwChanged || slotChanged) {
|
||||
console.log(`OTA detected (fw: ${fwChanged}, slot: ${slotChanged}). Reloading...`);
|
||||
window.location.href = window.location.pathname + '?t=' + Date.now();
|
||||
return;
|
||||
}
|
||||
lastKnownFirmware = sys.firmware;
|
||||
lastKnownSlot = ota.active_slot;
|
||||
systemInfo = sys;
|
||||
otaStatus = ota;
|
||||
upcomingData = upcoming;
|
||||
@@ -180,7 +192,7 @@
|
||||
<div class="w-full max-w-6xl mx-auto space-y-8">
|
||||
<!-- Header -->
|
||||
<div class="text-center">
|
||||
<h1 class="text-2xl font-bold text-accent">Calendink Provider 📅📅🚀🚀⚡✨🌈</h1>
|
||||
<h1 class="text-2xl font-bold text-accent">Calendink Provider 📅⚡✨🌈</h1>
|
||||
<p class="text-text-secondary text-sm">ESP32-S3 System Dashboard v{__APP_VERSION__}</p>
|
||||
|
||||
<!-- Status Badge -->
|
||||
@@ -214,29 +226,46 @@
|
||||
|
||||
<!-- Upcoming Tasks Section (top priority) -->
|
||||
{#if upcomingData.users.length > 0}
|
||||
{@const periodNames = ['Morning', 'Afternoon', 'Evening']}
|
||||
{@const periodIcons = ['🌅', '☀️', '🌙']}
|
||||
<div class="bg-bg-card border border-border rounded-xl overflow-hidden shadow-xl">
|
||||
<div class="px-5 py-3 border-b border-border">
|
||||
<h2 class="text-sm font-semibold text-text-primary uppercase tracking-wider">
|
||||
📋 Upcoming Tasks
|
||||
📋 Today's Routine
|
||||
</h2>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-0 divide-y md:divide-y-0 md:divide-x divide-border">
|
||||
{#each upcomingData.users as user}
|
||||
{@const routineTasks = user.tasks.filter(t => t.recurrence > 0)}
|
||||
<div class="p-4">
|
||||
<h3 class="text-xs font-bold text-accent mb-3 uppercase tracking-wider">{user.name}</h3>
|
||||
{#if user.tasks.length === 0}
|
||||
<p class="text-[11px] text-text-secondary italic">No pending tasks</p>
|
||||
{#if routineTasks.length === 0}
|
||||
<p class="text-[11px] text-text-secondary italic">No routine tasks</p>
|
||||
{:else}
|
||||
<div class="space-y-2">
|
||||
{#each user.tasks as task}
|
||||
<div class="flex items-start gap-2">
|
||||
<span class="text-[10px] mt-0.5 {isOverdue(task.due_date) ? 'text-danger' : 'text-text-secondary'} font-mono whitespace-nowrap">
|
||||
{formatRelativeDate(task.due_date)}
|
||||
</span>
|
||||
<span class="text-xs text-text-primary leading-tight">{task.title}</span>
|
||||
{#each [0, 1, 2] as periodIdx}
|
||||
{@const tasksForPeriod = routineTasks.filter(t => t.period & (1 << periodIdx))}
|
||||
{#if tasksForPeriod.length > 0}
|
||||
<div class="mb-2">
|
||||
<div class="text-[10px] uppercase tracking-wider text-text-secondary font-semibold mb-1">
|
||||
{periodIcons[periodIdx]} {periodNames[periodIdx]}
|
||||
</div>
|
||||
{#each tasksForPeriod as task}
|
||||
<div class="flex items-center gap-2 py-0.5 pl-3">
|
||||
<span class="text-xs text-text-primary leading-tight">• {task.title}</span>
|
||||
{#if task.recurrence > 0}
|
||||
<span class="text-[9px] text-accent font-mono">
|
||||
{task.recurrence === 0x7F ? '∞' : task.recurrence === 0x1F ? 'wk' : ''}
|
||||
</span>
|
||||
{:else if task.due_date > 0}
|
||||
<span class="text-[9px] {isOverdue(task.due_date) ? 'text-danger' : 'text-text-secondary'} font-mono">
|
||||
{formatRelativeDate(task.due_date)}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user