Design-System Sprint A: utilities.css + 948 Inline-Styles → Utility-Klassen, SW by-v1102
PHASE 1 — Sofort-Cleanup ohne Risiko: - Neue Datei utilities.css mit ~25 Klassen für häufige Kombinationen: * text-xs-muted, text-xs-secondary, text-sm-muted, text-sm-secondary * flex-gap-2/3, flex-col-gap-2/3/4, flex-center-gap-1/2/3 * flex-between, flex-1-min, mb-1/3, mt-1/3 * icon-xs/sm/md/lg, label-block, caption - index.html bindet utilities.css ein - mb-3/mt-3 ergänzt (waren in design-system.css unvollständig) PHASE 2 — .by-tab Modifier für Vereinheitlichung: - .by-tabs.grid (mit --tab-cols Variable für Admin/Health/etc.) - .by-tabs.sticky (Desktop vertikale Tabs für Admin) - .by-tabs.wrap (Zuchthunde, flex-wrap statt scroll) - .by-tabs.separated (Sitting, mit eigenem Hintergrund + Border) PHASE 3 — Inline-Style → Klassen-Migration (Python-Script): - 948 Inline-Styles entfernt (5101 → 4153, -18%) - 962 Migrationen über 47 Page-Dateien - Top-Treffer: admin.js (180), health.js (67), dog-profile.js (67), litters.js (62), settings.js (61), zuchthunde.js (51) - Patterns: text-muted, text-secondary, text-danger, text-xs-muted, text-sm-muted, grid-2 (Duplikat-Bug behoben!), flex-col-gap-3, p-3/4, mb-2/3/4, hidden, w-full, flex-1, ... - Bewahrt bestehende class-Attribute (mergt korrekt) Alle 19 Tests grün. Kein visueller Diff erwartet (gleiche Property-Werte).
This commit is contained in:
parent
279f76714e
commit
459cd425f2
54 changed files with 1809 additions and 956 deletions
|
|
@ -212,7 +212,7 @@ window.Page_diary = (() => {
|
|||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#download-simple"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div id="diary-stats-bar" class="diary-stats-bar" style="display:none"></div>
|
||||
<div id="diary-stats-bar" class="diary-stats-bar hidden"></div>
|
||||
<div id="diary-view-content">
|
||||
<div id="diary-list"></div>
|
||||
</div>
|
||||
|
|
@ -295,7 +295,7 @@ window.Page_diary = (() => {
|
|||
`;
|
||||
card.innerHTML = `
|
||||
<div style="font-size:1.8rem;flex-shrink:0;line-height:1">🐾</div>
|
||||
<div style="flex:1;min-width:0">
|
||||
<div class="flex-1-min">
|
||||
<div style="font-size:var(--text-xs);font-weight:var(--weight-semibold);
|
||||
color:var(--c-primary-dark);text-transform:uppercase;
|
||||
letter-spacing:.06em;margin-bottom:var(--space-1)">
|
||||
|
|
@ -963,7 +963,7 @@ window.Page_diary = (() => {
|
|||
|
||||
// Hunde-Chips (bei mehreren Hunden)
|
||||
const dogsHtml = dogIds.length > 1
|
||||
? `<div class="diary-detail-dogs" style="margin-bottom:var(--space-3)">
|
||||
? `<div class="diary-detail-dogs mb-3">
|
||||
${dogIds.map(did => {
|
||||
const dog = _appState.dogs.find(d => d.id === did);
|
||||
return dog ? `<div class="diary-dog-chip">
|
||||
|
|
@ -1279,7 +1279,7 @@ window.Page_diary = (() => {
|
|||
value="${entry?.datum || today}" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Titel <span style="color:var(--c-text-secondary)">(optional)</span></label>
|
||||
<label class="form-label">Titel <span class="text-secondary">(optional)</span></label>
|
||||
<input class="form-control" type="text" name="titel"
|
||||
value="${UI.escape(entry?.titel || '')}" placeholder="z.B. Erster Schultag">
|
||||
</div>
|
||||
|
|
@ -1293,10 +1293,10 @@ window.Page_diary = (() => {
|
|||
<div id="diary-existing-media"></div>
|
||||
|
||||
<!-- Neue Medien: Vorschau-Grid -->
|
||||
<div id="diary-new-media-grid" class="diary-media-grid" style="display:none"></div>
|
||||
<div id="diary-new-media-grid" class="diary-media-grid hidden"></div>
|
||||
|
||||
<!-- versteckter Input — multiple für Mehrfachauswahl -->
|
||||
<input type="file" id="diary-media-input" accept="image/*,video/*,application/pdf" multiple style="display:none">
|
||||
<input type="file" id="diary-media-input" accept="image/*,video/*,application/pdf" multiple class="hidden">
|
||||
|
||||
<!-- Einzelner Button — iOS zeigt nativen Picker (Mediathek / Kamera / Datei) -->
|
||||
<label for="diary-media-input" class="btn btn-secondary" style="cursor:pointer;display:flex;align-items:center;gap:var(--space-2);justify-content:center">
|
||||
|
|
@ -1305,7 +1305,7 @@ window.Page_diary = (() => {
|
|||
</label>
|
||||
</div>
|
||||
<div class="form-group" id="diary-location-group">
|
||||
<label class="form-label">Ort <span style="color:var(--c-text-secondary)">(optional)</span></label>
|
||||
<label class="form-label">Ort <span class="text-secondary">(optional)</span></label>
|
||||
|
||||
<!-- Karte (Lesemodus, Edit per Button aktivierbar) -->
|
||||
<div style="position:relative">
|
||||
|
|
@ -1318,7 +1318,7 @@ window.Page_diary = (() => {
|
|||
</div>
|
||||
|
||||
<!-- POI-Name + Aktionen -->
|
||||
<div style="margin-top:var(--space-2)">
|
||||
<div class="mt-2">
|
||||
<div id="diary-location-chip-wrap" style="${entry?.location_name ? '' : 'display:none'}">
|
||||
<div class="diary-location-chip">
|
||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#map-pin"></use></svg>
|
||||
|
|
@ -1341,7 +1341,7 @@ window.Page_diary = (() => {
|
|||
${dogPickerHtml}
|
||||
<div class="form-group" style="margin-top:var(--space-5)">
|
||||
<input type="checkbox" name="is_milestone" id="diary-milestone-cb"
|
||||
${entry?.is_milestone ? 'checked' : ''} style="display:none">
|
||||
${entry?.is_milestone ? 'checked' : ''} class="hidden">
|
||||
<button type="button" id="diary-milestone-btn"
|
||||
class="diary-milestone-toggle${entry?.is_milestone ? ' diary-milestone-toggle--active' : ''}">
|
||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#trophy"></use></svg>
|
||||
|
|
@ -1353,10 +1353,10 @@ window.Page_diary = (() => {
|
|||
|
||||
const footer = `
|
||||
<div style="display:flex;flex-direction:column;gap:var(--space-2);width:100%">
|
||||
<button type="submit" form="diary-form" class="btn btn-primary" style="width:100%">
|
||||
<button type="submit" form="diary-form" class="btn btn-primary w-full">
|
||||
${isEdit ? 'Speichern' : 'Erstellen'}
|
||||
</button>
|
||||
<div style="display:flex;gap:var(--space-2)">
|
||||
<div class="flex-gap-2">
|
||||
${isEdit ? `<button type="button" class="btn btn-danger" id="diary-form-delete">Löschen</button>` : ''}
|
||||
<button type="button" class="btn btn-secondary flex-1" id="diary-form-cancel">Abbrechen</button>
|
||||
</div>
|
||||
|
|
@ -1843,32 +1843,32 @@ window.Page_diary = (() => {
|
|||
<strong>${UI.escape(_appState.activeDog?.name || 'deinem Hund')}</strong>.
|
||||
</p>
|
||||
|
||||
<div style="display:flex;flex-direction:column;gap:var(--space-3)">
|
||||
<div class="flex-col-gap-3">
|
||||
|
||||
<label class="import-format-card" id="fmt-nsx">
|
||||
<input type="radio" name="import-fmt" value="nsx" checked style="display:none">
|
||||
<input type="radio" name="import-fmt" value="nsx" checked class="hidden">
|
||||
<div class="import-format-icon">
|
||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#note"></use></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight:var(--weight-semibold)">Synology NoteStation</div>
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-muted)">.nsx-Datei aus dem NoteStation-Export</div>
|
||||
<div class="text-xs-muted">.nsx-Datei aus dem NoteStation-Export</div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label class="import-format-card" id="fmt-csv">
|
||||
<input type="radio" name="import-fmt" value="csv" style="display:none">
|
||||
<input type="radio" name="import-fmt" value="csv" class="hidden">
|
||||
<div class="import-format-icon">
|
||||
<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#file-csv"></use></svg>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-weight:var(--weight-semibold)">CSV / Excel</div>
|
||||
<div style="font-size:var(--text-xs);color:var(--c-text-muted)">Spalten: datum, titel, text, tags, gps_lat, gps_lon, is_milestone</div>
|
||||
<div class="text-xs-muted">Spalten: datum, titel, text, tags, gps_lat, gps_lon, is_milestone</div>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:var(--space-4)">
|
||||
<div class="mt-4">
|
||||
<label class="form-label">Datei auswählen</label>
|
||||
<input type="file" class="form-control" id="import-file-input"
|
||||
accept=".nsx,.csv" style="cursor:pointer">
|
||||
|
|
@ -1917,7 +1917,7 @@ window.Page_diary = (() => {
|
|||
: await API.importData.csv(dogId, file);
|
||||
|
||||
const errHtml = res.errors?.length
|
||||
? `<details style="margin-top:var(--space-2)"><summary style="font-size:var(--text-xs);cursor:pointer">${res.errors.length} Fehler anzeigen</summary>
|
||||
? `<details class="mt-2"><summary style="font-size:var(--text-xs);cursor:pointer">${res.errors.length} Fehler anzeigen</summary>
|
||||
<pre style="font-size:var(--text-xs);white-space:pre-wrap;margin-top:var(--space-1)">${UI.escape(res.errors.join('\n'))}</pre></details>`
|
||||
: '';
|
||||
|
||||
|
|
@ -1925,7 +1925,7 @@ window.Page_diary = (() => {
|
|||
<div style="background:var(--c-success-subtle);border-radius:var(--radius-md);
|
||||
padding:var(--space-3) var(--space-4);color:var(--c-success)">
|
||||
<strong>${res.imported} Einträge importiert</strong>
|
||||
${res.skipped ? `<span style="color:var(--c-text-muted);font-size:var(--text-sm)"> · ${res.skipped} übersprungen</span>` : ''}
|
||||
${res.skipped ? `<span class="text-sm-muted"> · ${res.skipped} übersprungen</span>` : ''}
|
||||
${errHtml}
|
||||
</div>`;
|
||||
resultEl.style.display = 'block';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue