chore: auto-commit uncommitted changes
This commit is contained in:
parent
8ca3514735
commit
7b138ae605
|
|
@ -1,61 +1,5 @@
|
|||
{
|
||||
"deliveries": [
|
||||
{
|
||||
"id": "20a209a9",
|
||||
"carrier": "UPS",
|
||||
"retailer": "Tri-Med",
|
||||
"description": "Tri-Med Medical Supplies Order #3386",
|
||||
"expected_date": "2026-01-27",
|
||||
"status": "delivered",
|
||||
"notes": "Sophia medical supplies. Import fee $43.25 paid.",
|
||||
"created_at": "2026-02-01T06:30:58.42184085Z",
|
||||
"updated_at": "2026-02-01T06:30:58.421840934Z"
|
||||
},
|
||||
{
|
||||
"id": "ef54b72b",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "Brother ADS-4300N Professional Desktop Scanner",
|
||||
"expected_date": "2026-02-02",
|
||||
"status": "delivered",
|
||||
"notes": "Order #112-7614761-1552234 - $427.99 | Delivered Feb 2 - left near front door",
|
||||
"created_at": "2026-02-01T19:30:52.407998449Z",
|
||||
"updated_at": "2026-02-02T22:54:22.634574588Z"
|
||||
},
|
||||
{
|
||||
"id": "627e730e",
|
||||
"carrier": "eBay",
|
||||
"retailer": "eBay",
|
||||
"description": "Intel Xeon E3 SR14S CPU",
|
||||
"expected_date": "2026-02-02",
|
||||
"status": "delivered",
|
||||
"notes": "Delivered Mon Feb 2, 4:42 PM. E3-1275v3 for james server upgrade.",
|
||||
"created_at": "2026-02-02T12:40:49.133341067Z",
|
||||
"updated_at": "2026-02-02T21:58:07.178775258Z"
|
||||
},
|
||||
{
|
||||
"id": "7e90d6e0",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "World Organic - Chlorophyll Liquid",
|
||||
"expected_date": "2026-02-08",
|
||||
"status": "shipped",
|
||||
"notes": "Order #112-4979107-5850639 — $13.42",
|
||||
"created_at": "2026-02-04T12:50:16.021108279-05:00",
|
||||
"updated_at": "2026-02-04T12:50:16.021108323-05:00"
|
||||
},
|
||||
{
|
||||
"id": "5559792b",
|
||||
"carrier": "Pediatric Home Service",
|
||||
"retailer": "All About Pediatrics",
|
||||
"description": "Sophia medical supplies (pulse ox wraps, etc.)",
|
||||
"tracking_number": "75175",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "shipped",
|
||||
"notes": "4 boxes shipped Feb 3. Order #75175.",
|
||||
"created_at": "2026-02-04T13:11:29.306713737-05:00",
|
||||
"updated_at": "2026-02-04T13:11:29.306713781-05:00"
|
||||
},
|
||||
{
|
||||
"id": "0e67333b",
|
||||
"carrier": "Pediatric Home Service",
|
||||
|
|
@ -63,10 +7,10 @@
|
|||
"description": "Sophia monthly supplies (Feb 2026) - 4 boxes",
|
||||
"tracking_number": "75175",
|
||||
"expected_date": "2026-02-06",
|
||||
"status": "in_transit",
|
||||
"notes": "Shipped Feb 3. Trach ties, saline, gauze, suction tubes, filters, gloves, H2O2, trach, pulse-ox wraps, cleaning kits, collars, alcohol wipes. Still need updated Rx from Dr Lastra for pulse-ox wraps.",
|
||||
"status": "delivered",
|
||||
"notes": "Shipped Feb 3, 4 boxes. Expected Feb 6-7.",
|
||||
"created_at": "2026-02-04T14:36:17.040575584-05:00",
|
||||
"updated_at": "2026-02-04T14:36:17.040575636-05:00"
|
||||
"updated_at": "2026-02-08T03:48:44.120692938-05:00"
|
||||
},
|
||||
{
|
||||
"id": "4d72150d",
|
||||
|
|
@ -80,72 +24,6 @@
|
|||
"created_at": "2026-02-04T14:36:17.076836995-05:00",
|
||||
"updated_at": "2026-02-04T14:36:17.076837035-05:00"
|
||||
},
|
||||
{
|
||||
"id": "0f28675d",
|
||||
"carrier": "Pediatric Home Service",
|
||||
"retailer": "All About Pediatrics",
|
||||
"description": "Sophia monthly supplies (Feb 2026) - Pediatric Home Service",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "shipped",
|
||||
"notes": "Order #75175, 4 boxes, shipped Feb 3. Trach ties, saline, gauze, suction tubes, filters, gloves, H2O2, trach, cleaning kits, collars, alcohol wipes.",
|
||||
"created_at": "2026-02-04T15:24:15.704405892-05:00",
|
||||
"updated_at": "2026-02-04T15:24:15.704405942-05:00"
|
||||
},
|
||||
{
|
||||
"id": "1c3a76f8",
|
||||
"carrier": "Pediatric Home Service",
|
||||
"retailer": "Pediatric Home Service",
|
||||
"description": "Sophia supplies (4 boxes)",
|
||||
"tracking_number": "75175",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "shipped",
|
||||
"notes": "Shipped Feb 3, 2026. Order #75175. Pulse-ox wraps prescription issue - expired, needs renewal.",
|
||||
"created_at": "2026-02-04T16:31:59.598579883-05:00",
|
||||
"updated_at": "2026-02-04T16:31:59.598579924-05:00"
|
||||
},
|
||||
{
|
||||
"id": "0882ab83",
|
||||
"carrier": "Pediatric Home Service",
|
||||
"retailer": "Pediatric Home Service",
|
||||
"description": "Sophia medical supplies (4 boxes)",
|
||||
"expected_date": "2026-02-06",
|
||||
"status": "shipped",
|
||||
"notes": "Order #75175, shipped Feb 3",
|
||||
"created_at": "2026-02-04T20:18:45.540488089-05:00",
|
||||
"updated_at": "2026-02-04T20:18:45.540488134-05:00"
|
||||
},
|
||||
{
|
||||
"id": "3cbb090f",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "World Organic Chlorophyll",
|
||||
"expected_date": "2026-02-09",
|
||||
"status": "shipped",
|
||||
"notes": "Order #112-4979107-5850639, $13.42",
|
||||
"created_at": "2026-02-04T20:19:33.429595282-05:00",
|
||||
"updated_at": "2026-02-04T20:19:33.429595321-05:00"
|
||||
},
|
||||
{
|
||||
"id": "fa880aec",
|
||||
"carrier": "Amazon",
|
||||
"description": "Amazon: Mickiewicz A4 Box \u0026 Frame",
|
||||
"tracking_number": "112-3270982-9786636",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "delivered",
|
||||
"notes": "Delivered Feb 7 - left at front door",
|
||||
"created_at": "2026-02-07T01:35:44.405003972-05:00",
|
||||
"updated_at": "2026-02-07T18:54:49.904848713-05:00"
|
||||
},
|
||||
{
|
||||
"id": "671b07c8",
|
||||
"carrier": "UPS",
|
||||
"description": "UPS: JIMMY LE (Signature Required)",
|
||||
"tracking_number": "1ZX866D54223587093",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"created_at": "2026-02-07T01:35:44.417078183-05:00",
|
||||
"updated_at": "2026-02-07T01:35:44.417078223-05:00"
|
||||
},
|
||||
{
|
||||
"id": "90333f6c",
|
||||
"carrier": "Other",
|
||||
|
|
@ -161,34 +39,10 @@
|
|||
"description": "ARG ButyrEn Colon Lining, INCAS Butterfly Pea",
|
||||
"tracking_number": "113-8193397-8031467",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"notes": "Arriving today 7 AM - 11 AM (Updated from email)",
|
||||
"created_at": "2026-02-07T02:18:56.918641023-05:00",
|
||||
"updated_at": "2026-02-07T09:23:25.229040845-05:00"
|
||||
},
|
||||
{
|
||||
"id": "f4ac3352",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "OM Mushroom Cordyceps Powder",
|
||||
"tracking_number": "113-3964151-5665049",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "delivered",
|
||||
"notes": "Delivered Feb 7 - left at front door",
|
||||
"created_at": "2026-02-07T02:18:56.924406989-05:00",
|
||||
"updated_at": "2026-02-07T18:54:49.898880888-05:00"
|
||||
},
|
||||
{
|
||||
"id": "01f106ce",
|
||||
"carrier": "UPS",
|
||||
"retailer": "Unknown",
|
||||
"description": "Package from JIMMY LE",
|
||||
"tracking_number": "1ZX866D54223587093",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "in_transit",
|
||||
"notes": "Arriving today 2 PM - 6 PM",
|
||||
"created_at": "2026-02-07T02:18:56.930064873-05:00",
|
||||
"updated_at": "2026-02-07T02:18:56.930064913-05:00"
|
||||
"notes": "Arriving today 7 AM - 11 AM. Likely delivered Feb 7.",
|
||||
"created_at": "2026-02-07T02:18:56.918641023-05:00",
|
||||
"updated_at": "2026-02-08T03:48:34.238948912-05:00"
|
||||
},
|
||||
{
|
||||
"id": "a7c36153",
|
||||
|
|
@ -197,124 +51,20 @@
|
|||
"description": "Pure Encapsulations Vitamin D3 \u0026 K2 Liquid",
|
||||
"tracking_number": "113-1880998-3453029",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"notes": "Arriving today 10 AM – 3 PM (Updated from email)",
|
||||
"created_at": "2026-02-07T02:51:07.360704007-05:00",
|
||||
"updated_at": "2026-02-07T09:22:48.097426944-05:00"
|
||||
},
|
||||
{
|
||||
"id": "3bea0e2d",
|
||||
"carrier": "Amazon",
|
||||
"description": "Pure Encapsulations Vitamin D3",
|
||||
"status": "shipped",
|
||||
"created_at": "2026-02-07T05:47:05.790779196-05:00",
|
||||
"updated_at": "2026-02-07T05:47:05.790779236-05:00"
|
||||
},
|
||||
{
|
||||
"id": "b4a65bd5",
|
||||
"carrier": "Amazon",
|
||||
"description": "ARG ButyrEn Colon Lining",
|
||||
"status": "in_transit",
|
||||
"created_at": "2026-02-07T05:47:05.796554683-05:00",
|
||||
"updated_at": "2026-02-07T05:47:05.796554728-05:00"
|
||||
},
|
||||
{
|
||||
"id": "1921176f",
|
||||
"carrier": "UPS",
|
||||
"description": "Package from JIMMY LE (Signature Required)",
|
||||
"tracking_number": "1ZX866D54223587093",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"created_at": "2026-02-07T05:47:05.8095637-05:00",
|
||||
"updated_at": "2026-02-07T05:47:05.80956375-05:00"
|
||||
},
|
||||
{
|
||||
"id": "02ca5ace",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "ARG ButyrEn \u0026 Butterfly Pea Flower",
|
||||
"tracking_number": "113-8193397-8031467",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"created_at": "2026-02-07T06:11:10.322120933-05:00",
|
||||
"updated_at": "2026-02-07T06:11:10.322120973-05:00"
|
||||
},
|
||||
{
|
||||
"id": "f821124c",
|
||||
"carrier": "UPS",
|
||||
"retailer": "Unknown",
|
||||
"description": "Package from Jimmy Le",
|
||||
"tracking_number": "1ZX866D54223587093",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"notes": "Arriving today 2 PM - 6 PM (Signature Required) (Updated from email)",
|
||||
"created_at": "2026-02-07T06:11:10.334051915-05:00",
|
||||
"updated_at": "2026-02-07T09:23:25.241375793-05:00"
|
||||
},
|
||||
{
|
||||
"id": "28a5352a",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "Amazon: ButyrEn \u0026 Butterfly Pea Flower",
|
||||
"tracking_number": "113-8193397-8031467",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"created_at": "2026-02-07T08:35:16.557843046-05:00",
|
||||
"updated_at": "2026-02-07T08:35:16.557843087-05:00"
|
||||
},
|
||||
{
|
||||
"id": "75272605",
|
||||
"carrier": "UPS",
|
||||
"retailer": "Unknown",
|
||||
"description": "UPS: Package from JIMMY LE (Signature Required)",
|
||||
"tracking_number": "1ZX866D54223587093",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"notes": "Signature Required",
|
||||
"created_at": "2026-02-07T08:35:16.611208985-05:00",
|
||||
"updated_at": "2026-02-07T08:35:16.611209025-05:00"
|
||||
},
|
||||
{
|
||||
"id": "e3c6a7cb",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "Debbie Meyer GreenBags 40-Pack + Amazon Basics Gallon Bags (x2)",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "delivered",
|
||||
"notes": "Order #113-1370340-7784255. Delivered Feb 7, left near front door.",
|
||||
"created_at": "2026-02-07T16:58:44.446390969-05:00",
|
||||
"updated_at": "2026-02-07T20:02:48.222265547-05:00"
|
||||
"notes": "Likely delivered Feb 7.",
|
||||
"created_at": "2026-02-07T02:51:07.360704007-05:00",
|
||||
"updated_at": "2026-02-08T03:48:34.250472485-05:00"
|
||||
},
|
||||
{
|
||||
"id": "9e4540ab",
|
||||
"carrier": "Colorado Camel Milk",
|
||||
"retailer": "Colorado Camel Milk",
|
||||
"description": "Raw Camel Milk (6 Pints, Frozen)",
|
||||
"status": "shipped",
|
||||
"notes": "Order #16698, $115.00 (paid via Venmo)",
|
||||
"created_at": "2026-02-07T17:42:53.341962693-05:00",
|
||||
"updated_at": "2026-02-07T17:42:53.341962732-05:00"
|
||||
},
|
||||
{
|
||||
"id": "b97cc4db",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "ARG ButyrEn + INCAS Organic Butterfly Pea",
|
||||
"tracking_number": "113-8193397-8031467",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"created_at": "2026-02-07T23:46:33.865768972-05:00",
|
||||
"updated_at": "2026-02-07T23:46:33.86576901-05:00"
|
||||
},
|
||||
{
|
||||
"id": "687fa874",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "OM Mushroom Cordyceps Powder",
|
||||
"tracking_number": "113-3964151-5665049",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"created_at": "2026-02-07T23:46:33.871339337-05:00",
|
||||
"updated_at": "2026-02-07T23:46:33.871339382-05:00"
|
||||
"updated_at": "2026-02-08T03:50:24.733529085-05:00"
|
||||
},
|
||||
{
|
||||
"id": "29790fb7",
|
||||
|
|
@ -323,20 +73,21 @@
|
|||
"tracking_number": "1ZX866D54223587093",
|
||||
"tracking_url": "https://www.ups.com/track?tracknum=1ZX866D54223587093",
|
||||
"expected_date": "2026-02-07",
|
||||
"status": "out_for_delivery",
|
||||
"status": "delivered",
|
||||
"notes": "Signature required. ETA 2-6 PM",
|
||||
"created_at": "2026-02-07T23:46:33.876959687-05:00",
|
||||
"updated_at": "2026-02-07T23:46:33.876959731-05:00"
|
||||
"updated_at": "2026-02-08T03:48:34.244859442-05:00"
|
||||
},
|
||||
{
|
||||
"id": "30314356",
|
||||
"carrier": "Amazon",
|
||||
"retailer": "Amazon",
|
||||
"description": "MagiCare 75% Large Alcohol Wipes",
|
||||
"expected_date": "2026-02-09",
|
||||
"status": "shipped",
|
||||
"notes": "Order #112-6757146-7896258, $29.95",
|
||||
"created_at": "2026-02-08T01:09:32.878277346-05:00",
|
||||
"updated_at": "2026-02-08T01:09:32.878277392-05:00"
|
||||
"updated_at": "2026-02-08T03:50:24.739469433-05:00"
|
||||
},
|
||||
{
|
||||
"id": "e72c423c",
|
||||
|
|
|
|||
|
|
@ -1,46 +1,40 @@
|
|||
{
|
||||
"items": {
|
||||
"claude": {
|
||||
"key": "claude",
|
||||
"value": "10% weekly · checked 3:00 AM",
|
||||
"type": "info",
|
||||
"updated_at": "2026-02-08T03:48:44.142964395-05:00"
|
||||
},
|
||||
"claude-usage": {
|
||||
"key": "claude-usage",
|
||||
"value": "📊 Weekly: 10% used (90% remaining)",
|
||||
"value": "📊 Weekly: 11% used (89% remaining)",
|
||||
"type": "info",
|
||||
"updated_at": "2026-02-08T02:19:40.561285908-05:00"
|
||||
},
|
||||
"claude_usage": {
|
||||
"key": "claude_usage",
|
||||
"value": "100%",
|
||||
"type": "error",
|
||||
"updated_at": "2026-02-07T02:51:20.984852047-05:00"
|
||||
"updated_at": "2026-02-08T04:19:41.402068343-05:00"
|
||||
},
|
||||
"claude_weekly": {
|
||||
"key": "claude_weekly",
|
||||
"value": "10% used · 3:00 AM",
|
||||
"value": "11% used · 4:00 AM",
|
||||
"type": "info",
|
||||
"updated_at": "2026-02-08T03:00:03.972507289-05:00"
|
||||
"updated_at": "2026-02-08T04:00:03.434683526-05:00"
|
||||
},
|
||||
"openclaw-update": {
|
||||
"key": "openclaw-update",
|
||||
"value": "2026.2.2-3 (latest) ✅",
|
||||
"openclaw": {
|
||||
"key": "openclaw",
|
||||
"value": "2026.2.2-3",
|
||||
"type": "info",
|
||||
"updated_at": "2026-02-04T13:26:44.866210785-05:00"
|
||||
"updated_at": "2026-02-08T03:48:44.148386604-05:00"
|
||||
},
|
||||
"services": {
|
||||
"key": "services",
|
||||
"value": "All services healthy ✅ (checked 09:52 UTC)",
|
||||
"value": "All healthy",
|
||||
"type": "info",
|
||||
"updated_at": "2026-02-07T04:52:09.952144442-05:00"
|
||||
},
|
||||
"valley_balance": {
|
||||
"key": "valley_balance",
|
||||
"value": "$29,892.71",
|
||||
"type": "info",
|
||||
"updated_at": "2026-02-07T09:23:25.26084725-05:00"
|
||||
"updated_at": "2026-02-08T03:48:44.153833827-05:00"
|
||||
},
|
||||
"zurich": {
|
||||
"key": "zurich",
|
||||
"value": "VPS OK ✅",
|
||||
"value": "VPS OK",
|
||||
"type": "info",
|
||||
"updated_at": "2026-02-04T13:26:44.877121921-05:00"
|
||||
"updated_at": "2026-02-08T03:48:44.164810289-05:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
156
index.html
156
index.html
|
|
@ -73,6 +73,23 @@
|
|||
|
||||
.updated { font-size: 0.8rem; color: var(--text-muted); }
|
||||
|
||||
/* Claude Usage Mini Chart */
|
||||
.claude-chart-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 4px 10px;
|
||||
background: var(--bg);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.claude-chart-label { font-size: 0.75rem; color: var(--text-muted); white-space: nowrap; }
|
||||
.claude-chart-pct { font-size: 0.85rem; font-weight: 600; }
|
||||
.claude-chart-pct.ok { color: var(--success); }
|
||||
.claude-chart-pct.warning { color: var(--accent); }
|
||||
.claude-chart-pct.error { color: var(--danger); }
|
||||
.claude-chart-svg { display: block; }
|
||||
|
||||
/* Agents Bar */
|
||||
.agents-bar {
|
||||
display: flex;
|
||||
|
|
@ -455,8 +472,8 @@
|
|||
<header>
|
||||
<h1><span class="accent">James</span> Dashboard</h1>
|
||||
<div class="header-right">
|
||||
<div class="claude-chart-wrap" id="claude-chart"></div>
|
||||
<span class="status-inline" id="status-items"></span>
|
||||
<span class="updated" id="last-updated">Loading...</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
@ -755,8 +772,6 @@
|
|||
`;
|
||||
}
|
||||
|
||||
document.getElementById('last-updated').textContent = 'Updated ' + formatTime(new Date().toISOString());
|
||||
|
||||
} catch (e) {
|
||||
console.error('Failed to load data:', e);
|
||||
}
|
||||
|
|
@ -796,30 +811,129 @@
|
|||
return;
|
||||
}
|
||||
|
||||
// Sort by key for consistent display
|
||||
const sorted = Object.entries(items).sort((a, b) => a[0].localeCompare(b[0]));
|
||||
// Custom render order and formatting
|
||||
const parts = [];
|
||||
|
||||
document.getElementById('status-items').innerHTML = sorted.map(([key, item]) => {
|
||||
// Determine color class based on type or value
|
||||
let valueClass = 'ok';
|
||||
if (item.type === 'warning' || (item.value && item.value.includes('%') && parseInt(item.value) > 70)) {
|
||||
valueClass = 'warning';
|
||||
}
|
||||
if (item.type === 'error' || (item.value && item.value.includes('%') && parseInt(item.value) > 85)) {
|
||||
valueClass = 'error';
|
||||
}
|
||||
|
||||
// Compact format for header: "Claude: 46%"
|
||||
const label = key.replace('_weekly', '').replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
|
||||
const shortValue = item.value.replace(/ \([^)]+\)/, ''); // Remove parenthetical
|
||||
|
||||
return `<span class="value ${valueClass}">${label}: ${shortValue}</span>`;
|
||||
}).join(' · ');
|
||||
// OpenClaw version — green if "(latest)" or type=info, red if outdated
|
||||
if (items.openclaw) {
|
||||
const ver = items.openclaw.value.replace(/\s*\(latest\)\s*/g, '').replace(/✅/g, '').trim();
|
||||
const isLatest = items.openclaw.type !== 'error';
|
||||
const color = isLatest ? 'var(--success)' : 'var(--danger)';
|
||||
parts.push(`<span style="color:${color};font-weight:600">OpenClaw ${ver}</span>`);
|
||||
}
|
||||
|
||||
// Services — just the value, no checkmarks
|
||||
if (items.services) {
|
||||
const svc = items.services.value.replace(/✅/g, '').replace(/\(checked[^)]*\)/g, '').replace(/services/gi, '').trim();
|
||||
parts.push(`<span class="value ok">${svc || 'All healthy'}</span>`);
|
||||
}
|
||||
|
||||
// Valley Balance
|
||||
if (items.valley_balance) {
|
||||
parts.push(`<span class="value ok">Valley ${items.valley_balance.value}</span>`);
|
||||
}
|
||||
|
||||
// Zurich — no checkmarks
|
||||
if (items.zurich) {
|
||||
const z = items.zurich.value.replace(/✅/g, '').trim();
|
||||
parts.push(`<span class="value ok">Zurich ${z}</span>`);
|
||||
}
|
||||
|
||||
document.getElementById('status-items').innerHTML = parts.join(' · ');
|
||||
|
||||
// Claude usage mini chart
|
||||
await loadClaudeChart(items.claude);
|
||||
} catch (e) {
|
||||
console.error('Failed to load status:', e);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadClaudeChart(claudeStatus) {
|
||||
const container = document.getElementById('claude-chart');
|
||||
if (!container) return;
|
||||
|
||||
let weeklyPct = 10;
|
||||
let lastCheck = '';
|
||||
let resetTime = null;
|
||||
|
||||
if (claudeStatus) {
|
||||
const m = claudeStatus.value.match(/(\d+)%/);
|
||||
if (m) weeklyPct = parseInt(m[1]);
|
||||
const tm = claudeStatus.value.match(/checked\s+(.+)/);
|
||||
if (tm) lastCheck = tm[1];
|
||||
}
|
||||
|
||||
// Try to get reset time from usage data
|
||||
try {
|
||||
const res = await fetch('/api/claude-usage');
|
||||
if (res.ok) {
|
||||
const d = await res.json();
|
||||
if (d.weekly_resets) resetTime = new Date(d.weekly_resets);
|
||||
if (d.weekly_percent !== undefined) weeklyPct = d.weekly_percent;
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
let pctClass = 'ok';
|
||||
if (weeklyPct > 70) pctClass = 'warning';
|
||||
if (weeklyPct > 85) pctClass = 'error';
|
||||
|
||||
// Chart: 7 days, 4 blocks per day (6h each) = 28 blocks
|
||||
const W = 160, H = 36, PAD = 2;
|
||||
const BLOCKS = 28;
|
||||
const blockW = (W - PAD*2) / BLOCKS;
|
||||
|
||||
// Figure out week start (reset - 7 days)
|
||||
const now = new Date();
|
||||
let weekStart;
|
||||
if (resetTime) {
|
||||
weekStart = new Date(resetTime.getTime() - 7 * 86400000);
|
||||
} else {
|
||||
// Guess: week resets Friday, so started last Friday
|
||||
const d = new Date(now);
|
||||
d.setDate(d.getDate() - ((d.getDay() + 2) % 7)); // last Friday
|
||||
d.setHours(0,0,0,0);
|
||||
weekStart = d;
|
||||
}
|
||||
|
||||
const weekMs = 7 * 86400000;
|
||||
const elapsed = Math.min(now - weekStart, weekMs);
|
||||
const nowBlock = Math.min(Math.floor((elapsed / weekMs) * BLOCKS), BLOCKS);
|
||||
|
||||
// Budget line: 0% → 100% over full week (dashed gray)
|
||||
const bx0 = PAD, by0 = H - PAD;
|
||||
const bx1 = PAD + BLOCKS * blockW, by1 = PAD;
|
||||
|
||||
// Actual usage line: linear from 0 to weeklyPct, ending at nowBlock
|
||||
const ax1 = PAD + nowBlock * blockW;
|
||||
const ay1 = H - PAD - ((weeklyPct / 100) * (H - PAD*2));
|
||||
|
||||
// Day separators
|
||||
let dayLines = '';
|
||||
for (let d = 1; d < 7; d++) {
|
||||
const x = PAD + d * 4 * blockW;
|
||||
dayLines += `<line x1="${x}" y1="0" x2="${x}" y2="${H}" stroke="#E5E2DE" stroke-width="0.5"/>`;
|
||||
}
|
||||
|
||||
// "Now" marker
|
||||
const nowX = PAD + nowBlock * blockW;
|
||||
|
||||
const color = pctClass === 'ok' ? '#059669' : pctClass === 'warning' ? '#B45309' : '#DC2626';
|
||||
|
||||
const svg = `<svg class="claude-chart-svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}">
|
||||
${dayLines}
|
||||
<line x1="${bx0}" y1="${by0}" x2="${bx1}" y2="${by1}" stroke="#E5E2DE" stroke-width="1" stroke-dasharray="3,2"/>
|
||||
<line x1="${PAD}" y1="${H - PAD}" x2="${ax1}" y2="${ay1}" stroke="${color}" stroke-width="2" stroke-linecap="round"/>
|
||||
<circle cx="${ax1}" cy="${ay1}" r="2.5" fill="${color}"/>
|
||||
</svg>`;
|
||||
|
||||
container.innerHTML = `
|
||||
<span class="claude-chart-label">Claude</span>
|
||||
<span class="claude-chart-pct ${pctClass}">${weeklyPct}%</span>
|
||||
${svg}
|
||||
${lastCheck ? `<span class="claude-chart-label">${lastCheck}</span>` : ''}
|
||||
`;
|
||||
}
|
||||
|
||||
loadAgents();
|
||||
loadStatus();
|
||||
loadData();
|
||||
|
|
|
|||
BIN
james-dashboard
BIN
james-dashboard
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue