Asked claude opus to make an audit of code and use coding guidelines etc. This is the fix
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script>
|
||||
import { getSystemInfo, reboot, getOTAStatus, getUpcomingTasks } from "./lib/api.js";
|
||||
import { formatUptime, formatBytes, formatRelativeDate, isOverdue } from "./lib/utils.js";
|
||||
import OTAUpdate from "./lib/OTAUpdate.svelte";
|
||||
import Sidebar from "./lib/Sidebar.svelte";
|
||||
import TaskManager from "./lib/TaskManager.svelte";
|
||||
@@ -32,49 +33,7 @@
|
||||
|
||||
let upcomingData = $state({ users: [] });
|
||||
|
||||
/** Format uptime seconds into human-readable string */
|
||||
function formatUptime(seconds) {
|
||||
const d = Math.floor(seconds / 86400);
|
||||
const h = Math.floor((seconds % 86400) / 3600);
|
||||
const m = Math.floor((seconds % 3600) / 60);
|
||||
const s = seconds % 60;
|
||||
const parts = [];
|
||||
if (d > 0) parts.push(`${d}d`);
|
||||
if (h > 0) parts.push(`${h}h`);
|
||||
if (m > 0) parts.push(`${m}m`);
|
||||
parts.push(`${s}s`);
|
||||
return parts.join(" ");
|
||||
}
|
||||
|
||||
/** Format bytes into human-readable string */
|
||||
function formatBytes(bytes) {
|
||||
if (bytes >= 1048576) return `${(bytes / 1048576).toFixed(1)} MB`;
|
||||
if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
||||
return `${bytes} B`;
|
||||
}
|
||||
|
||||
function formatRelativeDate(timestamp) {
|
||||
const now = Date.now() / 1000;
|
||||
const diff = timestamp - now;
|
||||
const absDiff = Math.abs(diff);
|
||||
|
||||
if (absDiff < 3600) {
|
||||
const mins = Math.round(absDiff / 60);
|
||||
return diff < 0 ? `${mins}m ago` : `in ${mins}m`;
|
||||
}
|
||||
if (absDiff < 86400) {
|
||||
const hours = Math.round(absDiff / 3600);
|
||||
return diff < 0 ? `${hours}h ago` : `in ${hours}h`;
|
||||
}
|
||||
const days = Math.round(absDiff / 86400);
|
||||
return diff < 0 ? `${days}d ago` : `in ${days}d`;
|
||||
}
|
||||
|
||||
function isOverdue(timestamp) {
|
||||
return timestamp < Date.now() / 1000;
|
||||
}
|
||||
|
||||
let isFetching = false;
|
||||
let isFetching = false; // mutex, not reactive
|
||||
let lastKnownFirmware = null;
|
||||
let lastKnownSlot = null;
|
||||
async function fetchAll(silent = false) {
|
||||
@@ -158,7 +117,7 @@
|
||||
]);
|
||||
</script>
|
||||
|
||||
<div class="app-layout">
|
||||
<div class="flex min-h-screen bg-bg-primary">
|
||||
<Sidebar
|
||||
{currentView}
|
||||
isOpen={mobileMenuOpen}
|
||||
@@ -168,25 +127,25 @@
|
||||
|
||||
{#if mobileMenuOpen}
|
||||
<button
|
||||
class="mobile-backdrop"
|
||||
class="fixed inset-0 bg-black/40 backdrop-blur z-[999] border-none p-0 cursor-pointer"
|
||||
onclick={() => mobileMenuOpen = false}
|
||||
aria-label="Close menu"
|
||||
></button>
|
||||
{/if}
|
||||
|
||||
<main class="main-content">
|
||||
<main class="main-gradient-bg flex-1 p-8 h-screen overflow-y-auto max-md:p-4 max-md:h-auto">
|
||||
<!-- Mobile Top Bar -->
|
||||
<header class="mobile-header">
|
||||
<header class="hidden max-md:flex items-center justify-between px-4 py-3 bg-bg-card border-b border-border sticky top-0 z-50 backdrop-blur-[10px] max-md:-mx-4 max-md:-mt-4 max-md:mb-5">
|
||||
<!-- svelte-ignore a11y_consider_explicit_label -->
|
||||
<button class="hamburger" onclick={() => mobileMenuOpen = true}>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<button class="bg-transparent border-none text-text-primary p-2 cursor-pointer" onclick={() => mobileMenuOpen = true}>
|
||||
<svg class="w-6 h-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
|
||||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||||
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||||
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="mobile-title">Calendink</span>
|
||||
<div style="width: 40px;"></div> <!-- Spacer -->
|
||||
<span class="font-bold text-base tracking-[-0.02em] text-accent">Calendink</span>
|
||||
<div class="w-10"></div> <!-- Spacer -->
|
||||
</header>
|
||||
|
||||
<div class="w-full max-w-6xl mx-auto space-y-8">
|
||||
@@ -378,7 +337,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Updates & Maintenance Card -->
|
||||
<OTAUpdate onReboot={() => { status = "rebooting"; isRecovering = true; }} />
|
||||
<OTAUpdate otaInfo={otaStatus} {systemInfo} onReboot={() => { status = "rebooting"; isRecovering = true; }} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -426,87 +385,3 @@
|
||||
</div>
|
||||
|
||||
<Spinner />
|
||||
|
||||
<style>
|
||||
.app-layout {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
background: var(--color-bg-primary);
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 32px;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
background: radial-gradient(circle at top right, var(--color-bg-card), transparent 40%),
|
||||
var(--color-bg-primary);
|
||||
}
|
||||
|
||||
.mobile-header {
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px;
|
||||
background: var(--color-bg-card);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--color-text-primary);
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.hamburger svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.mobile-title {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
letter-spacing: -0.02em;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.mobile-backdrop {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
backdrop-filter: blur(4px);
|
||||
z-index: 999;
|
||||
border: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
animation: fadeIn 0.2s ease-out;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.main-content {
|
||||
padding: 16px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.mobile-header {
|
||||
display: flex;
|
||||
margin: -16px -16px 20px -16px;
|
||||
}
|
||||
|
||||
.mobile-backdrop {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user