Add address fields, e-invoice, stats and auto-backup

- Split address into street, postal code, city (sortable)
- Add billing postal code/city fields
- Add e-invoice address and operator fields
- Add trivia stats (top postal code, top speed, avg price)
- Improved layout with stat cards grid and max-width container
- Sticky header, modal animations, search icon
- Auto-backup on every save (keeps last 30 backups)
- Footer added

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 00:01:43 +02:00
parent 297ba39c4f
commit 127b581a69
5 changed files with 595 additions and 202 deletions

View File

@@ -24,8 +24,13 @@
<div id="dashboard" style="display:none">
<header>
<div class="header-left">
<h1>CuituNet Intra</h1>
<span class="subtitle">Asiakashallinta</span>
<div class="header-brand">
<span class="brand-icon">&#9889;</span>
<div>
<h1>CuituNet Intra</h1>
<span class="subtitle">Kuituasiakkaiden hallinta</span>
</div>
</div>
</div>
<div class="header-right">
<button id="btn-add" class="btn-primary">+ Lisää asiakas</button>
@@ -33,35 +38,78 @@
</div>
</header>
<!-- Haku -->
<div class="search-bar">
<input type="text" id="search-input" placeholder="Hae yrityksen nimellä tai osoitteella...">
</div>
<div class="main-container">
<!-- Stat-kortit -->
<div class="stats-row">
<div class="stat-card">
<div class="stat-label">Asiakkaita</div>
<div class="stat-value" id="stat-count">0</div>
</div>
<div class="stat-card">
<div class="stat-label">Laskutus / kk</div>
<div class="stat-value stat-highlight" id="stat-billing">0,00 €</div>
</div>
<div class="stat-card">
<div class="stat-label">Laskutus / vuosi</div>
<div class="stat-value" id="stat-yearly">0,00 €</div>
</div>
<div class="stat-card stat-trivia">
<div class="stat-label">Suosituin postinumero</div>
<div class="stat-value" id="stat-top-zip">-</div>
<div class="stat-sub" id="stat-top-zip-detail"></div>
</div>
<div class="stat-card stat-trivia">
<div class="stat-label">Suosituin nopeus</div>
<div class="stat-value" id="stat-top-speed">-</div>
<div class="stat-sub" id="stat-top-speed-detail"></div>
</div>
<div class="stat-card stat-trivia">
<div class="stat-label">Keskihinta / kk</div>
<div class="stat-value" id="stat-avg-price">-</div>
</div>
</div>
<!-- Taulukko -->
<div class="table-container">
<table id="customer-table">
<thead>
<tr>
<th data-sort="yritys">Yritys ↕</th>
<th data-sort="asennusosoite">Asennusosoite ↕</th>
<th data-sort="liittymanopeus">Nopeus ↕</th>
<th data-sort="hinta">Hinta/kk ↕</th>
<th>Toiminnot</th>
</tr>
</thead>
<tbody id="customer-tbody"></tbody>
</table>
<div id="no-customers" class="empty-state" style="display:none">
<p>Ei asiakkaita vielä. Lisää ensimmäinen asiakas!</p>
<!-- Toolbar: haku + info -->
<div class="toolbar">
<div class="search-bar">
<span class="search-icon">&#128269;</span>
<input type="text" id="search-input" placeholder="Hae yrityksen nimellä, osoitteella tai yhteyshenkilöllä...">
</div>
</div>
<!-- Taulukko -->
<div class="table-card">
<table id="customer-table">
<thead>
<tr>
<th data-sort="yritys">Yritys ↕</th>
<th data-sort="asennusosoite">Osoite ↕</th>
<th data-sort="postinumero">Postinro ↕</th>
<th data-sort="kaupunki">Kaupunki ↕</th>
<th data-sort="liittymanopeus">Nopeus ↕</th>
<th data-sort="hinta">Hinta/kk ↕</th>
<th>Toiminnot</th>
</tr>
</thead>
<tbody id="customer-tbody"></tbody>
</table>
<div id="no-customers" class="empty-state" style="display:none">
<div class="empty-icon">&#128203;</div>
<p>Ei asiakkaita vielä.</p>
<p class="empty-hint">Klikkaa "Lisää asiakas" lisätäksesi ensimmäisen asiakkaan.</p>
</div>
</div>
<!-- Yhteenveto -->
<div class="summary-bar">
<span id="customer-count">0 asiakasta</span>
<span id="total-billing">Laskutus yhteensä: 0,00 €/kk</span>
</div>
</div>
<!-- Yhteenveto -->
<div class="summary-bar">
<span id="customer-count">0 asiakasta</span>
<span id="total-billing">Laskutus yhteensä: 0,00 €/kk</span>
</div>
<footer>
<p>CuituNet Intra &mdash; Asiakashallintajärjestelmä</p>
</footer>
</div>
<!-- Asiakas-modal -->
@@ -84,10 +132,26 @@
<label for="form-ytunnus">Y-tunnus</label>
<input type="text" id="form-ytunnus" placeholder="1234567-8">
</div>
<div class="form-group">
<label for="form-asennusosoite">Asennusosoite</label>
<input type="text" id="form-asennusosoite">
</div>
<h3>Asennusosoite</h3>
<div class="form-grid">
<div class="form-group full-width">
<label for="form-asennusosoite">Osoite</label>
<input type="text" id="form-asennusosoite" placeholder="esim. Kauppakatu 5">
</div>
<div class="form-group">
<label for="form-postinumero">Postinumero</label>
<input type="text" id="form-postinumero" placeholder="20100">
</div>
<div class="form-group">
<label for="form-kaupunki">Kaupunki</label>
<input type="text" id="form-kaupunki" placeholder="Turku">
</div>
</div>
<h3>Liittymä</h3>
<div class="form-grid">
<div class="form-group">
<label for="form-liittymanopeus">Liittymänopeus</label>
<input type="text" id="form-liittymanopeus" placeholder="esim. 100/100">
@@ -120,10 +184,26 @@
<label for="form-laskutusosoite">Laskutusosoite</label>
<input type="text" id="form-laskutusosoite">
</div>
<div class="form-group">
<label for="form-laskutuspostinumero">Postinumero</label>
<input type="text" id="form-laskutuspostinumero" placeholder="20100">
</div>
<div class="form-group">
<label for="form-laskutuskaupunki">Kaupunki</label>
<input type="text" id="form-laskutuskaupunki">
</div>
<div class="form-group">
<label for="form-laskutussahkoposti">Laskutussähköposti</label>
<input type="email" id="form-laskutussahkoposti">
</div>
<div class="form-group">
<label for="form-elaskuosoite">E-laskuosoite</label>
<input type="text" id="form-elaskuosoite" placeholder="esim. 003712345678">
</div>
<div class="form-group">
<label for="form-elaskuvalittaja">E-laskuvälittäjä</label>
<input type="text" id="form-elaskuvalittaja" placeholder="esim. DABAFIHH">
</div>
</div>
<h3>Lisätiedot</h3>