internetarchive / internetarchive/openlibrary

Epic: 'Build your library' Experience on My Books Page

Open
#13,255 4 comments 0 reactions 0 assignees View on GitHub
Affects: Data Affects: Server Affects: UI Lead: @mekarpeles Module: CSS Module: JavaScript Needs: Designs Needs: Staff Decision Priority: 2 Type: Epic
Dominant language
Python
Stars
6.7k
Forks
2k
Avg merge
2d 19h
Merged PRs (30d)
138

Description

# Epic: "Build your library" Experience on My Books Page

## Summary

A new patron's first visit to My Books is a blank slate — the empty-room equivalent of walking into a library with no books. We know populated shelves drive engagement and retention, but right now we actively work against that: import is buried, and most patrons never learn the feature exists at signup. This Epic replaces the empty state with an encouraging **"Build your library"** onboarding banner at the top of My Books, linking out to three low-friction cataloging workflows built or revamped as part of this work.

Image

This is a planning/implementation issue, not a single PR — it's split below into five independently mergeable PRs so nothing ships as a broken or empty placeholder page. **Close this issue once all five PRs below are merged and the banner is live on My Books.**

```mermaid
graph TD
PR1[PR 1: Import/Export UI Splitting] --> PR4[PR 4: Goodreads Match Resolution]
PR2[PR 2: Find Your First Book Explorer] --> PR5[PR 5: Build Your Library Banner & Integration]
PR3[PR 3: Mass Barcode Scanner Upgrade] --> PR5
PR4 --> PR5
```

## Checklist

**1. Import/Export UI Splitting** (self-contained refactor) — separates the tangled `/account/import` and `/account/export` routes/menus into dedicated screens. Low risk: export keeps working exactly as it does today, import gets its own view and controller, and no Goodreads CSV parsing logic changes yet. This is the foundation PR 4 builds on.
- Create a page dedicated solely to **Importing** (Goodreads, etc.).
- Create a separate page/tab dedicated to **Exporting** data (reading logs, notes, reviews, lists, ratings).
- Target files: `openlibrary/templates/account/import.html` (import-only), `openlibrary/templates/account/export.html` [NEW], `openlibrary/plugins/upstream/account.py` (split route handlers).

**2. "Find your first book" Explorer Page** — a standalone discovery entry point patrons can reach directly (link, search suggestion) independent of the onboarding banner, so it can ship and be useful on its own before PR 5 wires it in.
- Browse-by-genre grid of book covers, in the style of standard library explorers.
- Mass-add UI: book cards carry a prominent "Add to bookshelf" dropdown/button directly on the card, no redirect to the book details page required.
- Central, prominent search bar built on the new search autocomplete component, optimized for rapid multi-book adds.
- Target files: `openlibrary/templates/my_books/explore.html` [NEW], `openlibrary/plugins/upstream/mybooks.py` (new controller/routes), `openlibrary/plugins/openlibrary/js/my-books/` (new explorer components).

**3. Mass Barcode Scanner Upgrade** (self-contained) — the `/barcodescanner` camera view already exists in beta; this upgrades it to continuous scanning instead of redirecting after a single detection, an isolated frontend change.
- Interaction loop: scan barcode → a lazy card pops up under the viewport with confirmation/status (e.g. "Added to Want to Read" or "ISBN Unavailable") → camera stays active → patron scans the next barcode.
- Embed shelf/bookshelf-dropper buttons directly inside each scanned card so patrons can scan, add, and keep scanning without leaving the view.
- Target files: `openlibrary/components/BarcodeScanner.vue` (continuous scan loop + inline feedback), `openlibrary/components/BarcodeScanner/components/LazyBookCard.vue` (embedded shelf buttons).

**4. Revamped Goodreads Match Resolution Flow** — builds directly on the clean `/account/import` template from PR 1, so it's gated on that merging first.
- Wizard interface following the latest Goodreads import mockups.
- Interactive resolution screen handling common edge cases gracefully: books not found in Solr, edition mismatches, custom matching configuration.
- Let patrons preview and customize target shelves (want-to-read, already-read, etc.) before running the import.
- Target files: `openlibrary/templates/account/import.html`, import parser + resolution-table logic (new).

**5. "Build your library" Landing Banner & Integration** (Major PR — merges only after PRs 1–4 are stable in production) — ties the three onboarding channels together on My Books.
- Empty-state detection: patron's shelves (want-to-read, currently-reading, already-read, stopped-reading) are all at 0 books.
- Banner renders on both desktop and mobile with a milestone progress bar (e.g. `0 / 20 books`, step-dot style) motivating patrons toward unlocking personalized recommendations.
- Three action cards inside the banner: **Search your first book** (→ Explorer, PR 2), **Import Goodreads library** (→ split import + resolution flow, PRs 1/4), **Scan barcodes (ISBN)** (→ mass scanner, PR 3).
- Target files: `openlibrary/templates/account/mybooks.html` (shelf-count check + conditional rendering), `openlibrary/plugins/upstream/mybooks.py` (backend checks/metrics for empty accounts), `static/css/components/library-builder.css` [NEW].

## Next steps

- PR 1 (Import/Export split), PR 2 (Explorer), and PR 3 (Barcode scanner) have no dependencies on each other and can be worked in parallel.
- PR 4 (Goodreads match resolution) is gated on PR 1 merging first — it builds on the split `/account/import` template.
- PR 5 is gated on PRs 1–4 all being stable in production, so all three onboarding channels ("Explore", "Import", "Scan") work flawlessly before they're surfaced together in the banner.
- Close this issue once PR 5 is merged and the banner is confirmed live with milestone tracking working end to end.

## Engineering Standards

- **Python**: double quotes, max line length 162, Ruff-compliant import order.
- **JS**: ESLint-compliant, single quotes, no jQuery in new components.
- **CSS**: Stylelint-compliant — no hex colors, use variables defined in `static/css/`.
- **i18n**: don't split sentences into separate translatable fragments around HTML links. Use single translatable strings with placeholders (e.g. `%(link_start)s` / `%(link_end)s`) so translators can reposition links per target-language grammar.

Contributor guide

Open the contributing guide

Research direction

Treat this as an epic rather than a single starter task, and choose one independently mergeable PR from its checklist. Begin with the named target files for that PR, verify its dependencies and existing tests or routes, and use the corresponding checklist item and acceptance details as the definition of done.

Written by the indexing model from the issue text.

Assessment

Tech stack
css, javascript, python
Domain
backend, frontend, full-stack
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.