Show Mon–Fri school lunch menus in a full-width panel layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Joshua King
2026-08-09 14:47:55 -04:00
parent 1ee7f0c739
commit f0af1eacfa
2 changed files with 227 additions and 60 deletions
+165 -60
View File
@@ -1,7 +1,8 @@
# Lunch Menus — school cafeteria calendars (one week each) # Lunch Menus — school cafeteria calendars (MonFri each)
# #
# Three Google Calendar entities, each shown in listWeek so the wall/panel # Panel layout so the title spans the full width and the three school cards
# view stays focused on the current week instead of a full month grid. # sit in one row. Menus come from packages/lunch_menus.yaml (stock calendar
# cards cannot limit to a school-week window).
title: Lunch Menus title: Lunch Menus
theme: cubecraft theme: cubecraft
views: views:
@@ -9,64 +10,168 @@ views:
path: lunch-menus path: lunch-menus
icon: mdi:food-apple icon: mdi:food-apple
theme: cubecraft theme: cubecraft
type: masonry type: panel
cards: cards:
- type: markdown - type: vertical-stack
content: | cards:
# School Lunch Menus - type: markdown
## Week of {{ now().strftime("%B %d, %Y") }} content: |
card_mod: {% set wd = now().weekday() %}
style: | {% if wd >= 5 %}
ha-card { {% set monday = today_at() + timedelta(days=(7 - wd)) %}
background: var(--cc-gradient); {% else %}
color: #fff; {% set monday = today_at() - timedelta(days=wd) %}
border: none; {% endif %}
border-radius: var(--cc-radius-brand); {% set friday = monday + timedelta(days=4) %}
box-shadow: var(--cc-shadow-brand); # School Lunch Menus
padding: 6px 12px; ## {{ monday.strftime("%b %-d") }} {{ friday.strftime("%b %-d, %Y") }}
text-align: center; card_mod:
} style: |
ha-card h1 { ha-card {
margin: 0; background: var(--cc-gradient);
font-size: 1rem; color: #fff;
font-weight: 600; border: none;
letter-spacing: 0.02em; border-radius: var(--cc-radius-brand);
opacity: 0.85; box-shadow: var(--cc-shadow-brand);
color: #fff; padding: 6px 12px;
} text-align: center;
ha-card h2 { }
margin: 2px 0 0 0; ha-card h1 {
font-size: 1.5rem; margin: 0;
font-weight: 800; font-size: 1rem;
letter-spacing: -0.01em; font-weight: 600;
color: #fff; letter-spacing: 0.02em;
} opacity: 0.85;
color: #fff;
}
ha-card h2 {
margin: 2px 0 0 0;
font-size: 1.5rem;
font-weight: 800;
letter-spacing: -0.01em;
color: #fff;
}
- type: calendar - type: grid
title: BHS Lunch Menu columns: 3
initial_view: listWeek square: false
entities: cards:
- calendar.bhs_lunch_menu - type: markdown
card_mod: &cc_calendar title: BHS Lunch Menu
style: | entity_id: sensor.bhs_lunch_menu_week
ha-card { content: |
--calendar-day-color: var(--cc-text, var(--primary-text-color)); {% set events = state_attr('sensor.bhs_lunch_menu_week', 'events') or [] %}
--calendar-day-weekday-color: var(--cc-text-muted, var(--secondary-text-color)); {% if events is string %}{% set events = [] %}{% endif %}
--fc-today-bg-color: var(--cc-accent-soft); {% set wd = now().weekday() %}
--fc-event-bg-color: var(--cc-accent); {% if wd >= 5 %}
--fc-event-border-color: var(--cc-accent); {% set monday = today_at() + timedelta(days=(7 - wd)) %}
} {% else %}
{% set monday = today_at() - timedelta(days=wd) %}
{% endif %}
{% for offset in range(5) %}
{% set d = (monday + timedelta(days=offset)).date() %}
{% set d_str = d.isoformat() %}
{% set ns = namespace(found=false) %}
### {{ d.strftime("%A") }}
{{ d.strftime("%b %-d") }}
{% for e in events if e.start is defined and e.start[:10] == d_str %}
{% set ns.found = true %}
- {{ e.summary }}
{% endfor %}
{% if not ns.found %}
_No menu listed_
{% endif %}
- type: calendar {% endfor %}
title: BIS School Lunches card_mod: &cc_menu
initial_view: listWeek style: |
entities: ha-card .card-header {
- calendar.bis_school_lunches color: var(--cc-text, var(--primary-text-color));
card_mod: *cc_calendar font-weight: 700;
}
ha-markdown {
padding-top: 0 !important;
}
ha-markdown h3 {
margin: 0.85rem 0 0.15rem 0;
font-size: 1rem;
font-weight: 700;
color: var(--cc-accent, var(--primary-color));
}
ha-markdown h3:first-child {
margin-top: 0;
}
ha-markdown p {
margin: 0 0 0.35rem 0;
color: var(--cc-text-muted, var(--secondary-text-color));
font-size: 0.85rem;
}
ha-markdown ul {
margin: 0 0 0.5rem 0;
padding-left: 1.1rem;
}
ha-markdown li {
margin: 0.15rem 0;
color: var(--cc-text, var(--primary-text-color));
}
ha-markdown em {
color: var(--cc-text-muted, var(--secondary-text-color));
}
- type: calendar - type: markdown
title: HMS Lunch Menu title: BIS School Lunches
initial_view: listWeek entity_id: sensor.bis_lunch_menu_week
entities: content: |
- calendar.hms_lunch_menu {% set events = state_attr('sensor.bis_lunch_menu_week', 'events') or [] %}
card_mod: *cc_calendar {% if events is string %}{% set events = [] %}{% endif %}
{% set wd = now().weekday() %}
{% if wd >= 5 %}
{% set monday = today_at() + timedelta(days=(7 - wd)) %}
{% else %}
{% set monday = today_at() - timedelta(days=wd) %}
{% endif %}
{% for offset in range(5) %}
{% set d = (monday + timedelta(days=offset)).date() %}
{% set d_str = d.isoformat() %}
{% set ns = namespace(found=false) %}
### {{ d.strftime("%A") }}
{{ d.strftime("%b %-d") }}
{% for e in events if e.start is defined and e.start[:10] == d_str %}
{% set ns.found = true %}
- {{ e.summary }}
{% endfor %}
{% if not ns.found %}
_No menu listed_
{% endif %}
{% endfor %}
card_mod: *cc_menu
- type: markdown
title: HMS Lunch Menu
entity_id: sensor.hms_lunch_menu_week
content: |
{% set events = state_attr('sensor.hms_lunch_menu_week', 'events') or [] %}
{% if events is string %}{% set events = [] %}{% endif %}
{% set wd = now().weekday() %}
{% if wd >= 5 %}
{% set monday = today_at() + timedelta(days=(7 - wd)) %}
{% else %}
{% set monday = today_at() - timedelta(days=wd) %}
{% endif %}
{% for offset in range(5) %}
{% set d = (monday + timedelta(days=offset)).date() %}
{% set d_str = d.isoformat() %}
{% set ns = namespace(found=false) %}
### {{ d.strftime("%A") }}
{{ d.strftime("%b %-d") }}
{% for e in events if e.start is defined and e.start[:10] == d_str %}
{% set ns.found = true %}
- {{ e.summary }}
{% endfor %}
{% if not ns.found %}
_No menu listed_
{% endif %}
{% endfor %}
card_mod: *cc_menu
+62
View File
@@ -0,0 +1,62 @@
################################################################################
# lunch_menus.yaml
#
# Pulls MonFri of the current school week from each lunch Google Calendar into
# template sensors. On Sat/Sun, advances to next week's Monday. The Lunch Menus
# dashboard renders those attributes — the stock calendar card has no school-
# week view.
################################################################################
template:
- trigger:
- platform: time_pattern
minutes: "/15"
- platform: homeassistant
event: start
- platform: event
event_type: event_template_reloaded
action:
- variables:
# weekday(): Mon=0 … Sun=6. Weekend → next Monday.
school_monday: >-
{% set wd = now().weekday() %}
{% if wd >= 5 %}
{{ (today_at() + timedelta(days=(7 - wd))).isoformat() }}
{% else %}
{{ (today_at() - timedelta(days=wd)).isoformat() }}
{% endif %}
- action: calendar.get_events
target:
entity_id:
- calendar.bhs_lunch_menu
- calendar.bis_school_lunches
- calendar.hms_lunch_menu
data:
start_date_time: "{{ school_monday }}"
duration:
days: 5
response_variable: agenda
sensor:
- name: "BHS Lunch Menu Week"
unique_id: bhs_lunch_menu_week
icon: mdi:food-apple
state: "{{ agenda['calendar.bhs_lunch_menu'].events | count }}"
attributes:
events: "{{ agenda['calendar.bhs_lunch_menu'].events }}"
week_start: "{{ school_monday }}"
- name: "BIS Lunch Menu Week"
unique_id: bis_lunch_menu_week
icon: mdi:food-apple
state: "{{ agenda['calendar.bis_school_lunches'].events | count }}"
attributes:
events: "{{ agenda['calendar.bis_school_lunches'].events }}"
week_start: "{{ school_monday }}"
- name: "HMS Lunch Menu Week"
unique_id: hms_lunch_menu_week
icon: mdi:food-apple
state: "{{ agenda['calendar.hms_lunch_menu'].events | count }}"
attributes:
events: "{{ agenda['calendar.hms_lunch_menu'].events }}"
week_start: "{{ school_monday }}"