Skip to content

feat: add bookmarks to events and bookmark page - #5

Merged
flvvius merged 3 commits into
mainfrom
feat/2.2-bookmarks
Feb 28, 2026
Merged

feat: add bookmarks to events and bookmark page#5
flvvius merged 3 commits into
mainfrom
feat/2.2-bookmarks

Conversation

@flvvius

@flvvius flvvius commented Feb 28, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Event bookmarking across the platform with visual saved-state indicators and size/accessibility options.
    • Bookmark buttons added to event cards and event detail headers; show toasts for success/failure and disable during actions.
    • New Bookmarks page (authenticated view, loading/empty states) accessible from the header to view and manage saved events.
    • Backend support for toggling, querying, and listing bookmarks plus interaction logging.

@vercel

vercel Bot commented Feb 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
news-web Ready Ready Preview, Comment Feb 28, 2026 2:40pm

@coderabbitai

coderabbitai Bot commented Feb 28, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f562713 and b060b14.

📒 Files selected for processing (3)
  • apps/web/src/components/bookmark-button.tsx
  • packages/backend/convex/interactions.ts
  • packages/backend/convex/schema.ts

Walkthrough

Adds a bookmark feature: UI button and page, client-side integration with Convex queries/mutations, and backend interaction/schema changes to store and query user bookmarks and interactions.

Changes

Cohort / File(s) Summary
Bookmark UI
apps/web/src/components/bookmark-button.tsx
New BookmarkButton component with isEventBookmarked query, toggleBookmark mutation, auth gating, click debounce, toasts, disabled state during mutation, aria attributes, and size variant.
Event UI Integration
apps/web/src/components/feed/event-card.tsx, apps/web/src/routes/event.$slug.tsx
Inserted BookmarkButton into event card and event detail header, grouped with article count/title for layout alignment.
Navigation & Page Route
apps/web/src/components/header.tsx, apps/web/src/routes/bookmarks.tsx
Added "Bookmarks" nav item and new /bookmarks route with auth gating, BookmarksContent that fetches getBookmarkedEvents, empty/loading states, and event list rendering.
Backend: Convex interactions
packages/backend/convex/interactions.ts
New server-side APIs: toggleBookmark, isEventBookmarked, getBookmarkedEvents, logInteraction — include auth checks, deduplication/cooldown logic, and enriched bookmarked event responses.
Backend: Schema / Indexes
packages/backend/convex/schema.ts
Added "unbookmark" interaction type and two composite indexes: by_user_type (userId, type) and by_user_event_type (userId, eventId, type) to support interaction queries.

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as BookmarkButton (client)
    participant Auth
    participant Convex as Convex API
    participant DB as Database

    User->>UI: Click bookmark icon
    UI->>Auth: Ensure authenticated
    alt unauthenticated
        Auth->>User: Prompt sign-in
    else authenticated
        UI->>Convex: toggleBookmark(eventId)
        Convex->>DB: Read recent interactions for user/event
        alt recent toggle found
            Convex->>DB: Insert patch entry (unbookmark/bookmark)
        else no recent toggle
            Convex->>DB: Insert new bookmark interaction
        end
        Convex-->>UI: {bookmarked: true|false}
        UI->>Convex: invalidate/refresh isEventBookmarked query
        Convex->>DB: Query latest bookmark state
        Convex-->>UI: updated status
        UI->>User: Update icon, aria-pressed, show toast
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: adding bookmark functionality to events and a dedicated bookmarks page.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/2.2-bookmarks

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/components/bookmark-button.tsx`:
- Line 72: The ternary in the BookmarkButton component is redundant—both
branches return "icon"—so replace size={size === "sm" ? "icon" : "icon"} with a
single explicit value or the actual prop: if the control should always be the
icon size, use size="icon"; if it should vary with the incoming prop, use
size={size} (or map size to the correct tokens). Update the occurrence in
bookmark-button.tsx (the component using the size prop) accordingly.

In `@packages/backend/convex/interactions.ts`:
- Around line 115-121: The query that builds bookmarks
(ctx.db.query("interactions").withIndex("by_user_type", q => q.eq("userId",
user._id).eq("type", "bookmark")).order("desc").collect()) relies on Convex's
default ordering by _creationTime for the descending/newest-first result; add a
concise inline comment next to this call (or above where bookmarks is defined)
stating that .order("desc") orders by _creationTime (newest first) so future
readers know this is implicit and intentionally used.
- Around line 10-11: The function requireUserId currently types ctx as any;
replace that with the proper Convex server context type and remove the cast when
calling authComponent.safeGetAuthUser: import the appropriate Convex context
type (e.g., QueryContext or MutationContext) from "convex/server" and change the
signature to async function requireUserId(ctx: QueryContext) (or MutationContext
/ a union that matches where this function is used), or if
authComponent.safeGetAuthUser requires extra fields, declare a small interface
(e.g., interface AuthCtx extends QueryContext { auth: AuthType }) and use that
type for ctx; then call authComponent.safeGetAuthUser(ctx) without the as any
cast so TypeScript enforces correctness for requireUserId and
authComponent.safeGetAuthUser.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd67269 and f562713.

⛔ Files ignored due to path filters (2)
  • apps/web/src/routeTree.gen.ts is excluded by !**/routeTree.gen.ts
  • packages/backend/convex/_generated/api.d.ts is excluded by !**/_generated/**, !**/_generated/**
📒 Files selected for processing (7)
  • apps/web/src/components/bookmark-button.tsx
  • apps/web/src/components/feed/event-card.tsx
  • apps/web/src/components/header.tsx
  • apps/web/src/routes/bookmarks.tsx
  • apps/web/src/routes/event.$slug.tsx
  • packages/backend/convex/interactions.ts
  • packages/backend/convex/schema.ts

Comment thread apps/web/src/components/bookmark-button.tsx Outdated
Comment thread packages/backend/convex/interactions.ts Outdated
Comment thread packages/backend/convex/interactions.ts Outdated
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