diff --git a/.env.example b/.env.example index 2f3a864..a110ad9 100644 --- a/.env.example +++ b/.env.example @@ -97,6 +97,24 @@ NUXT_PUBLIC_SITE_URL=http://localhost:3000 # Display name for the SSO button (default: "SSO") # OIDC_PROVIDER_NAME=Company SSO +# ─── Optional: Transactional Email ─────────────────────────────────────────── +# Reqcore logs emails to the console by default (safe for local dev). +# For production, configure one of the providers below. +# SMTP takes priority over Resend when SMTP_HOST is set. + +# Option A: SMTP (recommended for self-hosted / enterprise setups) +# Supports any SMTP server: Postfix, Gmail, Exchange, Mailcow, Mailu, etc. +# SMTP_HOST=smtp.example.com +# SMTP_PORT=587 +# SMTP_USER=reqcore@example.com +# SMTP_PASS=your-smtp-password +# SMTP_FROM="Reqcore " +# SMTP_SECURE=false # true = implicit TLS (port 465), false = STARTTLS (port 587) + +# Option B: Resend (free tier: 3,000 emails/month — resend.com) +# RESEND_API_KEY=re_xxxxxxxxxxxx +# RESEND_FROM_EMAIL="Reqcore " + # ─── Optional: Social Sign-In (Google, GitHub, Microsoft) ──────────────────── # Enable social login buttons on the sign-in and sign-up pages. # Each provider requires both CLIENT_ID and CLIENT_SECRET to be set. diff --git a/.gitignore b/.gitignore index a0a1fec..b53fecd 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ test-results/ playwright-report/ blob-report/ playwright/.cache/ +.playwright-mcp/ *.code-workspace diff --git a/SELF-HOSTING.md b/SELF-HOSTING.md index 50813f3..cc487cc 100644 --- a/SELF-HOSTING.md +++ b/SELF-HOSTING.md @@ -440,7 +440,37 @@ docker compose up --build -d By default, Reqcore logs email content to the console (useful for development). For production, configure a transactional email service. -### Using Resend (Recommended) +**Priority:** When `SMTP_HOST` is set, SMTP is used. Otherwise, if `RESEND_API_KEY` is set, Resend is used. If neither is configured, emails are logged to the console. + +### Option A: SMTP (recommended for self-hosted setups) + +SMTP works with any mail server — Postfix, Gmail, Exchange, Mailcow, Mailu, etc. No external service dependency. + +1. Add to your `.env` file: + +```bash +SMTP_HOST=smtp.example.com +SMTP_PORT=587 +SMTP_USER=reqcore@example.com +SMTP_PASS=your-smtp-password +SMTP_FROM="Reqcore " +SMTP_SECURE=false # true for implicit TLS (port 465), false for STARTTLS (port 587) +``` + +2. Restart: `docker compose up --build -d` + +**Common setups:** + +| Provider | SMTP_HOST | SMTP_PORT | SMTP_SECURE | +|---|---|---|---| +| Gmail (App Password) | `smtp.gmail.com` | `587` | `false` | +| Outlook / Office 365 | `smtp.office365.com` | `587` | `false` | +| Mailcow / Mailu | your server hostname | `587` | `false` | +| Custom Postfix | your server hostname | `587` or `465` | `false` / `true` | + +> For Gmail, generate an [App Password](https://support.google.com/accounts/answer/185833) — your regular Gmail password will not work. + +### Option B: Resend 1. Sign up at [resend.com](https://resend.com) (free tier: 3,000 emails/month) 2. Verify your sending domain @@ -454,11 +484,6 @@ RESEND_FROM_EMAIL="Reqcore " 5. Restart: `docker compose up --build -d` -This enables: -- Team member invitation emails -- Interview scheduling notifications -- Candidate communication emails - --- ## Security Best Practices diff --git a/app/components/AppTopBar.vue b/app/components/AppTopBar.vue index b8dce83..e87f0f0 100644 --- a/app/components/AppTopBar.vue +++ b/app/components/AppTopBar.vue @@ -144,6 +144,22 @@ watch(() => route.path, () => { showGetStartedMenu.value = false }) +// ───────────────────────────────────────────── +// New Job button +// ───────────────────────────────────────────── + +const newJobResetSignal = useState('new-job-reset-signal', () => 0) + +function handleNewJobClick() { + const newJobPath = localePath('/dashboard/jobs/new') + if (route.path === newJobPath) { + // Already on the page: signal the wizard to reset instead of navigating + newJobResetSignal.value++ + } else { + navigateTo(newJobPath) + } +} + // Close user menu on outside click const userMenuRef = useTemplateRef('userMenuRoot') function onClickOutsideUser(e: MouseEvent) { @@ -264,13 +280,13 @@ onUnmounted(() => { - +