Commit Graph

25 Commits

Author SHA1 Message Date
soroush.asadi 753a14286f Mobile hero search: compact magnify button + dropdown under the input
CI/CD / CI · dotnet build (push) Successful in 4m17s
CI/CD / Deploy · hamkadr (push) Successful in 4m30s
- Submit button is now a 44x44 magnify icon inside the search pill on mobile instead of a full-width stacked button (desktop keeps the جستجو text).
- Anchor the typeahead dropdown to the search pill so results appear directly under the input rather than below the popular-search chips; full pill width.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 07:39:23 +03:30
soroush.asadi 62e9bf1353 Nav: replace inline search box with a «🔎 جستجو» link to /Search
CI/CD / CI · dotnet build (push) Successful in 2m39s
CI/CD / Deploy · hamkadr (push) Successful in 2m36s
The hero is now the primary search; the navbar just links to the search
page (cleaner header, less clutter on mobile). Typeahead remains on the
hero (form[data-suggest]).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:26:37 +03:30
soroush.asadi bcf90f2437 Home hero: replace filter dropdowns with a search-engine box (+ live typeahead)
CI/CD / CI · dotnet build (push) Successful in 2m32s
CI/CD / Deploy · hamkadr (push) Successful in 2m0s
The hero is now a single big search box → /Search (the rich, ranked,
highlighted search across shifts/jobs/applicants), with popular-search
chips. Typeahead is generalized to any form[data-suggest], so the hero box
shows the same instant highlighted dropdown as the header pill.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 22:34:31 +03:30
soroush.asadi 8b0b21f24d Search: Elasticsearch-style highlighted match snippets (results + typeahead)
CI/CD / CI · dotnet build (push) Successful in 6m9s
CI/CD / Deploy · hamkadr (push) Has been cancelled
- SearchHighlight.Snippet: extracts a ±70-char window around the first
  matching term and marks it (with ellipses) — the ES "highlight" fragment.
- Result cards (shift/job/talent) now show that snippet from the matched
  description/tags when a query is present, so you SEE where the term hit
  (e.g. «…دارای مدرک <mark>mmt</mark>…») instead of just the role.
- Typeahead suggestions gain a highlighted "sub" line (talent→tags,
  shift→city·specialty, job→facility·city) so matches show in the dropdown too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 21:43:50 +03:30
soroush.asadi eb7d0f6559 Fix: search suggestions dropdown was clipped by the pill's overflow:hidden
CI/CD / CI · dotnet build (push) Failing after 14s
CI/CD / Deploy · hamkadr (push) Has been skipped
Moved overflow:hidden onto an inner .nav-search-pill so the rounded corners
still clip the input/button, but the absolutely-positioned suggestions box
(a child of the non-clipped .nav-search) is no longer hidden. Dropdown given
a readable min-width.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 17:42:07 +03:30
soroush.asadi 61afc957aa Search: fix header UI + instant typeahead (5 highlighted matches) + ranking
CI/CD / CI · dotnet build (push) Successful in 1m38s
CI/CD / Deploy · hamkadr (push) Successful in 2m6s
- Header search restyled as one clean RTL pill (input + button flush).
- Google-style autocomplete: typing ≥2 chars fetches /search/suggest and
  shows up to 5 live matches (round-robin across shifts/jobs/applicants)
  with the query highlighted, plus a «همه نتایج» link. Debounced, closes on
  outside-click/Escape.
- Search results page now RANKS by relevance (term hits in role/title/
  facility/city/tags weighted ×3, description ×1) instead of date-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 11:58:30 +03:30
soroush.asadi 9db4deafbc Site-wide rich search with keyword highlighting + header search box
CI/CD / CI · dotnet build (push) Successful in 1m53s
CI/CD / Deploy · hamkadr (push) Successful in 2m47s
- /Search: searches shifts, hiring openings, and applicants together via
  Postgres ILIKE (every term must match across role/city/facility/title/
  description/tags/person). Results grouped per type.
- Keyword highlighting (<mark>) extended to shift & job cards (was talent-only),
  so matches stand out everywhere.
- Persistent header search box (.nav-search) → /Search; big hero box on the
  page itself.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 11:40:26 +03:30
soroush.asadi 4e5df73cf7 Add «آماده به کار» (talent) listing type — workers offering themselves
CI/CD / CI · dotnet build (push) Successful in 1m41s
CI/CD / Deploy · hamkadr (push) Has been cancelled
Adds a third listing kind alongside Shift/Job for healthcare staff who
advertise their own availability (very common in Iranian medical
channels, e.g. "دندانپزشک آماده همکاری… ۵۰٪ تسویه"). These have no
facility; the contact phone is the key field.

- Model: TalentListing (role, person name, years, licensed, city/district,
  area note, availability, gender, comp, phone) + ListingKind.Talent +
  RawListing.LinkedTalentId + DbSet/relations/indexes + EF migration.
- Parser: detect آماده‌به‌کار/جویای کار → Kind=Talent; extract person name,
  years of experience, licensed flag, area («منطقه ۱»), phone. Facility
  name extraction now skipped for talent.
- Validator: talent path scores role + phone + medical (no facility/pay
  required).
- Ingestion auto-publish: creates a TalentListing for talent kind.
- Review (manual publish): Talent option + talent fields; publishes a
  TalentListing without a facility. Shift/Job facility now falls back to a
  shared «نامشخص / ثبت نشده» record when the ad names none — publishing
  never fails on a missing facility.
- Browse /Talent (indexable, filters: city/district/role/gender),
  details /Talent/Details (noindex — personal contact, tel: call button),
  _TalentCard, badge-talent, nav link, home section.
- Sitemap includes /Talent; robots disallows /Talent/Details. Archiver
  expires stale talent listings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 08:01:12 +03:30
soroush.asadi bdcca5e548 Redesign header menu: separate account dropdown from dashboard nav
CI/CD / CI · dotnet build (push) Successful in 1m7s
CI/CD / Deploy · hamkadr (push) Successful in 1m57s
The profile dropdown was doing three jobs at once (account actions, the
job-seeker panel menu, and the admin panel menu) and a stray inline @if
for the notification badge leaked into the markup as literal text.

- Profile dropdown is now account-only: identity card (avatar + name +
  phone), one role-aware dashboard entry, edit profile, logout. This
  removes the leaked @if and de-clutters the menu.
- Dashboard menu is centralized in _PanelNav and auto-rendered by the
  layout on every logged-in panel page (/Admin, /Me, /Employer,
  /Preferences) instead of being duplicated in the dropdown and pages.
- Drop the now-duplicate manual <partial name="_PanelNav" /> from
  Overview, Ingested, Me/Index, Employer/Index.
- CSS: identity-card (.pd-id) styles + mobile tweaks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 07:33:22 +03:30
soroush.asadi 3d128ea051 [Brand] Branded favicon + icon links in <head>
CI/CD / CI · dotnet build (push) Successful in 1m43s
CI/CD / Deploy · hamkadr (push) Failing after 1m35s
Replace the default ASP.NET favicon.ico with one generated from the همکادر brand icon (multi-size 16/32/48/64), add favicon-32.png, and wire <link rel=icon> (ico + png 32/192) in the layout head so browsers and Google show the brand mark.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 06:28:01 +03:30
soroush.asadi 33c13ec524 [Dashboard] Panel sub-nav menu + clearer profile button (name, not phone digit)
CI/CD / CI · dotnet build (push) Successful in 2m11s
CI/CD / Deploy · hamkadr (push) Failing after 2m37s
Logged-in panels (admin/employer/job-seeker) now show a sticky role-based dashboard menu (_PanelNav) on Employer/Index, Me/Index and Admin/Overview, with the active section highlighted — so users have an obvious menu and dashboard, not just a hidden avatar. Profile button: avatar fallback shows a 👤 glyph instead of the phone's first digit (the confusing '0'), and the desktop button now shows the user's name (or «حساب من») so it reads as a profile menu.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 22:12:51 +03:30
soroush.asadi 69e4f305e9 [Nav] Add ثبت آگهی CTA, streamline menu, active-link highlight, role dashboards
CI/CD / CI · dotnet build (push) Successful in 3m26s
CI/CD / Deploy · hamkadr (push) Failing after 2m41s
Header gets a prominent accent +ثبت آگهی CTA → /Employer/Index (auth redirect handles login → register/post). Main nav trimmed to the 5 core public links (خانه/شیفت‌ها/استخدام/مراکز/تقویم); دریافت اپ + راهنما live in the footer and علاقه‌مندی‌ها in the profile menu, so the bar is far less crowded. Added active-page highlight (accent underline on desktop, soft background on mobile). Login now sends admins to /Admin/Overview (dashboard) instead of the ingestion queue; employers→/Employer/Index, job-seekers→/Me already in place.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 21:38:08 +03:30
soroush.asadi 6af6a026a1 [SEO] JobPosting structured data, canonical/OG meta, noindex private pages, fuller sitemap
CI/CD / CI · dotnet build (push) Successful in 59s
CI/CD / Deploy · hamkadr (push) Successful in 2m27s
Strategy = Google-for-Jobs + clean indexing. Add schema.org JobPosting JSON-LD to shift & job detail pages (title, description, datePosted, validThrough, employmentType, hiringOrganization, jobLocation, baseSalary) plus Organization + WebSite JSON-LD on the home page (SeoJsonLd helper; System.Text.Json => valid, script-safe). Layout emits per-page canonical, Open Graph + Twitter cards, and applies robots noindex,nofollow to all private/applicant areas (/Admin,/Me,/Employer,/Account,/Preferences) so applicant data is never indexed. robots.txt now disallows those + /resume,/avatar,/report,/push,/notifications and points at the sitemap; sitemap.xml adds facility pages + content pages (Download/Help/Privacy/Rules/Terms).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 08:16:30 +03:30
soroush.asadi e633463906 [Profile] Editable profile (avatar + resume) + role-based profile dropdown menu
CI/CD / CI · dotnet build (push) Successful in 44s
CI/CD / Deploy · hamkadr (push) Successful in 57s
Every user gets a full editable profile at /Me/Profile: name, role, city, specialty/title, license, years, bio + avatar image upload + resume upload (PDF/image). Avatar/resume stored in-DB on User (migration, 5 nullable columns). Endpoints: /avatar/{id} (public) and /resume/{id} (owner, admin, or an employer who received that user's application). Nav: replaced the scattered action links with an avatar button + dropdown listing all of the user's pages by role (profile, کارجو panel, alerts, preferences, notifications; employer panel; admin panel + settings; logout) — shows the avatar image or initials; collapses into the burger menu on mobile; closes on outside-click.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 21:49:40 +03:30
soroush.asadi 698565c460 [Help] Add help/learning page + interactive guided app tour
CI/CD / CI · dotnet build (push) Successful in 46s
CI/CD / Deploy · hamkadr (push) Successful in 1m10s
New /Help page: quick-start, separate guides for کادر درمان (search/near-me/preferences/اعلام تمایل/saved) and مراکز درمانی (register/post/verify-with-docs/applicants), notifications+install, report/complaint, and an FAQ accordion. Self-hosted tour.js (no CDN, RTL): spotlights elements via data-tour hooks in the nav, auto-runs once for new visitors on the home page (localStorage flag), re-runnable from the Help page button or ?tour=1; skips steps whose target is hidden so it works on mobile/other pages. Help linked from nav + footer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:39:03 +03:30
soroush.asadi c7e4bf059e [Legal] Add Privacy, Rules, and Terms of Use pages (Persian/RTL) + footer links
CI/CD / CI · dotnet build (push) Successful in 1m0s
CI/CD / Deploy · hamkadr (push) Successful in 1m11s
Three policy pages tailored to همکادر: /Privacy (data collected, use, sharing, no Google services, cookies, security), /Rules (accurate info, allowed listings, conduct, prohibited content, verification badge meaning, reports), /Terms (intermediary nature/no employment guarantee, account terms, scraped-listing disclaimer, liability, IP, governing law = Iran). Linked from the footer; .legal long-form reading style added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 16:48:10 +03:30
soroush.asadi 716433ce20 [Notify] Add live in-app notifications over SSE (Iran-friendly)
CI/CD / CI · dotnet build (push) Has been cancelled
CI/CD / Deploy · hamkadr (push) Has been cancelled
Web Push is delivered by the browser vendor's push service (Chrome to Google FCM), which is filtered in Iran, so background push is unreliable. Add a Server-Sent Events channel over our own origin that always reaches users while the tab/PWA is open: NotificationHub (in-memory pub/sub), a /notifications/stream SSE endpoint (auth-gated, keep-alive pings, nginx no-buffer), and NotificationService now publishes each saved notification to the hub. Client updates the bell badge instantly, shows a toast, and fires a local OS notification via the service worker when permission is granted (no push server). Web Push stays as best-effort for closed-app reach. Verified end-to-end: login, open stream, broadcast, event delivered.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:42:16 +03:30
soroush.asadi d2a7b18cb3 [UI] Fix navbar bell Razor leak, add Settings link, tidy desktop bar
CI/CD / CI · dotnet build (push) Successful in 1m13s
CI/CD / Deploy · hamkadr (push) Successful in 56s
Wrap the bell label in a span so the conditional parses as Razor code instead of leaking as literal text (Persian word char before the at-sign triggered email detection). Bell is icon-only on desktop, label shows in the mobile dropdown. Add a Settings link to admin actions so the demo-mode page is reachable from the navbar. Tighten desktop nav/action spacing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:06:44 +03:30
soroush.asadi 9e047c96ed [UI] Responsive hamburger nav for mobile
CI/CD / CI · dotnet build (push) Failing after 1m40s
CI/CD / Deploy · hamkadr (push) Has been skipped
- _Layout: wrap nav + actions in .nav-collapse; add CSS-only burger
  (checkbox toggle) + always-visible mobile bell next to it
- site.css: desktop layout unchanged; <=860px collapses nav into a
  full-width dropdown (column links, stacked actions), animated open
- Login (ورود) + logout render as full-width buttons in the menu
  instead of overflowing the header row

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 14:07:22 +03:30
soroush.asadi eae38373b9 Admin suite: monitoring dashboard, user management/ban, broadcast, reports, SMS test
CI/CD / CI · dotnet build (push) Failing after 1m40s
CI/CD / Deploy · hamkadr (push) Has been skipped
- /Admin/Overview: platform monitoring stats (users by role, facilities, listings, applies, push subs, queue, reports, bans)
- /Admin/Users: search/filter + ban/unban (User.IsBanned + reason); banned users blocked at login
- /Admin/Broadcast: send announcement (in-app + web push) to all / staff / employers via NotificationService
- Reports: report button on shift/job detail → /report endpoint → /Admin/Reports (resolve/dismiss)
- Settings: 'send test SMS' button; admin cross-nav links; SMS API config already in place
- migration AdminBanReports; verified overview/users/broadcast/report persist

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 13:19:20 +03:30
soroush.asadi 10d4727bd5 Notify matching users when a new shift/job is posted (in-app notifications)
CI/CD / CI · dotnet build (push) Failing after 1m40s
CI/CD / Deploy · hamkadr (push) Has been skipped
- Notification entity + NotificationService: on publish, notify users whose saved prefs match the listing (role/city/+shift type); users with no preference aren't spammed
- Wired into PostShift, PostJob, and Admin Review publish
- 🔔 bell with unread count in the header (@inject) + /Me/Notifications page (mark-all-read on open)
- Reliable in-app delivery (works in Iran without FCM); Web Push can ride the same records later
- Verified: employee pref → employer posts matching shift → employee bell=۱ + 'شیفت جدید: پزشک عمومی'

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 11:56:07 +03:30
soroush.asadi a02eb6a985 PWA: installable app (web/win/android/ios) + download/help page + push notifications
CI/CD / CI · dotnet build (push) Successful in 40s
CI/CD / Deploy · hamkadr (push) Successful in 55s
- manifest.webmanifest + service worker (offline shell + push + notificationclick) + PNG icons (192/512/apple) + iOS meta + SW registration → installable everywhere
- /Download page: per-OS install help (web/windows/android/ios), install button (beforeinstallprompt), 'enable notifications' flow, usage guide, Bazaar/TWA note; nav + footer links
- Web Push foundation: WebPushSubscription entity + /push/subscribe (stores), VAPID + push settings in /Admin/Settings, on-device local notification; server broadcast documented (WebPush via Nexus)
- docs/PWA-TWA.md: VAPID keygen, server-push wiring, Bubblewrap→Cafe Bazaar + assetlinks steps
- Verified: manifest/sw/icons served, download page, subscribe stores (200), layout wired

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 11:23:13 +03:30
soroush.asadi 6cfdd16c42 Add gender requirement (آقا/خانم/فرقی نمی‌کند) + employee (کارجو) panel
CI/CD / CI · dotnet build (push) Successful in 6m23s
CI/CD / Deploy · hamkadr (push) Failing after 6m30s
- Gender enum + GenderRequirement on Shift/JobOpening + Gender on UserPreferences (migration)
- Employer PostShift/PostJob + admin Review have a gender select; parser detects آقا/خانم/مرد/زن
- Gender badge on cards + detail; gender filter on Shifts/Jobs; gender in preferences
- Recommendations exclude listings whose gender requirement conflicts with the person's gender
- Two panels: new /Me employee (کارجو) panel (recommendations + saved + applied + prefs) alongside /Employer; nav routes by role; /Account/Profile → /Me

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 00:19:32 +03:30
soroush.asadi 563a40d1f4 Add hiring, AI parser+admin, OTP auth, employer dashboard, profit-share pay
- Hiring (استخدام) listings: JobOpening + /Jobs browse/detail + home section
- Heuristic Persian listing-parser + admin queue (/Admin) → publish shift/job
- Phone-OTP cookie auth + visitor-history linking + profile; Admin role gate
- Employer side: self-serve facility registration, dashboard, post/manage shifts & jobs, applicants list with contact
- Compensation models: fixed / hourly / profit-share (درصدی) / negotiable / choice (به انتخاب شما); SharePercent + JalaliDate.PayLabel; parser + filter

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 06:26:54 +03:30
soroush.asadi 2fb86a435e Initial commit — Hamkadr (همکادر) healthcare-staffing marketplace
ASP.NET Core 10 Razor Pages + PostgreSQL/EF Core. RTL Persian, Jalali dates, self-hosted Vazirmatn, teal/coral brand.

Features:
- Shift listings: browse/filter (city, district, role, type, pay), weekly Jalali calendar, detail + interest handoff, near-me distance sort
- Hiring (استخدام) listings with employment type + salary range
- Pattern-engine recommendations + anonymous interest tracking (visitor cookie)
- Heuristic Persian listing-parser + admin queue (raw channel post → shift/job)
- Phone-OTP cookie auth + visitor-history linking + profile

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 01:44:24 +03:30