{# =========================================================================== jobs/_table.html — table-body rows partial =========================================================================== Returned by GET /jobs/table (the filter/sort/live-refresh target) AND included by the full page. STRUCTURE IS UNCHANGED from the original — only the empty state copy/styling is touched. PORT NOTE (load-bearing): the hidden placeholder that trails every compact row is the slot the expand swap replaces and the collapse response restores. Keep it. colspan is 7 (Score, Title, Company, Location, Salary, Posted, Status). #} {% if jobs %} {% for job in jobs %} {% include "jobs/_row.html" %} {% endfor %} {% elif total_jobs is defined and total_jobs == 0 %} {# WP5: brand-new / empty DB — "loosen the filters" is wrong advice when there is nothing to filter. Tell the user what Sync actually does. The CTA links to the dashboard rather than half-wiring a Sync button here: sync_start's progress UI polls #sync-status, which only exists there. #}

No jobs yet.

Job Cannon pulls from the free job portals (RemoteOK, Remotive, Himalayas) using your target titles — plus Gmail alerts and watched companies if you've connected them.

{% if profile_titles_missing %}

Tip: free-portal search uses your target titles — set them in Profile first.

{% endif %} Go to the Dashboard and press Sync Now {% else %} {# DESIGN DECISION: empty state given a little more breathing room + a muted two-line read instead of a single terse line. No behavior change. #}

No jobs match the current filters.

Loosen the status, date, or advanced filters to see more.

{% endif %}