RENTVILLA

Home

55,555 · Madrid

PHASE 4.4 — DASHBOARD LISTINGS: SEARCH + FILTERS + SORT + PAGINATION (RESPONSIVE) You are a senior Next.js 16 App Router + Supabase engineer. Implement end-to-end, minimal and production-grade. CONTEXT - Supabase Postgres + RLS already set. - Dashboard shows listings for: - ADMIN: all listings - AGENT: only their own - Current /dashboard/listings exists but becomes hard to use at scale. - We also recently fixed server/client Supabase separation; keep it stable. ABSOLUTE RULES - Edit files directly in repo (not just pasted snippets). - Keep code concise, readable, and well-commented (only where useful). - All UI must be mobile-first responsive; no horizontal scroll at 320px. - Use Server Components for reads and Server Actions for writes. - No console.error inside Server Component render paths. - Any server action expecting FormData MUST be called via <form action={...}>. GOAL Upgrade /dashboard/listings to support: 1) Search (q): title + city partial match (case-insensitive) 2) Filters: - status: ALL / PUBLISHED / DRAFT - purpose: ALL / BUY / RENT - featured: ALL / YES / NO (ADMIN only) 3) Sort: - newest (default): updated_at desc - price_low: price asc - price_high: price desc 4) Pagination: - page size: 20 - show “Prev / Next” with page number - use querystring: ?q=&status=&purpose=&featured=&sort=&page= UX REQUIREMENTS (RESPONSIVE) - Desktop: filters row visible - Mobile: filters collapse into a shadcn Sheet/Drawer with an “Filters” button - Search always visible - Results: - Mobile: cards list - Desktop: table is OK (optional), but must still be readable - Keep actions per listing: - Edit -> /dashboard/listings/[id]/edit - Media -> /dashboard/listings/[id]/media - Publish/Unpublish toggle (via <form action={setPublishedAction}>) - Delete (via <form action={deleteListingAction}> with confirmation) IMPLEMENTATION DETAILS A) Parsing query params 1) Update app/dashboard/listings/page.tsx to read: searchParams: { q, status, purpose, featured, sort, page } 2) Normalize: - page integer >= 1 - empty strings treated as undefined B) Query function (server-side) 1) Create or update: lib/queries/dashboard.ts (or lib/queries/listings-dashboard.ts) Add function: - getDashboardListings({ profile, q, status, purpose, featured, sort, page, pageSize }) It should return: - items: listing rows - total: total matching count - page, pageSize, totalPages 2) Supabase query requirements: - Base table: public.listings - Columns needed: id, title, city, price, purpose, property_type, status, featured, updated_at, published_at - Apply role scoping: - ADMIN: no agent filter - AGENT: filter by agent_id = current agent id - Apply published filter for status: - PUBLISHED: status='PUBLISHED' AND published_at not null - DRAFT: status='DRAFT' OR published_at is null (use your schema’s truth) - Search: - Use ilike on title and city: or(title.ilike.%q%,city.ilike.%q%) - featured filter: - Only for ADMIN; ignore for AGENT - Sort mapping: - newest: updated_at desc - price_low: price asc - price_high: price desc - Pagination: - Use range(from, to) with pageSize - Total count: - Use select('*', { count: 'exact', head: true }) OR single query returning count (choose simplest reliable). - Ensure performance reasonable. C) UI controls 1) Build a small component for filter controls: components/dashboard/ListingsFilters.tsx (client) - Controlled inputs (search + selects) - On submit, push querystring using next/navigation router - Include “Clear” button that resets querystring - Mobile: open in Sheet 2) Keep page itself (page.tsx) server component: - reads searchParams - calls getDashboardListings - renders <ListingsFilters initialValues=... /> - renders results list + pagination component D) Pagination component 1) Create: components/dashboard/Pagination.tsx - shows “Prev”, “Next”, and “Page X of Y” - builds links preserving existing query params E) Actions integration (must be stable) 1) Publish/Unpublish: - Ensure it submits a form with hidden inputs id, published (true/false) 2) Delete: - Ensure it submits a form with hidden input id - Add confirmation: - easiest: use a client wrapper button with window.confirm and then submit a hidden form - OR use shadcn AlertDialog (preferred) 3) After actions: - Ensure revalidatePath('/dashboard/listings') is already in actions. - Also revalidatePath('/listings') if publish/unpublish/delete affects public. F) Verification (MUST DO AND REPORT) 1) npm run dev 2) As ADMIN: - search works (title/city) - filter status/purpose/featured works - sort changes ordering - pagination works for multiple pages (seed or create 25+ listings) 3) As AGENT: - only sees own listings - featured filter not shown 4) Actions: - Publish/Unpublish works without FormData undefined errors - Delete works without FormData undefined errors and redirects correctly 5) Responsiveness: - 390x844 and 360x800: no overflow; filter sheet works; buttons accessible. OUTPUT - Files changed - Commands run - Verification checklist + expected behavior - Any short follow-ups

BookPage BW version 300 DPI-modified
4 bd5 ba45 sqm

Listed by: Demo Agent

Request more info

We will reply quickly.

By sending, you agree to our Terms of Service.