Skip to content

feat: Sort & Filter for Job Feed (domain module, stable sort, premium UI, persistence, a11y)#17

Merged
r-yalcin merged 8 commits intomainfrom
copilot/add-sort-filter-functionality
Feb 24, 2026
Merged

feat: Sort & Filter for Job Feed (domain module, stable sort, premium UI, persistence, a11y)#17
r-yalcin merged 8 commits intomainfrom
copilot/add-sort-filter-functionality

Conversation

Copy link
Contributor

Copilot AI commented Feb 23, 2026

Summary

Replaces the placeholder filter button in the job feed with a fully functional sort/filter panel. Introduces a pure domain module for sort/filter logic, localStorage persistence with safe parsing, 25 unit tests, and a polished panel component with reduced-motion support and accessible markup.

Related Issues

Type of Change

  • 🐛 Bug fix
  • ✨ Feature
  • 💥 Breaking change
  • 🎨 UI/UX
  • ♻️ Refactor
  • 🧪 Tests
  • 📚 Docs
  • 🔧 Build/CI
  • 🛡️ Security / Abuse
  • ⚡ Performance

What changed

  • src/lib/jobs/sortFilter.ts — pure domain module: SortOption, FilterState, sortJobs (stable tie-breakers: primary → created_at desc → id asc), applyFilters (fast-path when no filters), deriveVisibleJobs (composed), SORT_META, isValidSortOption
  • src/components/jobs/JobFilterSortPanel.tsx — new bottom-sheet/modal: flat dark surface (bg-[#1a1a20]), flat bg-indigo-600 CTA (no gradient fill), 44px tap targets, aria-labelledby, aria-pressed on all toggles, useReducedMotion guard on all transforms, portal rendering, safe-area footer inset, animated CTA count swap via keyed motion.span
  • src/components/jobs/JobsList.tsx — imports types/functions exclusively from domain module; deriveVisibleJobs used in two useMemo calls; sortJobs applied to waitlist/applied tabs; debounce timer moved into useRef with cleanup (no dangling module-level timer); persistence via loadPersistedState / persistState with schema version + safe parse; animated tab transitions via AnimatePresence with directional slide
  • src/__tests__/jobs/sortFilter.test.ts + vitest.config.ts — 25 unit tests covering distance/newest/wage sorts, null/undefined handling, immutability, filter combinations, deriveVisibleJobs composition

User impact

  • Role(s): Teen
  • Before: Filter button opened a "coming soon" placeholder with no controls
  • After: Sort by distance / newest / wage; filter by category (multi-select) and max distance radius; filters are combinable, state persists across page reloads, results update deterministically; zero-result state shows inline hint

How to test

  • Lint / format / typecheck pass
  • Unit tests pass (npm test — 25 tests)
  • E2E / Playwright pass (if available)
  • Manual testing performed

Manual steps (if applicable):

  1. /app-home/jobs as Teen → tap Filter → panel opens with sort cards, category chips, distance chips
  2. Select "Vergütung" → jobs reorder by wage desc with tie-broken by recency
  3. Toggle a category chip → badge count appears on Filter button; only matching jobs shown
  4. Set "5 km" → jobs beyond threshold hidden; hint "Jobs ohne Entfernungsangabe werden ausgeblendet" appears
  5. Tap Zurücksetzen → all state clears; badge disappears
  6. Reload page → last sort/filter state is restored from localStorage
  7. Enable OS "Reduce Motion" → all transforms disabled, fades only

Edge cases:

  • Location unavailable: distance sort still works (jobs without distance_km sorted last deterministically)
  • Missing wage_hourly / category: jobs sink to bottom without crash
  • localStorage unavailable (SSR / private browsing): falls back to defaults silently

Screenshots / Recordings (if applicable)

Safety & Privacy (JobBridge)

  • No secrets/tokens in code, logs, or screenshots
  • No personal data (names, addresses, phone numbers, private chats)
  • Location visibility rules unchanged (no precise address leaks)
  • Moderation/reporting/trust mechanisms not weakened

AI assistance (optional)

AI Prompt Used
N/A - Manual implementation
Original prompt

This section details on the original issue you should resolve

<issue_title>[Feature]: Sort/Filter functionality for Job Feed</issue_title>
<issue_description>### Gibt es schon einen ähnlichen Feature-Vorschlag?

  • Ich habe nach bestehenden Issues gesucht

Problem / Motivation

Sortierung unklar. Personalisierung der Sortierung und Art der Jobs macht den Job Feed übersichtlicher.

Für wen ist das Feature?

Jugendliche

Vorschlag / Lösungsidee

Einführung einer erweiterten Sortier- und Filterfunktion in der Joblistenansicht.

  1. Standardsortierung
    Bei überregionalen Angeboten: Standardmäßig nach Entfernung (aufsteigend)
    Bei lokalen Angeboten: aktuelle Logik beibehalten oder ebenfalls Distanz als Default
  2. Manuelle Sortieroptionen (Dropdown)
    Entfernung (nächstgelegene zuerst)
    Neueste Jobs (Upload-Datum DESC)
    Vergütung (höchste zuerst)
    Optional: „Empfohlen“ (interne kombinierte Logik)
  3. Erweiterte Filter (kombinierbar)
    Kategorie (z. B. Gartenarbeit, Haushalt, Nachhilfe etc.)
    Maximale Entfernung (km-Wert)
    Zeitfenster / Datum
    Status (nur offene Jobs)
    Anforderungen an Anbieter:
    Extra-Verifizierung aktiv
    Bestimmter TrustScore-Schwellenwert
    Bestimmte Erfahrungsmerkmale (falls implementiert)

Akzeptanzkriterien (Definition of Done)

  • Überregionale Joblisten sind standardmäßig nach Entfernung sortiert
  • Nutzer können Sortieroption aktiv ändern
  • Filter sind kombinierbar
  • Ergebnisliste aktualisiert sich deterministisch
  • Performance bleibt stabil

Alternativen / Workarounds

No response

Bereich (Area)

Jobsuche / Filter / Liste

Wichtigkeit / Impact

Verbessert die Nutzererfahrung deutlich

Aufwandsschätzung (optional)

S (klein)

Mockups / Beispiele (optional)

No response

Risiken / Nebenwirkungen (optional)

No response

Zusätzlicher Kontext (optional)

No response</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@vercel
Copy link

vercel bot commented Feb 23, 2026

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

Project Deployment Actions Updated (UTC)
jobbridge Ready Ready Preview, Comment Feb 24, 2026 7:18am

Co-authored-by: r-yalcin <221595382+r-yalcin@users.noreply.github.com>
Copilot AI changed the title [WIP] Add sort and filter functionality for job feed feat: Implement Sort/Filter functionality for Job Feed Feb 23, 2026
Copilot AI requested a review from r-yalcin February 23, 2026 20:47
Copy link
Collaborator

@r-yalcin r-yalcin left a comment

Choose a reason for hiding this comment

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

Verbessere Stabilität und Design!

Co-authored-by: r-yalcin <221595382+r-yalcin@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

Verbessere Stabilität und Design!

Done in 76216d1. Here's what was improved:

Stability:

  • Body scroll is locked while the panel is open, restored on close
  • Escape key now closes the panel (keyboard accessibility)
  • toggleCategory / setMaxDistance use the functional update pattern (setFilterState(prev => …)) so useCallback no longer depends on filterState — stable references across renders
  • Panel renders via createPortal into document.body to avoid overflow/clip issues in the page hierarchy
  • Fixed: "Zurücksetzen" now also appears when only the sort order has been changed (not just when filters are active)
  • The badge count on the Filter button now counts sort changes too

Design:

  • Panel enter/exit now uses framer-motion spring animation (consistent with Modal.tsx) — smooth slide-up on open, slide-down on close
  • Section headings have semantic icons: ArrowUpDown for sort, Tag for category, MapPin for distance
  • Active chips get a subtle indigo glow for clearer visual feedback
  • Footer CTA changed from "Anwenden" to "Ergebnisse anzeigen"
  • Desktop Filter button shows the active sort label ("Neueste Jobs zuerst" / "Vergütung …") when only the sort is changed — no plain "Filter" label needed

Co-authored-by: r-yalcin <221595382+r-yalcin@users.noreply.github.com>
Copilot AI changed the title feat: Implement Sort/Filter functionality for Job Feed feat: Sort/Filter for Job Feed — all tabs, premium UI, animated transitions Feb 23, 2026
…tests

Co-authored-by: r-yalcin <221595382+r-yalcin@users.noreply.github.com>
Copilot AI changed the title feat: Sort/Filter for Job Feed — all tabs, premium UI, animated transitions feat: Sort & Filter for Job Feed — domain module, stable sort, persistence, a11y, reduced motion Feb 24, 2026
@r-yalcin r-yalcin marked this pull request as ready for review February 24, 2026 06:36
Copilot AI review requested due to automatic review settings February 24, 2026 06:36
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cc700a7193

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a comprehensive sort and filter system for the job feed, replacing a placeholder with production-grade functionality including persistent user preferences, accessibility features, and extensive test coverage.

Changes:

  • New pure domain module (sortFilter.ts) with stable sorting algorithms and filter logic backed by 21 unit tests
  • LocalStorage persistence with safe parsing, validation, and 400ms debouncing for user filter/sort preferences
  • Accessible filter panel with reduced-motion support, ARIA attributes, and premium flat UI design
  • Deterministic 3-tier sort stability (primary → created_at DESC → id ASC) prevents flickering across reloads

Reviewed changes

Copilot reviewed 6 out of 8 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
src/lib/jobs/sortFilter.ts Pure domain logic for sorting/filtering jobs with type guards and stable tie-breaking
src/__tests__/jobs/sortFilter.test.ts 21 unit tests covering sort modes, filters, edge cases, and immutability
src/components/jobs/JobFilterSortPanel.tsx Filter UI with reduced-motion support, disabled CTA on zero results, ARIA attributes
src/components/jobs/JobsList.tsx Integration of sort/filter with localStorage persistence, memoization, and tab animations
vitest.config.ts Test infrastructure configuration with vite-tsconfig-paths for path resolution
package.json Added vitest 4.0.18 and vite-tsconfig-paths 6.1.1 as dev dependencies

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…ated CTA, aria-labelledby

Co-authored-by: r-yalcin <221595382+r-yalcin@users.noreply.github.com>
Copilot AI changed the title feat: Sort & Filter for Job Feed — domain module, stable sort, persistence, a11y, reduced motion feat: Sort/Filter functionality for Job Feed Feb 24, 2026
…edundant useCallback

Co-authored-by: r-yalcin <221595382+r-yalcin@users.noreply.github.com>
Copilot AI changed the title feat: Sort/Filter functionality for Job Feed feat: Sort & Filter for Job Feed — domain module, premium UI, stable sort, persistence, tests Feb 24, 2026
@r-yalcin r-yalcin requested a review from Copilot February 24, 2026 07:07
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…tion or class'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Copilot AI changed the title feat: Sort & Filter for Job Feed — domain module, premium UI, stable sort, persistence, tests feat: Sort & Filter for Job Feed (domain module, stable sort, premium UI, persistence, a11y) Feb 24, 2026
Copilot AI requested a review from r-yalcin February 24, 2026 07:25
@r-yalcin r-yalcin merged commit 9c4d67f into main Feb 24, 2026
4 checks passed
@r-yalcin r-yalcin deleted the copilot/add-sort-filter-functionality branch February 24, 2026 07:29
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.

[Feature]: Sort/Filter functionality for Job Feed

3 participants