Overall rating is five clickable stars (real radio buttons underneath, so
the keyboard works) with a Clear button, in place of a select.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Moving a planting between gardens isn't part of quick editing. The
dialog no longer asks, or sends, which garden.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Three dots > Edit opens the planting's form in a modal instead of going to
the edit page. It saves as JSON and swaps in the refreshed garden card, so
the page is never left. Ctrl/cmd-click still opens the edit page.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The date on an annual planting row is a button with a pencil hint for
plantings the viewer can edit. It opens the browser's date picker, saves
with the tick or Enter, and swaps in the refreshed card so predictions
follow the new date.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
PATCH /plantings/:slug.json now returns the garden's refreshed card, as
create does, or the validation errors as 422. Annual plantings in the
card say whether the viewer can edit them.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The round three-dots toggle was scoped to .planting-row. Move it to a
generic .actions-toggle-dots so other menus can reuse it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A planting can now choose one of its crop's alternate names (eg. "lauki"
for calabash, "aubergine" for eggplant) and shows it instead of the
crop's primary name.
- plantings.alternate_name_id, validated to belong to the planting's crop
- Planting#display_name, used on cards, the planting page, garden lists,
the member page, the homepage and the RSS/ICS feeds
- planting form offers the crop's alternate names, preselecting the one
that was searched for
- crop autosuggest shows the matched alternate name, eg.
"aubergine (eggplant)", via matched_alternate_name in the search JSON
Part of #554
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bootstrap 5's chevron is a border triangle, so width: 100% stretched it into
a bar. The grid for icon, label and chevron also applied to the sign in and
sign up buttons, squeezing their labels into the icon column.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
list-group-item outside a .list-group has no background or border in
Bootstrap 5.3, as those come from variables set on .list-group. Wrap the
homepage lists and the planting page neighbours in one, white with a light
shadow.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The border was too faint to see, and Bootstrap 5 floated the checkbox to the
left edge of centred forms, away from its label.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bootstrap 5 picked black text for the old #2196f3 on text-bg-info badges
and btn-info buttons, where the site had white. #1976d2 gets white text at
4.6:1, which also passes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
It was a solid green active list item holding a green link. Use the light
list item, as the other sign in bars are.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
%badge.text-bg-warning was a <badge> element with a colour and no Bootstrap
badge styling, so it rendered as plain text.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A .dropdown-divider and a dropdown-item Delete link sat in the page body, outside
any dropdown, duplicating the Delete in the Actions menu. With the menu open the
page has two visible Delete links, and the 'Delete garden' spec, which clicks
'Actions' and then 'Delete', finds both. The Actions menu already has the
garden's Delete.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Typing a scientific name makes the page ask GBIF for suggestions after
jQuery UI's 300ms delay. Whether that request lands before Save navigates away
is a race the test only usually won, and when it lost, VCR blocked the real
request and failed the spec. Answer the suggestion with a double instead.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
In Bootstrap 5 the close button has an auto left margin, so before the
title it sat beside it instead of at the right edge.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
--bs-secondary is the site's dark blue here, so finished plantings had a
blue bar rather than the grey the progress colours call for.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
'.= f.submit' is not valid Haml, so the page raised a syntax error. Add a
request spec that renders it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
/api/v1/activities is the single busiest route in production: 216 of 1101
requests in a 14 minute log window, 19.6% of all traffic and 21.7% of
non-asset traffic. It was the only high-volume route with no rate limit,
since the throttle matched plantings, harvests and members only.
Collapses the two alternations into one regex with an optional /api/v1
prefix, so the HTML and API routes stay in step instead of being listed
twice. Verified equivalent to the old pair across both route families
plus their edge cases: /plantingsfoo, /memberships, /foo/plantings and
/api/v2/activities are still unmatched.
Note this does not by itself stop the client currently polling that
endpoint. It makes 189 requests over 21 minutes, about 9 per minute,
which is under the 15 per minute limit, and Rack::Attack counters live
in per-worker memory so at WEB_CONCURRENCY=2 each worker sees only half
of them. This closes the hole rather than fixing today's load.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The free Memcachier dev plan is timing out on every call in production
(58 IO::TimeoutError in a 14 minute log window). Each request pays the
0.5s socket timeout and then renders uncached anyway, so the cache is
currently pure overhead on a dyno that is already being OOM-killed.
Memcached is now used only when USE_MEMCACHED=true and MEMCACHIER_SERVERS
is present. Otherwise production uses a memory store capped at 32MB via
RAILS_CACHE_SIZE_MB, so deploying restores real caching without the
timeouts and without an addon upgrade.
The memory store is per process, so homepage_stats gets an expires_in to
bound staleness. It is the only fragment that relies on expire_fragment
rather than a versioned cache key.
Sessions are cookie-based and every other cached value is either keyed by
cache_key_with_version or carries a TTL, so nothing depends on the cache
being shared between processes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blue while growing, green while harvesting, amber when late, red when very
late, grey when finished. The track is now neutral grey so every colour
reads against it. Planting#progress_state decides, and the garden cards,
planting progress and timeline bars use it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bootstrap 5 buttons are flat with a border. Draw them as the old skin did:
no border, a Material shadow that deepens while pressed, 2px corners,
medium weight and uppercase. Link buttons stay plain. A bare .btn is drawn
raised with dark text instead of borrowing the outline style.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The card always rendered a .card-body and a .card-footer. A seed with no details
left them empty, and Bootstrap 5 pads them into white bars under the photo. Draw
each only when it has something in it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bootstrap 5 makes the text of a .badge white; Bootstrap 4 left it alone. The like
button's heart and count sit in a bare badge on a pale button, so they were white
on light grey. Set $badge-color to inherit, as before.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The chips were solid brown-grey pills with white text, so a row of crops read as a
row of dark blobs, and they competed with the blue status badges. Use Bootstrap
5.3's subtle success colours instead: a light green fill and border with dark
green text.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
_variables.scss still set $progress-height: 5em, $progress-bar-color and
$progress-bg: white, Bootstrap 3 variables the old skin ignored. Bootstrap 5
reads them, which made every progress bar 52px tall with an invisible white
track. Set the height to 0.875rem (as the old bar was), the track to a lighter
green and the bar to the site green, and drop the border-bottom trick that drew
the old bar.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bootstrap's dark navbar draws menu links at 55% white, which on the brown navbar
is 4.47:1, just under the 4.5:1 minimum. Use 85% white (white on hover). The
breadcrumb links were grey in the old skin and are now the link green, 4.12:1 on
the beige page; make them a darker grey again.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bootstrap 5's cards have a thin border, a grey header and a transparent body, so
the page background showed through. Set the card variables to white, no border,
a 2px radius and the old three-layer shadow, and keep the line under the header.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The cards from #4808 still used Bootstrap 4 names: .close with a times sign
(now .btn-close), sr-only (now visually-hidden), badge-info (now text-bg-info),
and dropdown-menu-right next to dropdown-menu-end (only -end is needed).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Updated config/environments/production.rb to set config.log_level using
ENV.fetch("RAILS_LOG_LEVEL", "info").to_sym. This prevents excessive SQL
query logging in production by default while allowing configuration via
the RAILS_LOG_LEVEL environment variable.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>