v0.0.5: gedeelde mailboxen (info@, facturen@, nieuwsbrief@, persoonlijk) met eigen IMAP/SMTP, afzender, rol en toegang per gebruiker; inbox per mailbox en versturen vanuit een gekozen mailbox; routines (jobs.py: types met @jobs.register, interval, instellingen, logboek, slot tegen dubbel draaien; app.py scheduler/tick) voor e-mail ophalen, nieuwsbrieven versturen en opschonen; meldingen (bel, bureaubladmelding); nieuwsbrieven met segmenten, testmail, inplannen en versturen per batch over één verbinding, afmeldlink met List-Unsubscribe en bounceverwerking; oude mailinstellingen worden de eerste mailbox

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Machiel
2026-10-16 18:25:44 +02:00
co-authored by Claude Opus 5.5
parent 8f6e1ab443
commit cad838f1f4
24 changed files with 1710 additions and 185 deletions
+46
View File
@@ -0,0 +1,46 @@
{% extends 'base.html' %}
{% block title %}{{ name or 'Nieuw segment' }}{% endblock %}
{% macro checks(key, options, selected) %}
<div class="d-flex flex-wrap gap-3">{% for v, l in options %}<div class="form-check"><input class="form-check-input" type="checkbox" id="{{ key }}-{{ loop.index }}" name="{{ key }}" value="{{ v }}" {{ 'checked' if v in selected }}><label class="form-check-label" for="{{ key }}-{{ loop.index }}">{{ l }}</label></div>{% endfor %}</div>
{% endmacro %}
{% block content %}
<div class="head">
<div><a class="label" href="{{ url_for('segments') }}">← Segmenten</a><h1>{{ name or 'Nieuw segment' }}</h1></div>
</div>
<div class="row g-4">
<div class="col-lg-7">
<form method="post" class="card"><div class="card-body">
<div class="row g-3">
<div class="col-12"><label class="form-label" for="name">Naam *</label><input class="form-control" id="name" name="name" value="{{ name }}" placeholder="Bijvoorbeeld: Leads met een ontwerp"></div>
<div class="col-12"><span class="form-label d-block">Soort</span>{{ checks('types', TYPES, filters.types or []) }}</div>
<div class="col-12"><span class="form-label d-block">Status</span>{{ checks('statuses', STATUSES, filters.statuses or []) }}</div>
{% if sources %}<div class="col-12"><span class="form-label d-block">Bron</span>{{ checks('sources', sources, filters.sources or []) }}</div>{% endif %}
<div class="col-12"><span class="form-label d-block">Toegewezen aan</span>{{ checks('users', users, filters.users or []) }}</div>
<div class="col-md-4"><label class="form-label" for="city">Plaats bevat</label><input class="form-control" id="city" name="city" value="{{ filters.city or '' }}"></div>
<div class="col-6 col-md-4"><label class="form-label" for="created_from">Aangemaakt vanaf</label><input class="form-control" id="created_from" type="date" name="created_from" value="{{ filters.created_from or '' }}"></div>
<div class="col-6 col-md-4"><label class="form-label" for="created_to">tot en met</label><input class="form-control" id="created_to" type="date" name="created_to" value="{{ filters.created_to or '' }}"></div>
<div class="col-12"><div class="form-check"><input class="form-check-input" type="checkbox" id="has_design" name="has_design" value="1" {{ 'checked' if filters.has_design }}><label class="form-check-label" for="has_design">Alleen met een gekozen woningontwerp</label></div></div>
</div>
<p class="hint">Niets aangevinkt bij een onderdeel = geen beperking daarop.</p>
<div class="actions">
<button class="btn btn-primary" name="action" value="save">Opslaan</button>
<button class="btn btn-outline-primary" name="action" value="preview">Ontvangers tellen</button>
</div>
</div></form>
{% if seg %}
<form method="post" action="{{ url_for('segment_delete', sid=seg.id) }}" onsubmit="return confirm('Segment verwijderen? Nieuwsbrieven die het gebruiken houden hun vastgelegde ontvangers.')">
<button class="btn btn-outline-secondary btn-sm">Segment verwijderen</button>
</form>
{% endif %}
</div>
<div class="col-lg-5">
<div class="card"><div class="card-body">
<h2>{{ count }} ontvanger{{ '' if count == 1 else 's' }}</h2>
{% if sample %}
<ul class="timeline">{% for c in sample %}<li><a href="{{ url_for('contact_view', cid=c.id) }}">{{ c.name or c.email }}</a><br><span class="muted">{{ c.email }}{% if c.city %} · {{ c.city }}{% endif %}</span></li>{% endfor %}</ul>
{% if count > sample|length %}<p class="hint">En nog {{ count - sample|length }}.</p>{% endif %}
{% else %}<p class="empty">Geen contacten met deze filters.</p>{% endif %}
</div></div>
</div>
</div>
{% endblock %}