v0.0.2: pre-productie (Bootstrap 5.3.3, LightPdf klant-PDF, server-setup en release-script)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bffa053c05
commit
7d302dc405
+92
-84
@@ -3,101 +3,109 @@
|
||||
{% block content %}
|
||||
<div class="head">
|
||||
<div><div class="kicker">Overzicht</div><h1>Dashboard</h1></div>
|
||||
<a class="btn" href="{{ url_for('contact_new') }}">Nieuw contact</a>
|
||||
<div class="actions"><a class="btn btn-primary" href="{{ url_for('contact_new') }}">Nieuw contact</a></div>
|
||||
</div>
|
||||
|
||||
<div class="kpis">
|
||||
<div class="kpi"><div class="label">Nieuwe leads · 30 dagen</div><div class="value">{{ stats.new30 }}</div><div class="muted">{{ stats.customers }} klantrelaties · {{ stats.partners }} partners</div></div>
|
||||
<div class="kpi"><div class="label">Open leads</div><div class="value">{{ stats.open_leads }}</div>
|
||||
<div class="muted">{{ stats.pipeline_value|euro }} verwacht{% if stats.unassigned %} · <a href="{{ url_for('contacts', type='lead', owner='none') }}">{{ stats.unassigned }} niet toegewezen</a>{% endif %}</div></div>
|
||||
<div class="kpi"><div class="label">Open offertes</div><div class="value">{{ stats.open_quotes }}</div><div class="muted">{{ stats.open_value|euro }} excl. btw</div></div>
|
||||
<div class="kpi"><div class="label">Gewonnen · 30 dagen</div><div class="value">{{ stats.won_value|euro }}</div><div class="muted">excl. btw</div></div>
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-sm-6 col-xl-3"><div class="kpi"><div class="label">Nieuwe leads · 30 dagen</div><div class="value">{{ stats.new30 }}</div><div class="muted">{{ stats.customers }} klantrelaties · {{ stats.partners }} partners</div></div></div>
|
||||
<div class="col-sm-6 col-xl-3"><div class="kpi"><div class="label">Open leads</div><div class="value">{{ stats.open_leads }}</div>
|
||||
<div class="muted">{{ stats.pipeline_value|euro }} verwacht{% if stats.unassigned %} · <a href="{{ url_for('contacts', type='lead', owner='none') }}">{{ stats.unassigned }} niet toegewezen</a>{% endif %}</div></div></div>
|
||||
<div class="col-sm-6 col-xl-3"><div class="kpi"><div class="label">Open offertes</div><div class="value">{{ stats.open_quotes }}</div><div class="muted">{{ stats.open_value|euro }} excl. btw</div></div></div>
|
||||
<div class="col-sm-6 col-xl-3"><div class="kpi"><div class="label">Gewonnen · 30 dagen</div><div class="value">{{ stats.won_value|euro }}</div><div class="muted">excl. btw</div></div></div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="card">
|
||||
<h2>Leads per status</h2>
|
||||
<div class="bars">
|
||||
{% for key, label, n in pipeline %}
|
||||
<a class="bar" href="{{ url_for('contacts', type='lead', status=key) }}">
|
||||
<span>{{ label }}</span>
|
||||
<span class="track"><span class="fill" style="width: {{ (n / pipe_max * 100)|round(1) }}%"></span></span>
|
||||
<span class="num">{{ n }}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>Leads per week</h2>
|
||||
<div class="cols">
|
||||
{% for wk, n in weekly %}
|
||||
<div title="Week {{ wk }}: {{ n }} lead(s)">
|
||||
<span>{{ n or '' }}</span>
|
||||
<span class="c" style="height: {{ (n / week_max * 75)|round(1) }}%"></span>
|
||||
<span>{{ wk }}</span>
|
||||
<div class="row g-4 mb-4 card-grid">
|
||||
<div class="col-md-6 col-xxl-4">
|
||||
<div class="card"><div class="card-body">
|
||||
<h2>Leads per status</h2>
|
||||
<div class="bars">
|
||||
{% for key, label, n in pipeline %}
|
||||
<a class="bar" href="{{ url_for('contacts', type='lead', status=key) }}">
|
||||
<span>{{ label }}</span>
|
||||
<span class="track"><span class="fill" style="width: {{ (n / pipe_max * 100)|round(1) }}%"></span></span>
|
||||
<span class="num">{{ n }}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>Bronnen</h2>
|
||||
{% if sources %}
|
||||
<div class="bars">
|
||||
{% for s in sources %}
|
||||
<div class="bar">
|
||||
<span title="{{ s.s }}" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap">{{ s.s }}</span>
|
||||
<span class="track"><span class="fill" style="width: {{ (s.n / source_max * 100)|round(1) }}%"></span></span>
|
||||
<span class="num">{{ s.n }}</span>
|
||||
<div class="col-md-6 col-xxl-4">
|
||||
<div class="card"><div class="card-body">
|
||||
<h2>Leads per week</h2>
|
||||
<div class="cols">
|
||||
{% for wk, n in weekly %}
|
||||
<div title="Week {{ wk }}: {{ n }} lead(s)">
|
||||
<span>{{ n or '' }}</span>
|
||||
<span class="c" style="height: {{ (n / week_max * 75)|round(1) }}%"></span>
|
||||
<span>{{ wk }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}<p class="empty">Nog geen leads.</p>{% endif %}
|
||||
</div></div>
|
||||
</div>
|
||||
<div class="col-md-12 col-xxl-4">
|
||||
<div class="card"><div class="card-body">
|
||||
<h2>Bronnen</h2>
|
||||
{% if sources %}
|
||||
<div class="bars">
|
||||
{% for s in sources %}
|
||||
<div class="bar">
|
||||
<span title="{{ s.s }}">{{ s.s }}</span>
|
||||
<span class="track"><span class="fill" style="width: {{ (s.n / source_max * 100)|round(1) }}%"></span></span>
|
||||
<span class="num">{{ s.n }}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}<p class="empty">Nog geen leads.</p>{% endif %}
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="two">
|
||||
<div class="card">
|
||||
<h2>Laatste leads</h2>
|
||||
{% if recent %}
|
||||
<div class="table-wrap"><table>
|
||||
<thead><tr><th>Naam</th><th>Bron</th><th>Toegewezen</th><th>Status</th><th>Binnen</th></tr></thead>
|
||||
<tbody>
|
||||
{% for c in recent %}
|
||||
<tr class="link" onclick="location='{{ url_for('contact_view', cid=c.id) }}'">
|
||||
<td><a href="{{ url_for('contact_view', cid=c.id) }}">{{ c.name }}</a><div class="muted">{{ c.email }}</div></td>
|
||||
<td>{{ c.source }}</td>
|
||||
<td>{{ c.user_name or '—' }}</td>
|
||||
<td><span class="chip {{ c.status }}">{{ STATUS.get(c.status, c.status) }}</span></td>
|
||||
<td class="muted">{{ c.created_at|dt }}</td>
|
||||
</tr>
|
||||
<div class="row gx-4">
|
||||
<div class="col-xl-8">
|
||||
<div class="card"><div class="card-body">
|
||||
<h2>Laatste leads</h2>
|
||||
{% if recent %}
|
||||
<div class="table-responsive"><table class="table table-hover table-stack">
|
||||
<thead><tr><th>Naam</th><th>Bron</th><th>Toegewezen</th><th>Status</th><th>Binnen</th></tr></thead>
|
||||
<tbody>
|
||||
{% for c in recent %}
|
||||
<tr class="link" onclick="location='{{ url_for('contact_view', cid=c.id) }}'">
|
||||
<td class="stack-title"><a href="{{ url_for('contact_view', cid=c.id) }}">{{ c.name }}</a><div class="muted">{{ c.email }}</div></td>
|
||||
<td data-label="Bron">{{ c.source }}</td>
|
||||
<td data-label="Toegewezen">{{ c.user_name or '—' }}</td>
|
||||
<td data-label="Status"><span class="chip {{ c.status }}">{{ STATUS.get(c.status, c.status) }}</span></td>
|
||||
<td data-label="Binnen" class="muted">{{ c.created_at|dt }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table></div>
|
||||
{% else %}<p class="empty">Nog geen contacten. Voeg er een toe of koppel een formulier via Instellingen.</p>{% endif %}
|
||||
</div></div>
|
||||
</div>
|
||||
<div class="col-xl-4">
|
||||
<div class="card"><div class="card-body">
|
||||
<h2>Mijn taken</h2>
|
||||
{% for t in tasks %}
|
||||
<form method="post" action="{{ url_for('task_done', tid=t.id) }}" class="task">
|
||||
<button class="check" aria-label="Afronden"></button>
|
||||
<div><div>{{ t.title }}</div>
|
||||
<div class="muted">{% if t.contact_id %}<a href="{{ url_for('contact_view', cid=t.contact_id) }}">{{ t.contact_name }}</a>{% endif %}
|
||||
{% if t.due_date %}· <span class="{{ 'overdue' if t.due_date < today }}">{{ t.due_date|dt('%d-%m-%Y') }}</span>{% endif %}</div></div>
|
||||
</form>
|
||||
{% else %}
|
||||
<p class="empty">Geen openstaande taken.</p>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table></div>
|
||||
{% else %}<p class="empty">Nog geen contacten. Voeg er een toe of koppel een formulier via Instellingen.</p>{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
<div class="card">
|
||||
<h2>Mijn taken</h2>
|
||||
{% for t in tasks %}
|
||||
<form method="post" action="{{ url_for('task_done', tid=t.id) }}" class="task">
|
||||
<button class="check" aria-label="Afronden"></button>
|
||||
<div><div>{{ t.title }}</div>
|
||||
<div class="muted">{% if t.contact_id %}<a href="{{ url_for('contact_view', cid=t.contact_id) }}">{{ t.contact_name }}</a>{% endif %}
|
||||
{% if t.due_date %}· <span class="{{ 'overdue' if t.due_date < today }}">{{ t.due_date|dt('%d-%m-%Y') }}</span>{% endif %}</div></div>
|
||||
</form>
|
||||
{% else %}
|
||||
<p class="empty">Geen openstaande taken.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>Ongelezen e-mail</h2>
|
||||
{% for e in mails %}
|
||||
<p><a href="{{ url_for('inbox_view', eid=e.id) }}">{{ e.subject }}</a><br><span class="muted">{{ e.from_name or e.from_addr }} · {{ e.date|dt }}</span></p>
|
||||
{% else %}
|
||||
<p class="empty">Geen ongelezen berichten.</p>
|
||||
{% endfor %}
|
||||
<a href="{{ url_for('inbox') }}">Naar inbox</a>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class="card"><div class="card-body">
|
||||
<h2>Ongelezen e-mail</h2>
|
||||
{% for e in mails %}
|
||||
<p><a href="{{ url_for('inbox_view', eid=e.id) }}">{{ e.subject }}</a><br><span class="muted">{{ e.from_name or e.from_addr }} · {{ e.date|dt }}</span></p>
|
||||
{% else %}
|
||||
<p class="empty">Geen ongelezen berichten.</p>
|
||||
{% endfor %}
|
||||
<a href="{{ url_for('inbox') }}">Naar inbox</a>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user