feat: Implement email sending utilities and templates for job notifications
Some checks failed
CI/CD Pipeline / test (push) Failing after 4m9s

- Added email_service.py for sending emails with SMTP configuration.
- Introduced email_templates.py to render job alert email subjects and bodies.
- Enhanced scraper.py to extract contact information from job listings.
- Updated settings.js to handle negative keyword input validation.
- Created email.html and email_templates.html for managing email subscriptions and templates in the admin interface.
- Modified base.html to include links for email alerts and templates.
- Expanded user settings.html to allow management of negative keywords.
- Updated utils.py to include functions for retrieving negative keywords and email settings.
- Enhanced job filtering logic to exclude jobs containing negative keywords.
This commit is contained in:
2025-11-28 18:15:08 +01:00
parent 8afb208985
commit 2185a07ff0
23 changed files with 2660 additions and 63 deletions

View File

@@ -0,0 +1,62 @@
{% extends 'base.html' %} {% block content %}
<h2>Email Subscriptions</h2>
<section>
<h3>Add Subscription</h3>
<form method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="hidden" name="action" value="subscribe" />
<label for="email">Email address</label>
<input
type="email"
id="email"
name="email"
placeholder="alerts@example.com"
required
/>
<button type="submit">Subscribe</button>
</form>
</section>
<section>
<h3>Current Recipients</h3>
{% if not subscriptions %}
<p>No subscriptions yet. Add one above to start sending alerts.</p>
<p>You can customize alert content from the <a href="{{ url_for('admin_email_templates') }}">Email Templates</a> page.</p>
{% else %}
<p>{{ total_active }} active of {{ total }} total.</p>
<table>
<thead>
<tr>
<th>Email</th>
<th>Status</th>
<th>Created</th>
<th>Updated</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for sub in subscriptions %}
<tr>
<td>{{ sub.email }}</td>
<td>{{ 'Active' if sub.is_active else 'Inactive' }}</td>
<td>{{ sub.created_at }}</td>
<td>{{ sub.updated_at }}</td>
<td>
<form method="post" style="display: inline-flex; gap: 0.5rem">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="hidden" name="email" value="{{ sub.email }}" />
{% if sub.is_active %}
<input type="hidden" name="action" value="unsubscribe" />
<button type="submit">Deactivate</button>
{% else %}
<input type="hidden" name="action" value="reactivate" />
<button type="submit">Reactivate</button>
{% endif %}
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</section>
{% endblock %}