Skip to content

feature/report sighting: multi-step wizard + smart auto-fill - #57

Open
irenecancode wants to merge 5 commits into
mainfrom
feature/multi-step-submission-form
Open

irenecancode wants to merge 5 commits into
mainfrom
feature/multi-step-submission-form

Conversation

@irenecancode

@irenecancode irenecancode commented Jul 9, 2026 •

Copy link
Copy Markdown
Collaborator
report_sighting_before_after

Report Sighting: multi-step wizard + smart auto-fill

Summary

Refactors the single-page "Report a Sighting" form into a guided 5-step wizard (Media → Time & Place → Species → Device & Credit → Preview & Publish), and layers in EXIF-based auto-fill so users have to type less. Frontend/template-only change — no Django views, models, URLs, or migrations touched.

Wizard structure

  • 5 steps behind a progress bar with Back / Next / Publish navigation; steps show/hide via CSS only (no DOM detachment), so the map, media previews, and species rows stay alive across navigation.
  • Per-step required-field validation before advancing, plus a final safety-net check on Publish (native validation skips fields inside hidden ancestors, so earlier hidden steps needed their own re-check).
  • Publish is only a real submit button while on the last step, so Enter in an earlier text field can't trigger an accidental early submit.

Media step

  • Per-file delete button on upload previews (subtle by default, darkens on hover), backed by rebuilding the input's FileList via DataTransfer — a removed file is genuinely gone from what's submitted.
  • Persistent "Media info detected" panel showing what EXIF actually found (camera, date/time, GPS), with a friendly fallback message when no location tag exists.

EXIF auto-fill (camera model, GPS, date/time)

  • Fixed a real bug where Nikon-style EXIF (Make: "NIKON CORPORATION", Model: "NIKON D3500") rendered as duplicated text.
  • Each auto-filled field tracks whether its value came from EXIF or the user, so removing the source photo cleanly resets it (fixing the originally reported stale-data bug), and any deliberate user action takes ownership so EXIF can never overwrite it again.
  • If EXIF finds a date, the fields lock (read-only, visibly darkened) and "Use Current Date/Time" hides — a wrong camera clock is corrected via Timestamp Offset instead. No date found → fields stay blank/editable.
  • Apple's Make tag auto-selects "Phone"; a localStorage-based memory (no backend field exists for this) recalls device type per camera model to cut repeat clicks.

Time & Place

  • "Saved Location" / "New Location" toggle, defaulting to whichever makes sense for the account, without overriding a deliberate user choice.
  • New Location supports naming + "save for next time," persisted through the existing saved-locations API.

Species

  • "I'm not sure what species this is" opt-out, placed after the species rows so identification is tried first.

Device & Credit

  • Device type selector (Camera/Phone/Home Camera/Trail Camera); deployment date + saved-device follow-ups only for the two installed types.
  • All four device types can now save a new device (previously Home/Trail Camera only).
  • Auto-recognizes an already-saved device by camera-model match and switches modes automatically; hides the redundant Camera Model field when reusing a saved device.
  • Reordered to: What captured this sighting? → Device Source → Camera Model → License, with save/deployment fields after License.

Preview & Publish

  • Redesigned into a feed-style card matching the site's sighting-feed look: media on top (video badge + play button for video), Title/Description edited inline, byline, location, compact meta line.
  • Divider added between Public Setting/Display Name and Obfuscation Radius/Location Accuracy.
  • km/m vs. mi/ft display toggle for those two fields — submitted values stay in the metric units the backend expects; only the display converts.

Explicit non-goals for this branch

  • No analytics/tracking added yet. Mapped ~30 candidate tracking points (funnel drop-off, EXIF hit rate, auto-fill override rate, opt-in rates, etc.) but held off pending a decision on tooling (likely GA4 or PostHog, both free at expected volume) — planned for a follow-up branch.
  • No video EXIF extraction — only image EXIF is parsed; video-only uploads fall into the "nothing detected" path.

Test plan

  • Full 5-step walkthrough with a photo carrying full EXIF (camera, GPS, date/time) — confirm auto-fill + locked date/time + detection panel.
  • Walkthrough with a photo lacking EXIF (e.g. screenshot) — fields stay blank/editable, fallback copy shows.
  • Upload → delete → upload a different photo — confirm no stale camera/location/date data lingers.
  • Toggle Saved/New Location and Device Source (New/Saved) both directions.
  • Save a new location and a new device; confirm they appear as "saved" on a subsequent report.
  • Submit with a Public Setting option; confirm Obfuscation Radius/Location Accuracy show/hide and unit toggle round-trips correctly.
  • Confirm Expert Bulk Upload (is_expert=True) still works unaffected.
  • python manage.py check + direct template render (done throughout dev; re-verify before merge).
Step 1 Step 2 Step 3 Step 4 Step 5

@irenecancode

Copy link
Copy Markdown
Collaborator Author

Follow-up tracked separately: device_type is UI-only on this branch — it routes which follow-up fields show, but no backend field exists so it isn't persisted. (camera_model and camera_deployment_date do persist and are unaffected.)

Will open a backend PR to add device_type to MediaPost alongside camera_model -- Home vs. Trail Camera in particular isn't recoverable from camera_model alone. Web-side is then a one-line passthrough in sightings/views.py.

Keeping it out of this PR so the frontend work isn't blocked on a migration.

irenecancode and others added 2 commits July 20, 2026 14:01
Passthrough for the new MediaPost.device_type field: the single-sighting
form already renders device-type radios (name="device_type"); forward the
selected value as deviceType so the backend can persist it.

Pairs with WildeBackyardBackend: Add device_type to MediaPost.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@irenecancode

Copy link
Copy Markdown
Collaborator Author

Updated privacy policy for the checkbox.

@oldtopos
oldtopos force-pushed the feature/multi-step-submission-form branch from 375ddcb to 2c84a68 Compare August 16, 2026 16:47

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant