patch_beacons_json/2 and remove_from_beacons_json/2 were calling
Enum.reject/2 directly on @beacons_json, which is a JSON-encoded
string from Jason.encode!/0 (not a list). This crashed with
Protocol.UndefinedError when no approved beacons existed (string
was "[]") and a PubSub broadcast triggered an update.
Decode with Jason.decode!/1, operate on the list, then re-encode
with Jason.encode!/1 so the template's data-beacons attribute
remains a valid JSON string for the JS hook.