Recently Removed Events โ Frontend Widget
For: Socrates ๐ง
From: Daedalus ๐จ
Date: 2026-04-24
Status: Frontend complete โ awaiting backend wiring
What's Built
Dashboard Widget
A new "Recently Removed" card added to the HoffDesk family dashboard (dashboard/templates/index.html):
- JS-driven polling โ calls
GET /family/events/removed?hours=24&limit=5every 60 seconds - Hidden by default โ card starts
display: none, only appears whencount > 0 - Source icons: ๐ฐ newsletter, ๐ง appointment, ๐จโ๐ฉโ๐งโ๐ฆ family, ๐ fallback
- Strikethrough titles โ removed event summaries are visually struck through with muted opacity
- Relative timestamps โ "removed 2h ago" format
- Smart date display โ "Today 3:30 PM", "Tomorrow 10:00 AM", "Apr 28 3:30 PM"
CSS (in dashboard/static/style.css)
New classes added:
- .removed-list โ flex column layout matching .event-list
- .removed-item โ row with icon + details, hover state
- .removed-icon โ emoji source indicator
- .removed-summary โ struck-through event title
- .removed-meta โ time + relative removal timestamp
Integration Notes
Endpoint Expected
GET /family/events/removed?hours=24&limit=5
Header: X-Hoffdesk-Secret: <secret>
Response Format
{
"removals": [
{
"uid": "dceb54d1-...",
"summary": "Softball Tryouts",
"start_time": "2026-04-28T15:30:00",
"removed_at": "2026-04-24T01:35:22.184532",
"removed_by": "telegram_user_-5296734042",
"source": "newsletter",
"reason": "User clicked REMOVE button",
"can_undo": false
}
],
"count": 1,
"hours": 24,
"timestamp": "2026-04-24T01:36:00.000000"
}
Auth (Updated 2026-04-24 โ per Socrates' security review)
โ ๏ธ Never expose X-Hoffdesk-Secret in browser HTML or JavaScript.
| Pattern | How | Security | Status |
|---|---|---|---|
| Proxy (production) | Dashboard server adds header when proxying to API | โ Secret stays server-side | Recommended |
| Session cookie (production) | User logs in โ session cookie โ server validates | โ Secret stays server-side | Recommended |
| Meta tag (dev only) | <meta name="x-hoffdesk-secret"> JS reads |
โ Visible in View Source | Dev only |
Current implementation: JS sends the request without a secret header. In production, the dashboard dev server should proxy the request and inject X-Hoffdesk-Secret server-side. For local dev, a <meta> tag can be added to the HTML.
For Aundrea's production access: Use session cookies or proxy pattern. She should never see API secrets.
Behavior Rules
| Condition | Behavior |
|---|---|
count === 0 |
Hide card entirely (display: none) |
count > 0 |
Show card with up to 5 items |
| Network error | Hide card, log error to console |
can_undo === true |
(Future) Show undo button โ not yet implemented |
Files Changed
| File | Change |
|---|---|
dashboard/templates/index.html |
Added removed-card section, JS fetch/renderer, helpers |
dashboard/static/style.css |
Added .removed-* classes |
No Backend Changes Needed From Socrates
The API spec in shared/api-specs/recently-removed-events.md already matches what the frontend expects. Just confirm the endpoint is live and returns the documented format.
Future Enhancements (v2)
- Undo button when
can_undo === true(currently alwaysfalseper Radicale limitations) - "View All โ" link to expand beyond 5 items
- Group by source with section headers