Skip to main content

Modules Documentation

Status & badge logic

How statuses transition and what badges render.

Complete

Opportunity status is computed at render time from `deadlineAt`, not stored as a field. The `OpportunityService.computeStatus()` method returns one of `Open` / `ClosingSoon` / `Closed` / `Rolling` — and every visual element (strip color, chip class, deadline pill) derives from that status.

The four computed statuses

Open · green (.chip-success, bg-badge-verified)
deadlineAt > today + 7 days. Top strip + status chip + deadline pill all render green-tinted.
ClosingSoon · orange (.chip-orange, bg-brand-orange)
deadlineAt ≤ today + 7 days (and still in the future). Urgent. May animate the deadline pill with a subtle pulse.
Closed · muted grey (.chip-muted, bg-muted-foreground)
deadlineAt < today. Card stays visible (for SEO/AEO entity history) but de-emphasized. Apply CTA hidden.
Rolling · purple (.chip-primary, bg-primary)
deadlineAt is NULL (no fixed deadline). Opportunity accepts applications continuously. Deadline pill shows "Rolling".

Deadline pill labels

  • `or.deadline.rolling` — "Rolling deadline" / "موعد متجدّد"
  • `or.deadline.closed` — "Closed" / "أُغلق"
  • `or.deadline.today` — "Closes today" / "ينتهي اليوم"
  • `or.deadline.inDays` — "Closes in {n} days" / "ينتهي خلال {n} أيام" (when ≤ 7 days)
  • `or.deadline.on` — "Closes on {date}" / "ينتهي في {date}" (when 8-60 days)
  • `or.deadline.openUntil` — "Open until {date}" / "مفتوحة حتى {date}" (when > 60 days)