summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-27 07:02:33 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-27 07:02:33 -1000
commit59c360c3c33a55447f08e95fed4714959300850c (patch)
treebdcd7fa0f98fa8ab874e63f888d7dc5528aee763
parentf8757aef930a22669255359ff50908e0f7a941af (diff)
Fix z-index, conditions auth, and meal combining (#62, #63, #64)
Bug fixes: - #62: Increase FAB button z-index from z-40 to z-50 - #63: Combine multiple meals per date+mealType in Meals tab - #64: Make /conditions route public (no auth required) Changes: - FAB button now z-50 (same as modals, appears on top when scrolling) - Meals tab groups meals by date+mealType, joins recipe names with " + " - Conditions page moved outside protected routes group DESIGN.md updates: - Updated z-index hierarchy table - Added Meals View section - Noted conditions page is public Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
-rw-r--r--DESIGN.md13
-rw-r--r--cmd/dashboard/main.go4
-rw-r--r--internal/handlers/handlers.go63
-rw-r--r--web/templates/index.html2
-rw-r--r--web/templates/partials/plantoeat-meals.html2
5 files changed, 79 insertions, 5 deletions
diff --git a/DESIGN.md b/DESIGN.md
index 1bc9ed9..32e2d15 100644
--- a/DESIGN.md
+++ b/DESIGN.md
@@ -190,7 +190,7 @@ BuildTimeline(ctx, store, calendarClient, tasksClient, start, end)
| Content | default | Page content |
| Sticky headers | z-10 | Timeline section headers |
| Details dropdown | z-30 | Navigation dropdown menu |
-| FAB button | z-40 | Floating action button |
+| FAB button | z-50 | Floating action button |
| Modals | z-50 | Action modal, edit modal |
### Typography
@@ -290,8 +290,19 @@ Aggregated shopping lists from Trello + PlanToEat + user items.
- Large touch targets
- Fixed bottom quick-add
+### Meals View (`/tabs/meals`)
+
+PlanToEat meal schedule for the next 7 days.
+
+**Features:**
+- Meals grouped by date + meal type (breakfast/lunch/dinner)
+- Multiple recipes for same slot combined with " + " separator
+- Sorted by date, then meal type order
+
### Conditions Page (`/conditions`)
+**Public route** - no authentication required.
+
Standalone live feeds page with:
- 3 Kilauea volcano webcams (USGS)
- 2 Hawaii weather maps (Windy.com)
diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go
index 920ccf2..ce91e6e 100644
--- a/cmd/dashboard/main.go
+++ b/cmd/dashboard/main.go
@@ -145,13 +145,15 @@ func main() {
fileServer := http.FileServer(http.Dir(cfg.StaticDir))
r.Handle("/static/*", http.StripPrefix("/static/", fileServer))
+ // Conditions page (public - no auth required)
+ r.Get("/conditions", h.HandleConditionsPage)
+
// Protected routes (auth required)
r.Group(func(r chi.Router) {
r.Use(authHandlers.Middleware().RequireAuth)
// Dashboard
r.Get("/", h.HandleDashboard)
- r.Get("/conditions", h.HandleConditionsPage)
r.Post("/api/refresh", h.HandleRefresh)
r.Get("/api/tasks", h.HandleGetTasks)
r.Get("/api/meals", h.HandleGetMeals)
diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go
index 1c2eb18..9fe1b2c 100644
--- a/internal/handlers/handlers.go
+++ b/internal/handlers/handlers.go
@@ -1139,6 +1139,14 @@ func (h *Handler) HandleTabPlanning(w http.ResponseWriter, r *http.Request) {
HTMLResponse(w, h.templates, "planning-tab", data)
}
+// CombinedMeal represents multiple meals combined for same date+mealType
+type CombinedMeal struct {
+ RecipeNames []string
+ Date time.Time
+ MealType string
+ RecipeURL string // URL of first meal
+}
+
// HandleTabMeals renders the Meals tab (PlanToEat)
func (h *Handler) HandleTabMeals(w http.ResponseWriter, r *http.Request) {
startDate := config.Now()
@@ -1150,7 +1158,60 @@ func (h *Handler) HandleTabMeals(w http.ResponseWriter, r *http.Request) {
return
}
- HTMLResponse(w, h.templates, "meals-tab", struct{ Meals []models.Meal }{meals})
+ // Group meals by date+mealType
+ type mealKey struct {
+ date string
+ mealType string
+ }
+ mealGroups := make(map[mealKey][]models.Meal)
+ for _, meal := range meals {
+ key := mealKey{
+ date: meal.Date.Format("2006-01-02"),
+ mealType: meal.MealType,
+ }
+ mealGroups[key] = append(mealGroups[key], meal)
+ }
+
+ // Convert to combined meals
+ var combined []CombinedMeal
+ for _, group := range mealGroups {
+ if len(group) == 0 {
+ continue
+ }
+ cm := CombinedMeal{
+ Date: group[0].Date,
+ MealType: group[0].MealType,
+ RecipeURL: group[0].RecipeURL,
+ }
+ for _, m := range group {
+ cm.RecipeNames = append(cm.RecipeNames, m.RecipeName)
+ }
+ combined = append(combined, cm)
+ }
+
+ // Sort by date then meal type order
+ sort.Slice(combined, func(i, j int) bool {
+ if !combined[i].Date.Equal(combined[j].Date) {
+ return combined[i].Date.Before(combined[j].Date)
+ }
+ return mealTypeOrder(combined[i].MealType) < mealTypeOrder(combined[j].MealType)
+ })
+
+ HTMLResponse(w, h.templates, "meals-tab", struct{ Meals []CombinedMeal }{combined})
+}
+
+// mealTypeOrder returns sort order for meal types
+func mealTypeOrder(mealType string) int {
+ switch mealType {
+ case "breakfast":
+ return 0
+ case "lunch":
+ return 1
+ case "dinner":
+ return 2
+ default:
+ return 3
+ }
}
// HandleTabShopping renders the Shopping tab (Trello Shopping board + PlanToEat + User items)
diff --git a/web/templates/index.html b/web/templates/index.html
index c6743ba..3451623 100644
--- a/web/templates/index.html
+++ b/web/templates/index.html
@@ -118,7 +118,7 @@
<!-- Unified Action Button (FAB) -->
<button onclick="openActionModal()"
- class="fixed bottom-4 right-4 z-40 bg-black/60 hover:bg-black/80 backdrop-blur-sm text-white p-4 rounded-full no-print"
+ class="fixed bottom-4 right-4 z-50 bg-black/60 hover:bg-black/80 backdrop-blur-sm text-white p-4 rounded-full no-print"
style="box-shadow: 0 0 12px black;"
title="Quick Actions (Ctrl+K)">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
diff --git a/web/templates/partials/plantoeat-meals.html b/web/templates/partials/plantoeat-meals.html
index 1f016ef..f05c98c 100644
--- a/web/templates/partials/plantoeat-meals.html
+++ b/web/templates/partials/plantoeat-meals.html
@@ -10,7 +10,7 @@
<div class="space-y-3">
{{range .Meals}}
<div class="border-l-4 border-plantoeat bg-black/30 pl-4 py-3 rounded-r-lg hover:bg-black/40 transition-colors">
- <p class="font-medium text-white">{{.RecipeName}}</p>
+ <p class="font-medium text-white">{{range $i, $name := .RecipeNames}}{{if $i}} + {{end}}{{$name}}{{end}}</p>
<div class="flex justify-between items-center mt-2">
<span class="text-sm text-white/60">{{.Date.Format "Mon, Jan 2"}}</span>
<span class="badge bg-green-900/50 text-green-300 capitalize">