Inspiration

I walked past the same dead streetlight for four months. Everyone on the street complained about it, nobody knew who to call, and the one neighbor who did call never heard back. That's the real problem, not apathy, but a reporting process that feels like shouting into a void. Existing local-government reporting tools are fragmented from city to city, desktop-shaped, and invisible once you hit submit: you file a report and never learn whether anyone read it. I wanted the opposite, something anyone, anywhere, could use in 30 seconds from a phone with two bars of signal, where every report is public, every neighbor can add weight to it, and every status change is visible to everybody who cared enough to upvote.

What it does

BlockBeacon is a hyper-local, mobile-first map of everyday street/neighborhood problems. Snap and pin. Open the camera, take a photo, drop a pin, pick a category ("Broken streetlight", "Pothole", "Litter") and post. Community validation. Neighbors upvote to signal priority. One vote per person, changeable, never desynced. A visible life cycle. Every report moves through Needs attention → City is looking → Fixed, with timestamps and an audit trail of who changed what. Verified city officials. Moderators sign up with an official work email, pass an AI-assisted document check, and get a verified badge so real city responses stand out from opinions. City-hall handoff. Moderators generate a 311-style referral PDF and email for the most-upvoted issues. When that happens, everyone who upvoted gets notified, and the pin carries an italic note telling the block it's been escalated. Auto-escalation. At 50 upvotes, the community's assigned moderator is notified automatically. Neighbor conversation. Threaded updates per issue ("still broken as of today") plus ephemeral chat rooms that expire on a schedule the opener sets. Global from day one. Country → state → city → street address picker, GPS, and a language dropdown that offers only the 2–3 languages that make sense for the user's country. Light gamification. Leaderboards for top reporters and fastest-fixed issues.

How we built it

Frontend is React 19 on TanStack Start, with TanStack Router and TanStack Query, Vite, TypeScript, and Tailwind. The map is Leaflet with React Leaflet over OpenStreetMap tiles. Backend is Firebase, Firestore for data, Firebase Auth for identity, UploadThing handling storage for photo uploads, Gemini (gemini-3.6-flash) powering photo recognition and autofill and moderator document verification, and Resend/Mailchimp handling outbound email. PDFs are generated in-browser with jsPDF. Geocoding is OpenStreetMap Nominatim.

The app is a TanStack Start project with file-based routes: the authenticated map experience, the report-creation sheet (photo upload, AI autofill, duplicate warning), the issue detail page, and the moderator dashboard and application flow each live in their own route, backed by dedicated Gemini API routes for photo analysis and moderator verification.

Challenges we ran into

Migrating the data layer mid-build was the hard one. The app was written against a SQL-style client, and moving to Firestore meant either rewriting every call site or building a compatibility shim. I built the shim, and then hit Firestore's composite-index requirement: any query combining a filter with a sort demands a pre-declared index, which meant the issue detail page silently hung on "Loading" with a failed-precondition error. The fix was to keep Firestore doing what it's cheap at (equality filters) and do ordering and pagination in memory, since a single issue's photos, votes, and status events are inherently small collections.

SSR hydration was the other recurring trap. Reading localStorage inside a useState initializer produces different HTML on the server and the client, and React discards the whole tree.

Getting anonymity right without breaking accountability also took several passes: a report can be anonymous to neighbors while still being one-vote-per-person and still traceable for moderation.

Accomplishments that we're proud of

An initial load that stays inside a tight budget and works on a weak cellular connection at the exact remote spot where the problem is. Offline capture that genuinely works, take the photo now, submit itself later. AI photo autofill that removes the "what do I even write here" friction from reporting. A moderator pipeline with real document verification instead of an honor-system checkbox. An interface people with no technical background could use without instructions.

What we learned

Civic software fails on trust, not features. The upvote count and the visible status timeline do more for participation than any additional form field. I also learned to treat the network as hostile by default: progress indicators, retries, and offline queues are not polish on a civic app, they are the product.

What's next for BlockBeacon

Ward or district boundaries so moderators only see reports in their assigned area. Stronger background push notification support. Richer duplicate clustering for issues reported many times in slightly different ways. Anonymized open data exports so journalists and researchers can see which blocks get fixed and which get ignored, that pattern is the story. Improved accessibility and a low-bandwidth mode.

Impact statement

BlockBeacon helps the people who are furthest from city hall or authorized decision-makers. A resident with a phone and a weak signal can document a hazard in under a minute; AI helps them describe it and checks it isn't a duplicate; their neighbors can back it with a tap; and a verified official can update or hand it off with a clear public trail instead of a phone tree. The upvote count converts scattered individual complaints into documented community demand, the thing that actually moves local priorities.

Built With

Share this project:

Updates

Submission history