nordabiz/templates/board/fees_readonly.html
Maciej Pienczyn ec60b50496
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
fix(fees): usunięto przykładową kwotę 500 zł z legendy zaległości
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 15:37:09 +01:00

286 lines
12 KiB
HTML

{% extends "base.html" %}
{% block title %}Składki Członkowskie - Rada Izby{% endblock %}
{% block extra_css %}
<style>
.admin-header {
margin-bottom: var(--spacing-xl);
}
.admin-header h1 {
font-size: var(--font-size-3xl);
color: var(--text-primary);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: var(--spacing-lg);
margin-bottom: var(--spacing-2xl);
}
.stat-card {
background: var(--surface);
padding: var(--spacing-sm) var(--spacing-md);
border-radius: var(--radius);
box-shadow: var(--shadow);
text-align: center;
}
.stat-card.success { border-left: 3px solid var(--success); }
.stat-card.warning { border-left: 3px solid var(--warning); }
.stat-card.primary { border-left: 3px solid var(--primary); }
.stat-value {
font-size: var(--font-size-xl);
font-weight: 700;
color: var(--primary);
}
.stat-label {
color: var(--text-secondary);
font-size: var(--font-size-sm);
margin-top: var(--spacing-xs);
}
.filters-bar {
background: var(--surface);
padding: var(--spacing-lg);
border-radius: var(--radius-lg);
box-shadow: var(--shadow);
margin-bottom: var(--spacing-xl);
display: flex;
gap: var(--spacing-md);
flex-wrap: wrap;
align-items: center;
}
.filters-bar select {
padding: var(--spacing-sm) var(--spacing-md);
border: 1px solid var(--border);
border-radius: var(--radius-md);
font-size: var(--font-size-sm);
}
.section {
background: var(--surface);
padding: var(--spacing-xl);
border-radius: var(--radius-lg);
box-shadow: var(--shadow);
margin-bottom: var(--spacing-xl);
}
.fees-table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
.fees-table th,
.fees-table td {
padding: var(--spacing-xs) var(--spacing-sm);
text-align: center;
border-bottom: 1px solid var(--border);
}
.fees-table th:first-child,
.fees-table td:first-child {
text-align: left;
width: 160px;
}
.fees-table th.col-month,
.fees-table td.col-month {
width: 36px;
padding: var(--spacing-xs) 2px;
}
.fees-table th {
font-weight: 600;
color: var(--text-secondary);
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0;
background: var(--background);
}
.fees-table tr:hover {
background: var(--background);
}
.month-cell {
width: 26px;
height: 26px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-sm);
font-size: 10px;
font-weight: 600;
}
.month-cell.paid { background: var(--success); color: white; }
.month-cell.partial { background: #60a5fa; color: white; }
.month-cell.pending { background: var(--warning); color: white; }
.month-cell.overdue { background: var(--error); color: white; }
.month-cell.empty { background: var(--surface-secondary); color: var(--text-secondary); }
.partial-badge {
position: absolute;
top: -6px;
right: -6px;
background: #ef4444;
color: white;
font-size: 8px;
font-weight: 700;
padding: 1px 3px;
border-radius: 6px;
line-height: 1;
transform: rotate(12deg);
min-width: 14px;
text-align: center;
}
.readonly-badge {
display: inline-block;
background: var(--info-bg);
color: var(--info);
font-size: var(--font-size-xs);
padding: 2px 8px;
border-radius: var(--radius-full);
font-weight: 600;
margin-left: var(--spacing-sm);
vertical-align: middle;
}
</style>
{% endblock %}
{% block content %}
<div class="container">
<div class="admin-header">
<h1>
<svg width="32" height="32" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
Strefa RADA <span class="readonly-badge">tylko podgląd</span>
</h1>
</div>
<!-- Board sub-navigation -->
<div style="display:flex;gap:0;margin-bottom:var(--spacing-xl);border-bottom:2px solid var(--border);">
<a href="{{ url_for('board.index') }}" style="padding:10px 20px;font-weight:500;font-size:var(--font-size-sm);text-decoration:none;border-bottom:2px solid transparent;color:var(--text-secondary);">Posiedzenia</a>
<a href="{{ url_for('board.board_fees') }}" style="padding:10px 20px;font-weight:500;font-size:var(--font-size-sm);text-decoration:none;border-bottom:2px solid var(--primary);color:var(--primary);margin-bottom:-2px;">Składki członkowskie</a>
</div>
<!-- Stats -->
<div class="stats-grid">
<div class="stat-card primary">
<div class="stat-value">{{ total_companies }}</div>
<div class="stat-label">Firm członkowskich</div>
</div>
<div class="stat-card success">
<div class="stat-value">{{ paid_count }}</div>
<div class="stat-label">Opłaconych składek (łącznie)</div>
</div>
<div class="stat-card warning">
<div class="stat-value">{{ pending_count }}</div>
<div class="stat-label">Oczekujących składek (łącznie)</div>
</div>
<div class="stat-card success">
<div class="stat-value">{{ total_paid|int }} zł</div>
<div class="stat-label">Zebrano</div>
</div>
<div class="stat-card warning">
<div class="stat-value">{{ (total_due - total_paid)|int }} zł</div>
<div class="stat-label">Do zebrania</div>
</div>
</div>
<!-- Legenda -->
<div style="display: flex; gap: var(--spacing-lg); flex-wrap: wrap; margin-bottom: var(--spacing-md); font-size: var(--font-size-sm); color: var(--text-secondary); align-items: center;">
<span style="display: flex; align-items: center; gap: 4px;"><span class="month-cell paid" style="width: 24px; height: 24px; font-size: 11px;">1</span> Opłacone</span>
<span style="display: flex; align-items: center; gap: 4px;"><span class="month-cell partial" style="width: 24px; height: 24px; font-size: 11px;">1</span> Niepełna wpłata</span>
<span style="display: flex; align-items: center; gap: 4px;"><span class="month-cell pending" style="width: 24px; height: 24px; font-size: 11px;">1</span> Oczekujące</span>
<span style="display: flex; align-items: center; gap: 4px;"><span class="month-cell overdue" style="width: 24px; height: 24px; font-size: 11px;">1</span> Zaległe</span>
<span style="display: flex; align-items: center; gap: 4px;"><span class="month-cell empty" style="width: 24px; height: 24px; font-size: 11px;">-</span> Brak danych</span>
<span style="display: flex; align-items: center; gap: 4px; border-left: 1px solid var(--border); padding-left: var(--spacing-lg);"><span style="color:var(--error);font-weight:700;font-size:12px;"></span> Zaległości z lat poprzednich</span>
</div>
<!-- Filters -->
<div class="filters-bar">
<form method="GET" action="{{ url_for('board.board_fees') }}" style="display: flex; gap: var(--spacing-md); flex-wrap: wrap; align-items: center;">
<select name="year" onchange="this.form.submit()">
{% for y in years %}
<option value="{{ y }}" {% if y == year %}selected{% endif %}>{{ y }}</option>
{% endfor %}
</select>
<select name="status" onchange="this.form.submit()">
<option value="">-- Wszystkie firmy --</option>
<option value="paid" {% if status_filter == 'paid' %}selected{% endif %}>Opłacone za cały rok</option>
<option value="partial" {% if status_filter == 'partial' %}selected{% endif %}>Częściowo opłacone</option>
<option value="none" {% if status_filter == 'none' %}selected{% endif %}>Brak wpłat</option>
</select>
</form>
</div>
<!-- Companies Table -->
<div class="section">
<div class="section-header" style="display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--spacing-lg);">
<h2>Lista firm ({{ year }}) <span style="display:inline-flex;align-items:center;justify-content:center;background:var(--error);color:white;font-size:var(--font-size-sm);font-weight:700;min-width:28px;height:28px;border-radius:var(--radius-full);padding:0 8px;vertical-align:middle;margin-left:8px;">{{ companies_fees|length }}</span></h2>
</div>
<table class="fees-table">
<thead>
<tr>
<th>Firma</th>
<th class="col-month">I</th><th class="col-month">II</th><th class="col-month">III</th><th class="col-month">IV</th><th class="col-month">V</th><th class="col-month">VI</th>
<th class="col-month">VII</th><th class="col-month">VIII</th><th class="col-month">IX</th><th class="col-month">X</th><th class="col-month">XI</th><th class="col-month">XII</th>
<th style="width:70px;font-size:9px;line-height:1.2;">Zaległ.<br><span style="font-weight:400;text-transform:none;">z lat poprz.</span></th>
</tr>
</thead>
<tbody>
{% set ns = namespace(separator_shown=false) %}
{% for cf in companies_fees %}
{% if not cf.has_data and not ns.separator_shown %}
{% set ns.separator_shown = true %}
<tr><td colspan="14" style="background: var(--border); padding: var(--spacing-xs); text-align: center; font-size: var(--font-size-sm); color: var(--text-secondary); font-weight: 600;">Firmy bez danych o składkach</td></tr>
{% endif %}
<tr{% if not cf.has_data %} style="opacity: 0.5;"{% endif %}>
<td>
<span {% if not cf.has_data %}style="color: var(--text-secondary);"{% endif %}>
{{ cf.company.name }}
</span>
{% if cf.monthly_rate and cf.monthly_rate > 200 %}
<span style="display:inline-block;background:#dbeafe;color:#1e40af;font-size:10px;padding:1px 5px;border-radius:3px;font-weight:600;vertical-align:middle;margin-left:4px;">{{ cf.monthly_rate }} zł</span>
{% endif %}
</td>
{% for m in range(1, 13) %}
<td class="col-month">
{% set fee = cf.months.get(m) %}
{% if fee %}
<span class="month-cell {{ fee.status }}" title="{{ fee.status }}: wpłacono {{ fee.amount_paid|int }} z {{ fee.amount|int }} zł" style="position:relative;">
{{ m }}{% if fee.status == 'partial' %}<span class="partial-badge">{{ fee.amount_paid|int }}</span>{% endif %}
</span>
{% else %}
<span class="month-cell empty" title="Brak rekordu">-</span>
{% endif %}
</td>
{% endfor %}
<td>
{% set debt = cf.company.previous_years_debt|default(0)|float %}
{% if debt > 0 %}
<span style="color:var(--error);font-weight:700;font-size:13px;">{{ debt|int }} zł</span>
{% else %}
<span style="color:var(--text-secondary);font-size:11px;"></span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}