Skip to content

Feat/dashboard url management phase 3 4 - #30

Merged
NehanAhmed merged 4 commits into
mainfrom
feat/dashboard-url-management-phase-3-4
Jul 15, 2026
Merged

Feat/dashboard url management phase 3 4#30
NehanAhmed merged 4 commits into
mainfrom
feat/dashboard-url-management-phase-3-4

Conversation

@NehanAhmed

@NehanAhmed NehanAhmed commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added URL creation with custom codes, expiration, scheduling, passwords, tags, collections, and bot blocking.
    • Added bulk URL creation with validation, result summaries, and copy actions.
    • Added URL management with search, filters, sorting, pagination, bulk selection, and deletion.
    • Added URL analytics, visit logs, charts, CSV export, QR code downloads, and link previews.
    • Added reusable copy, status, dialog, pagination, tabs, popover, tooltip, form, table, and selection controls.
  • Documentation
    • Added guidance for Phase 3 and Phase 4 implementation.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@NehanAhmed, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 47 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 519e4fd8-46b4-4237-bef8-137b42ccd5ec

📥 Commits

Reviewing files that changed from the base of the PR and between a7b11d1 and 4057b24.

📒 Files selected for processing (23)
  • README.md
  • apps/api/src/__tests__/index.test.ts
  • apps/dashboard/src/components/copy-button.tsx
  • apps/dashboard/src/components/ui/command.tsx
  • apps/dashboard/src/components/ui/dialog.tsx
  • apps/dashboard/src/components/ui/dropdown-menu.tsx
  • apps/dashboard/src/components/ui/pagination.tsx
  • apps/dashboard/src/components/ui/popover.tsx
  • apps/dashboard/src/components/ui/select.tsx
  • apps/dashboard/src/components/ui/switch.tsx
  • apps/dashboard/src/components/ui/tabs.tsx
  • apps/dashboard/src/components/ui/tooltip.tsx
  • apps/dashboard/src/lib/api.ts
  • apps/dashboard/src/pages/BulkCreatePage.tsx
  • apps/dashboard/src/pages/CreateUrlPage.tsx
  • apps/dashboard/src/pages/UrlDetailPage.tsx
  • apps/dashboard/src/pages/UrlsListPage.tsx
  • docs/API.md
  • docs/PROJECT.md
  • opencode.json
  • phases.md
  • specs/04-fifth-sixth-phase.md
  • specs/qr-caching-time-limited.md
📝 Walkthrough

Walkthrough

The dashboard now includes reusable UI primitives, complete URL creation and bulk creation flows, searchable and filterable URL management, detailed analytics with visits, charts, QR codes, export, and deletion, plus agent configuration and phase specification updates.

Changes

Dashboard UI foundation

Layer / File(s) Summary
Reusable controls and interaction primitives
apps/dashboard/src/components/copy-button.tsx, apps/dashboard/src/components/status-badge.tsx, apps/dashboard/src/components/ui/*
Adds copy feedback, status mapping, command controls, dialogs, popovers, tabs, pagination, tables, form controls, switches, and tooltips.

URL creation and management

Layer / File(s) Summary
Single and bulk URL creation
apps/dashboard/src/pages/CreateUrlPage.tsx, apps/dashboard/src/pages/BulkCreatePage.tsx
Adds validated forms, API submission, tags, collections, scheduling, bot blocking, bulk validation, result summaries, and copy/navigation actions.
URL listing and deletion
apps/dashboard/src/pages/UrlsListPage.tsx
Adds paginated URL loading, query-synchronized filters, sorting, row selection, copy actions, and soft deletion with confirmation.
URL details and analytics
apps/dashboard/src/pages/UrlDetailPage.tsx
Adds metadata, visits, statistics, charts, CSV export, QR generation, preview content, and deletion controls.

Project configuration and specification

Layer / File(s) Summary
Agent configuration normalization
opencode.json
Removes root and per-agent model overrides and reformats the MCP remote configuration.
Phase implementation specification
specs/03-third-fourth-phase.md
Adds implementation and design constraints for Phases 3 and 4.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant UrlsListPage
  participant URL API
  participant Dialog
  User->>UrlsListPage: apply filters or open row action
  UrlsListPage->>URL API: fetch filtered URL data
  URL API-->>UrlsListPage: paginated URLs and metadata
  User->>Dialog: confirm deletion
  Dialog->>UrlsListPage: confirm action
  UrlsListPage->>URL API: soft-delete URL
  URL API-->>UrlsListPage: deletion result
  UrlsListPage->>URL API: refresh URL list
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: dashboard URL management work for phases 3 and 4.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dashboard-url-management-phase-3-4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 17

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (10)
apps/dashboard/src/pages/UrlDetailPage.tsx-97-99 (1)

97-99: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Bind the download format to the generated QR result.

After generating PNG, changing the selector to SVG leaves the PNG blob displayed but downloads it with an .svg extension. Store { url, format } together and revoke replaced object URLs during cleanup.

Also applies to: 168-175, 582-589, 611-620

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/pages/UrlDetailPage.tsx` around lines 97 - 99, Update the
QR result state and generation flow around qrDataUrl, qrFormat, and setQrDataUrl
to store the generated object URL together with its actual format, and use that
stored format when naming downloads instead of the current selector value.
Revoke replaced object URLs when updating the result and revoke the final URL
during component cleanup, while preserving the existing display behavior.
apps/dashboard/src/pages/UrlDetailPage.tsx-580-598 (1)

580-598: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Associate the QR labels with their controls.

Add matching htmlFor/id values so assistive technology announces the Format and Logo URL labels.

Proposed fix
-<label className="text-xs font-medium text-muted-foreground">Format</label>
+<label htmlFor="qr-format" className="text-xs font-medium text-muted-foreground">Format</label>
 <select
+  id="qr-format"
   value={qrFormat}

-<label className="text-xs font-medium text-muted-foreground">Logo URL (optional)</label>
+<label htmlFor="qr-logo" className="text-xs font-medium text-muted-foreground">Logo URL (optional)</label>
 <input
+  id="qr-logo"
   value={qrLogo}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/pages/UrlDetailPage.tsx` around lines 580 - 598, Associate
the Format and Logo URL labels with their controls by adding matching htmlFor
attributes and unique id attributes to the corresponding select and input
elements in the QR settings form. Update only the controls surrounding qrFormat
and qrLogo, preserving their existing behavior.
apps/dashboard/src/components/copy-button.tsx-16-30 (1)

16-30: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Handle fallback copy failures
document.execCommand("copy") can return false, but this branch still marks the copy as successful. Wrap the temporary input cleanup in finally and only set copied when the command actually succeeds.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/components/copy-button.tsx` around lines 16 - 30, Update
handleCopy’s fallback branch to check the boolean result of
document.execCommand("copy") before calling setCopied(true) and scheduling the
reset. Ensure the temporary input is always removed with cleanup in a finally
block, including when the fallback command fails or throws.
apps/dashboard/src/components/ui/select.tsx-7-20 (1)

7-20: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Merge caller styles without dropping the select arrow styles. Move style ahead of {...props} and merge it into the existing inline styles; otherwise any caller-supplied style will replace backgroundImage, positioning, and paddingRight.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/components/ui/select.tsx` around lines 7 - 20, Update the
select component’s inline style handling in the forwarded-ref render function:
destructure the caller’s style from props or otherwise place it before the prop
spread, then merge it with the existing arrow styles so caller properties are
preserved without replacing backgroundImage, backgroundPosition, or
paddingRight.
apps/dashboard/src/pages/UrlDetailPage.tsx-230-235 (1)

230-235: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Avoid nesting <Button> inside <Link>
Button renders a native <button>, so this pattern creates nested interactive elements. Use the link itself styled like a button, or add asChild support before composing it this way.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/pages/UrlDetailPage.tsx` around lines 230 - 235, Update
the Settings navigation in UrlDetailPage to avoid wrapping the Button component
in a Link. Use the link itself with button styling, or use Button’s asChild
support if available, while preserving the existing `/urls/${code}/settings`
destination, outline variant, small size, icon, and label.
apps/dashboard/src/components/ui/pagination.tsx-73-85 (1)

73-85: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Give the page-size selector an accessible name.

The adjacent “Show” text is not associated with the <select>. Wrap both in a <label> or add aria-label="Results per page".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/components/ui/pagination.tsx` around lines 73 - 85, Update
the page-size selector in the pagination component so it has an accessible name,
either by associating the adjacent “Show” text through a label or by adding the
specified aria-label to the select. Preserve the existing pageSize value and
onPageSizeChange behavior.
apps/dashboard/src/components/ui/tooltip.tsx-23-39 (1)

23-39: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Expose tooltips on keyboard focus.

Show and hide the tooltip on focus/blur as well as hover, add role="tooltip", and connect it to the trigger with aria-describedby. The current truncated-URL tooltip is mouse-only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/components/ui/tooltip.tsx` around lines 23 - 39, Update
the tooltip component’s trigger container and conditional tooltip element to
support keyboard accessibility: track focus alongside mouse enter/leave in the
existing visibility handlers, add aria-describedby to the trigger referencing a
stable tooltip id, and assign role="tooltip" to the rendered content. Preserve
the current hover behavior and content rendering.
apps/dashboard/src/pages/UrlsListPage.tsx-345-351 (1)

345-351: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Label the selection checkboxes.

Add an accessible name such as “Select all URLs” and Select ${url.code}. Otherwise screen readers announce multiple indistinguishable checkboxes.

Also applies to: 382-388

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/pages/UrlsListPage.tsx` around lines 345 - 351, Add
accessible labels to the selection checkboxes in the URLs table: label the
header checkbox in the select-all control as “Select all URLs,” and label each
row checkbox using the corresponding URL code, such as “Select ${url.code}.”
Update both the header checkbox and row checkbox rendering near the selection
controls without changing their selection behavior.
apps/dashboard/src/pages/CreateUrlPage.tsx-105-107 (1)

105-107: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Enforce the documented custom-code character set.

Values containing spaces or unsupported punctuation pass client validation despite the UI promising only letters, numbers, hyphens, and underscores.

Proposed fix
-    if (form.customCode && (form.customCode.length < 3 || form.customCode.length > 16)) {
-      errs.customCode = "Custom code must be 3-16 characters"
+    if (
+      form.customCode &&
+      (form.customCode.length < 3 ||
+        form.customCode.length > 16 ||
+        !/^[A-Za-z0-9_-]+$/.test(form.customCode))
+    ) {
+      errs.customCode = "Custom code must be 3-16 letters, numbers, hyphens, or underscores"
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/pages/CreateUrlPage.tsx` around lines 105 - 107, Update
the customCode validation in CreateUrlPage to reject any value containing
characters outside letters, numbers, hyphens, and underscores, while preserving
the existing 3–16 character length checks and error behavior.
apps/dashboard/src/components/ui/switch.tsx-8-43 (1)

8-43: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the switch visuals in sync for uncontrolled usage.

SwitchProps still accepts defaultChecked, but the label/thumb classes are driven only by checked. If a caller uses this uncontrolled, the input toggles while the UI stays in the off state. Either track internal checked state or remove defaultChecked from the public props.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/dashboard/src/components/ui/switch.tsx` around lines 8 - 43, The Switch
component’s visual state must update when used with defaultChecked without a
controlled checked prop. Track the input’s internal checked state in the Switch
component, initialize it from checked or defaultChecked, update it in
handleChange, and use that state for the label and thumb classes while
preserving controlled checked behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/dashboard/src/components/ui/command.tsx`:
- Around line 10-23: Update the Command component to make filter, search,
setSearch, and inputRef available to CommandInput, CommandList, and CommandItem
through the existing child communication pattern, so filtering operates
correctly. Stabilize the input focus behavior by preserving one ref across
renders and using it for focus, or remove the unsupported ref API and rely on
autoFocus.

In `@apps/dashboard/src/components/ui/dialog.tsx`:
- Around line 28-41: Update the dialog component around the overlay and inner
element with role="dialog" to add aria-modal and title/description associations
using the dialog’s title and description elements. On open, move focus to an
appropriate element inside the modal; while open, intercept Tab navigation to
cycle focus only among modal descendants, including correct forward and reverse
wrapping. Track the previously focused trigger and restore focus to it when
onClose completes, while preserving the existing overlay-click behavior.

In `@apps/dashboard/src/components/ui/pagination.tsx`:
- Around line 15-22: Replace the O(totalPages) loop that builds pages with a
fixed candidate set containing page 1, totalPages, and the valid neighboring
pages around page, removing duplicates and out-of-range values. Sort the
candidates, then insert "..." between non-consecutive page numbers so the
rendered output remains unchanged without iterating through every page.

In `@apps/dashboard/src/components/ui/popover.tsx`:
- Around line 10-29: Update Popover to provide its open state and setter through
context, then have PopoverTrigger consume that context and toggle the state on
activation. Have PopoverContent consume the same context and render its children
only while open, while preserving controlled and uncontrolled behavior in
Popover and its outside-click handling.

In `@apps/dashboard/src/components/ui/tabs.tsx`:
- Around line 44-48: Implement the complete accessibility behavior across
TabsList, TabsTrigger, and TabsContent: add the tablist, tab, and tabpanel
roles; wire each trigger to its panel with stable matching ids and
aria-controls/aria-labelledby; expose selection with aria-selected; and
implement roving focus with arrow-key navigation while preserving existing tab
behavior. Alternatively, replace these components with a proven accessible tabs
primitive and retain the current API.

In `@apps/dashboard/src/pages/BulkCreatePage.tsx`:
- Around line 180-203: Update the result-row rendering in BulkCreatePage to
display the corresponding original input URL for every result, using
result.index and falling back to the response position when unavailable. Keep
the existing success and failure content, but add the URL beside it so failed
rows can be identified.

In `@apps/dashboard/src/pages/CreateUrlPage.tsx`:
- Around line 309-319: Associate the “Block bots” label with the nested Switch
in the CreateUrlPage block-bots control by adding a matching id and htmlFor, or
provide an aria-label of “Block bots” directly on the Switch.
- Around line 16-22: Update the TTL_PRESETS and associated form
validation/submission logic so the “Never” option, represented by 0, is accepted
consistently with the API contract. Ensure selecting “Never” no longer fails the
minimum-TTL validation while preserving validation for other invalid values.
- Around line 95-103: Centralize strict HTTP(S) normalization in a shared
helper, then update validation and submission flows to reuse its normalized
result. In apps/dashboard/src/pages/CreateUrlPage.tsx lines 95-103, validate
through the helper and allow only http: or https:; in lines 134-135, submit that
normalized value. In apps/dashboard/src/pages/BulkCreatePage.tsx lines 45-52,
normalize each input line with the same helper, and in lines 71-72 send the
previously normalized values without reapplying separate URL rules.
- Around line 127-132: Update the activeAt construction in the form submission
flow to interpret form.activeAt and form.activeTime as local values, create a
local Date from them, and serialize the result with toISOString(). Preserve the
existing midnight fallback when form.activeTime is absent, and avoid appending Z
directly to the local control values.

In `@apps/dashboard/src/pages/UrlDetailPage.tsx`:
- Around line 116-134: Protect the analytics requests in fetchVisits,
fetchStats, and exportVisitsCsv by enforcing the authenticated session token and
backend ownership validation for the short code. Update the corresponding
endpoint handling so unauthorized users cannot access visits, stats, or CSV
exports, while preserving the existing success and error flows for authorized
requests.
- Around line 104-147: Update fetchUrlInfo, fetchVisits, fetchStats, and the
useEffect request flow to use an AbortController per code change, pass its
signal through the corresponding getUrlInfo/getUrlVisits/getUrlStats API calls,
and abort the previous controller during cleanup. Ignore AbortError results and
gate state updates, toasts, navigation, and loading changes to the active
request so stale responses cannot affect the current URL.

In `@apps/dashboard/src/pages/UrlsListPage.tsx`:
- Around line 95-122: Update fetchData and its useEffect to prevent superseded
requests from updating state: use an AbortController or request-generation guard
so only the latest filter request may apply setUrls, setPagination, setTags, and
setCollections. Ensure canceled or stale requests do not trigger toast errors,
loading state is finalized only for the current request, and clean up the
previous request when dependencies change.
- Around line 431-452: The row menu in the URL list creates nested interactive
elements: `DropdownMenuTrigger` wraps a button, and the Settings `Link` wraps a
button-based `DropdownMenuItem`. Update the `DropdownMenuTrigger`, Settings
`Link`, and `DropdownMenuItem` composition so each menu action renders exactly
one final interactive element, using child-slot composition or the primitives’
`asChild` behavior without changing the existing actions.
- Around line 103-111: Update the data-loading flow in UrlsListPage around
listTags and listCollections so all tag and collection options are available
before setTags and setCollections build the filter menus. Page through both
endpoints until all pagination results are collected, preserving the existing
empty-fallback behavior, or replace the loading with server-backed filter
search.

In `@opencode.json`:
- Around line 450-452: Remove the hardcoded x-api-key value from the MCP
configuration block in opencode.json and source it through an
environment-variable or secure secret-management reference instead. Preserve the
remote URL and enabled setting while ensuring the headers configuration resolves
the key at runtime without committing the secret.
- Around line 80-81: Remove the live x-api-key value from the opencode
configuration and load it through an environment variable or secret-store
reference instead. If the subagent model removal near the edit/bash settings is
intentional, update the corresponding model schema documentation in the README
and migration guide to match.

---

Minor comments:
In `@apps/dashboard/src/components/copy-button.tsx`:
- Around line 16-30: Update handleCopy’s fallback branch to check the boolean
result of document.execCommand("copy") before calling setCopied(true) and
scheduling the reset. Ensure the temporary input is always removed with cleanup
in a finally block, including when the fallback command fails or throws.

In `@apps/dashboard/src/components/ui/pagination.tsx`:
- Around line 73-85: Update the page-size selector in the pagination component
so it has an accessible name, either by associating the adjacent “Show” text
through a label or by adding the specified aria-label to the select. Preserve
the existing pageSize value and onPageSizeChange behavior.

In `@apps/dashboard/src/components/ui/select.tsx`:
- Around line 7-20: Update the select component’s inline style handling in the
forwarded-ref render function: destructure the caller’s style from props or
otherwise place it before the prop spread, then merge it with the existing arrow
styles so caller properties are preserved without replacing backgroundImage,
backgroundPosition, or paddingRight.

In `@apps/dashboard/src/components/ui/switch.tsx`:
- Around line 8-43: The Switch component’s visual state must update when used
with defaultChecked without a controlled checked prop. Track the input’s
internal checked state in the Switch component, initialize it from checked or
defaultChecked, update it in handleChange, and use that state for the label and
thumb classes while preserving controlled checked behavior.

In `@apps/dashboard/src/components/ui/tooltip.tsx`:
- Around line 23-39: Update the tooltip component’s trigger container and
conditional tooltip element to support keyboard accessibility: track focus
alongside mouse enter/leave in the existing visibility handlers, add
aria-describedby to the trigger referencing a stable tooltip id, and assign
role="tooltip" to the rendered content. Preserve the current hover behavior and
content rendering.

In `@apps/dashboard/src/pages/CreateUrlPage.tsx`:
- Around line 105-107: Update the customCode validation in CreateUrlPage to
reject any value containing characters outside letters, numbers, hyphens, and
underscores, while preserving the existing 3–16 character length checks and
error behavior.

In `@apps/dashboard/src/pages/UrlDetailPage.tsx`:
- Around line 97-99: Update the QR result state and generation flow around
qrDataUrl, qrFormat, and setQrDataUrl to store the generated object URL together
with its actual format, and use that stored format when naming downloads instead
of the current selector value. Revoke replaced object URLs when updating the
result and revoke the final URL during component cleanup, while preserving the
existing display behavior.
- Around line 580-598: Associate the Format and Logo URL labels with their
controls by adding matching htmlFor attributes and unique id attributes to the
corresponding select and input elements in the QR settings form. Update only the
controls surrounding qrFormat and qrLogo, preserving their existing behavior.
- Around line 230-235: Update the Settings navigation in UrlDetailPage to avoid
wrapping the Button component in a Link. Use the link itself with button
styling, or use Button’s asChild support if available, while preserving the
existing `/urls/${code}/settings` destination, outline variant, small size,
icon, and label.

In `@apps/dashboard/src/pages/UrlsListPage.tsx`:
- Around line 345-351: Add accessible labels to the selection checkboxes in the
URLs table: label the header checkbox in the select-all control as “Select all
URLs,” and label each row checkbox using the corresponding URL code, such as
“Select ${url.code}.” Update both the header checkbox and row checkbox rendering
near the selection controls without changing their selection behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: db0784b8-800d-44bc-ad06-ad4d4ec0d34b

📥 Commits

Reviewing files that changed from the base of the PR and between 19f043c and a7b11d1.

📒 Files selected for processing (19)
  • apps/dashboard/src/components/copy-button.tsx
  • apps/dashboard/src/components/status-badge.tsx
  • apps/dashboard/src/components/ui/command.tsx
  • apps/dashboard/src/components/ui/dialog.tsx
  • apps/dashboard/src/components/ui/label.tsx
  • apps/dashboard/src/components/ui/pagination.tsx
  • apps/dashboard/src/components/ui/popover.tsx
  • apps/dashboard/src/components/ui/select.tsx
  • apps/dashboard/src/components/ui/switch.tsx
  • apps/dashboard/src/components/ui/table.tsx
  • apps/dashboard/src/components/ui/tabs.tsx
  • apps/dashboard/src/components/ui/textarea.tsx
  • apps/dashboard/src/components/ui/tooltip.tsx
  • apps/dashboard/src/pages/BulkCreatePage.tsx
  • apps/dashboard/src/pages/CreateUrlPage.tsx
  • apps/dashboard/src/pages/UrlDetailPage.tsx
  • apps/dashboard/src/pages/UrlsListPage.tsx
  • opencode.json
  • specs/03-third-fourth-phase.md

Comment thread apps/dashboard/src/components/ui/command.tsx
Comment thread apps/dashboard/src/components/ui/dialog.tsx
Comment thread apps/dashboard/src/components/ui/pagination.tsx Outdated
Comment thread apps/dashboard/src/components/ui/popover.tsx Outdated
Comment thread apps/dashboard/src/components/ui/tabs.tsx
Comment thread apps/dashboard/src/pages/UrlsListPage.tsx
Comment thread apps/dashboard/src/pages/UrlsListPage.tsx Outdated
Comment thread apps/dashboard/src/pages/UrlsListPage.tsx Outdated
Comment thread opencode.json
Comment thread opencode.json
@NehanAhmed
NehanAhmed merged commit 1beac81 into main Jul 15, 2026
1 of 2 checks passed
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