new jobs page to see all saved jobs with proper pagination.#20
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 42 minutes and 37 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughThe pull request introduces pagination support to the jobs feature. The backend's Changes
Sequence Diagram(s)sequenceDiagram
participant Client as JobsPageContent
participant API as getJobs()
participant Server as JobController
participant DB as JobService/Database
Client->>Client: Initialize state<br/>(page=1, pageSize=6)
Client->>Client: Calculate skip = (page-1) × 6
Client->>API: getJobs(skip, pageSize)
API->>Server: GET /jobs?skip=X&take=6
Server->>DB: getJobsByUserId(userId, skip, take)<br/>Fetch take+1 records
DB-->>Server: Return 7 records
Server->>Server: Slice to 6, compute hasMore
Server-->>API: { jobs: [...], hasMore: boolean }
API-->>Client: { jobs: [...], hasMore: boolean }
Client->>Client: Derive totalPages<br/>= hasMore ? page+1 : page
Client->>Client: Render JobsList<br/>with pagination controls
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
frontend/components/dashboard/dashboard-widgets.tsx (1)
21-29:⚠️ Potential issue | 🟡 MinorUpdate the helper copy to match the new CTA.
The button now says “Manage Jobs”, but the text above it still describes creating/analyzing a new posting. That mismatch is likely to confuse users on the dashboard.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/components/dashboard/dashboard-widgets.tsx` around lines 21 - 29, The helper copy above the CTA is out of sync: update the paragraph text in the dashboard-widgets component (the <p> element shown in dashboard-widgets.tsx that currently reads "Analyze a new job posting to get recommendations.") so it aligns with the CTA "Manage Jobs" (the Link with href="/jobs" and link text "Manage Jobs"); replace it with a short line like "View and manage your job postings" or similar copy that clearly references managing or viewing jobs.frontend/components/job/job-input-toggle.tsx (1)
17-31:⚠️ Potential issue | 🟡 MinorExpose the selected toggle state to assistive tech.
These buttons act like a toggle, but the active state is only visual right now. Adding
aria-pressedwill make the current selection understandable to screen readers.Accessibility fix
<button type="button" + aria-pressed={isText} onClick={() => onChange("TEXT")} className={`rounded-lg px-4 py-2 text-sm font-medium transition ${ isText ? "bg-white shadow text-black" : "text-gray-600 hover:text-black" @@ <button type="button" + aria-pressed={isLink} onClick={() => onChange("LINK")} className={`rounded-lg px-4 py-2 text-sm font-medium transition ${ isLink ? "bg-white shadow text-black" : "text-gray-600 hover:text-black"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@frontend/components/job/job-input-toggle.tsx` around lines 17 - 31, The toggle buttons (Paste Text and Link) only convey state visually; update the button elements (the one using isText and the one calling onChange("LINK")) to include an aria-pressed attribute that reflects the active state (for the TEXT button use aria-pressed={isText} and for the LINK button use aria-pressed={!isText} or an explicit isLink boolean), so screen readers can announce which option is selected; ensure the attribute is present on both buttons that call onChange and ties to the same isText state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/src/jobs/job.controller.ts`:
- Around line 52-61: The response currently returns only hasMore; update the
controller method that calls this.jobService.getJobsByUserId to include a
totalCount (or totalPages) in the returned payload so the frontend can render
numbered pagination. Modify the jobService.getJobsByUserId (or add a companion
method like jobService.countJobsByUserId) to return totalCount alongside
result.jobs and result.hasMore, then change the controller return object to
include totalCount (or compute totalPages from totalCount and query.take) and
update the TypeScript return type accordingly.
In `@backend/src/jobs/job.service.ts`:
- Around line 29-33: The pagination sorting is currently non-deterministic
because jobRepository.find orders only by createdAt; update the order clause
used by jobRepository.find to include a unique tie-breaker such as the primary
key (e.g., id) in a deterministic direction (for example order: { createdAt:
'DESC', id: 'DESC' }) so offset pagination with skip/take (take + 1) will not
duplicate or skip rows when createdAt values are identical.
In `@frontend/components/job/job-card.tsx`:
- Around line 27-33: The "View" and "Delete" buttons in the JobCard component
are interactive but currently no-ops; update the component (JobCard) to accept
optional callback props (e.g., onView: (id: string) => void, onDelete: (id:
string) => void) and wire the "View" button to call props.onView(job.id) and the
"Delete" button to call props.onDelete(job.id) (with proper null-checks), or if
you prefer not to implement callbacks yet, render these buttons with disabled
styling/disabled attribute and remove onclick behavior; ensure to update the
component's props interface and all callers to pass handlers or accept the
disabled state.
In `@frontend/components/job/jobs-page-content.tsx`:
- Around line 26-30: The empty/error fetch branches do not clear previous
results, so add a call to clear the jobs state (e.g., setJobs([])) before
returning in both the "if (!jobs || jobs.length === 0) { ... }" branch and the
error/empty path around lines 42-46; keep the existing setTotalPages(1) and
setIsLoading(false) but ensure setJobs([]) is invoked prior to return so stale
job entries are not rendered after an empty response or failed request.
- Around line 19-49: The fetchJobs useEffect is vulnerable to out-of-order
responses overwriting state; make it race-safe by tracking the latest request
and ignoring stale responses: add a fetchRequestId ref (e.g.,
fetchRequestId.current) or an AbortController per invocation inside the
useEffect, increment/replace it before calling getJobs, capture the id or signal
in the async fetchJobs, and only call setJobs, setTotalPages, and setIsLoading
if the captured id matches the current fetchRequestId (or the signal is not
aborted). Keep the existing getJobs, fetchJobs, and state setters but gate state
updates behind this check and ensure cleanup in the effect returns
abort/invalidates the request to prevent updates after unmount.
---
Outside diff comments:
In `@frontend/components/dashboard/dashboard-widgets.tsx`:
- Around line 21-29: The helper copy above the CTA is out of sync: update the
paragraph text in the dashboard-widgets component (the <p> element shown in
dashboard-widgets.tsx that currently reads "Analyze a new job posting to get
recommendations.") so it aligns with the CTA "Manage Jobs" (the Link with
href="/jobs" and link text "Manage Jobs"); replace it with a short line like
"View and manage your job postings" or similar copy that clearly references
managing or viewing jobs.
In `@frontend/components/job/job-input-toggle.tsx`:
- Around line 17-31: The toggle buttons (Paste Text and Link) only convey state
visually; update the button elements (the one using isText and the one calling
onChange("LINK")) to include an aria-pressed attribute that reflects the active
state (for the TEXT button use aria-pressed={isText} and for the LINK button use
aria-pressed={!isText} or an explicit isLink boolean), so screen readers can
announce which option is selected; ensure the attribute is present on both
buttons that call onChange and ties to the same isText state.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9d767c83-ef1b-4055-bc05-35631680f109
📒 Files selected for processing (14)
backend/src/jobs/job.controller.tsbackend/src/jobs/job.service.tsfrontend/app/jobs/page.tsxfrontend/components/dashboard/dashboard-widgets.tsxfrontend/components/job/job-card.tsxfrontend/components/job/job-form.tsxfrontend/components/job/job-input-toggle.tsxfrontend/components/job/job-list.tsxfrontend/components/job/job-result-preview.tsxfrontend/components/job/jobs-list.tsxfrontend/components/job/jobs-page-content.tsxfrontend/lib/job-api.tsfrontend/types/auth.tsfrontend/types/job.ts
💤 Files with no reviewable changes (1)
- frontend/types/auth.ts
Release Notes
hasMoreflag) enabling efficient client-side paginationfrontend/types/job.tsincluding newJobtype andInputTypeenum moved from API layergetJobs()endpoint function to fetch paginated job lists with skip/take parametersnew commit changes:
feat(backend): Add pagination improvements with deterministic ordering
feat(backend): Add totalPages calculation to jobs controller
feat(frontend): Update job API to return totalCount and totalPages
feat(frontend): Implement race-safety with AbortController
feat(frontend): Clear jobs state on empty and error responses
feat(frontend): Add callbacks to JobCard component
feat(frontend): Improve accessibility and UX