diff --git a/src/applypilot/view.py b/src/applypilot/view.py index ff42fec..2e84577 100644 --- a/src/applypilot/view.py +++ b/src/applypilot/view.py @@ -76,7 +76,8 @@ def generate_dashboard(output_path: str | None = None) -> str: jobs = conn.execute(""" SELECT url, title, salary, description, location, site, strategy, full_description, application_url, detail_error, - fit_score, score_reasoning + fit_score, score_reasoning, + applied_at, apply_status, apply_error, last_attempted_at FROM jobs WHERE fit_score >= 5 ORDER BY fit_score DESC, site, title @@ -178,8 +179,68 @@ def generate_dashboard(output_path: str | None = None) -> str: if apply_url: apply_html = f'Apply' + # Auto-apply command button (only for jobs not yet applied) + raw_url = j["url"] or "" + auto_apply_cmd = f"applypilot apply --url {raw_url}" + + # Applied indicator + was_applied = j["apply_status"] == "applied" and j["applied_at"] + applied_banner = "" + applied_attr = "" + if was_applied: + try: + from datetime import datetime as _dt + applied_dt = _dt.fromisoformat(j["applied_at"].replace("Z", "+00:00")) + applied_date_str = applied_dt.strftime("%b %-d, %Y") + except (ValueError, AttributeError): + applied_date_str = j["applied_at"][:10] + applied_banner = f'
' + applied_attr = ' data-applied="true"' + + # Failed indicator + _status_reasons = { + "expired": "Job posting expired", + "captcha": "CAPTCHA blocked", + "login_issue": "Login required", + "not_eligible_location": "Location not eligible", + "not_eligible_salary": "Salary not eligible", + "already_applied": "Already applied", + "account_required": "Account required", + "not_a_job_application": "Not a job posting", + "unsafe_permissions": "Unsafe permissions", + "unsafe_verification": "Unsafe verification", + "sso_required": "SSO required", + "site_blocked": "Site blocked", + "cloudflare_blocked": "Cloudflare blocked", + "failed": "Application failed", + } + was_failed = ( + j["apply_status"] and j["apply_status"] != "applied" + and j["last_attempted_at"] + ) + failed_banner = "" + if was_failed: + try: + from datetime import datetime as _dt + failed_dt = _dt.fromisoformat(j["last_attempted_at"].replace("Z", "+00:00")) + failed_date_str = failed_dt.strftime("%b %-d, %Y") + except (ValueError, AttributeError): + failed_date_str = j["last_attempted_at"][:10] + short_reason = ( + escape((j["apply_error"] or "")[:60]) or + _status_reasons.get(j["apply_status"], j["apply_status"].replace("_", " ").title()) + ) + failed_banner = f'' + + card_extra_class = "" + if was_applied: + card_extra_class = " job-card--applied" + elif was_failed: + card_extra_class = " job-card--failed" + job_sections += f""" -{desc_preview}...
{"