feat(prezentacja): zakladka „Skompiluj" — zbiorczy raport (PRE-23)
build / build (push) Successful in 52s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m16s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m57s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 32s
Testy / Kontrola składni wszystkich warstw (push) Failing after 8s
build / build (push) Successful in 52s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 11m16s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m57s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 32s
Testy / Kontrola składni wszystkich warstw (push) Failing after 8s
Czwarta wskazowka partnerow. Nowa zakladka sklada w jedno trzy kawalki liczone w roznych miejscach: policzony horoskop, interpretacje natalna z AI i wszystkie zapamietane predykcje okresowe. Uklad sekcji dokladnie wg prosby: imie i nazwisko -> wprowadzone dane -> RYSUNEK kosmogramu -> interpretacja natalna -> predykcje okresowe. Test pilnuje tej kolejnosci, bo to jedyna rzecz, ktora latwo przestawic przy refaktorze, a partnerzy podali ja wprost. Skad material: - HOROSKOP liczymy TU NA NOWO z danych formularza, zamiast go zapamietywac. To czysta funkcja wejscia — tanio powtorzyc, a odpada trzymanie w przegladarce duzego wyniku, ktory moglby sie rozjechac z aktualnym formularzem. - INTERPRETACJA NATALNA — nowy natal.js, odpowiednik predictions.js. Natalna jest JEDNA (dotyczy momentu urodzenia, nie okresu), wiec ponowne wygenerowanie podmienia slot zamiast dokladac wpis. - PREDYKCJE — z magazynu z PRE-22. compile.js czyta magazyny przez ICH API (window.astrololoNatal / astrololoPredictions), a nie siegajac wprost do localStorage — format danych ma jednego wlasciciela: modul, ktory je zapisuje. Test tego pilnuje. Zakladka MOWI, CZEGO BRAKUJE: panel gotowosci z trzema pozycjami i podpowiedzia, na ktorej zakladce uzupelnic. Bez tego uzytkownik zlozylby niekompletny raport i dowiedzialby sie o tym dopiero po otwarciu PDF-a. Tresc od modelu jest ESKEJPOWANA przed wstawieniem do DOM — to tekst z zewnatrz, wiec bez tego mielibysmy wektor wstrzykniecia. Weryfikacja na zywej aplikacji: dwie predykcje zapisane w Kalendarzu, natalna w Interpretacjach, obie odczytane na Skompiluj (panel: brak horoskopu na zolto, dwa pozostale na zielono). Po zlozeniu wszystkie trzy zielone, a raport zaczyna sie od „Jan Kowalski" i danych wejsciowych. Kolejnosc sekcji sprawdzona na wyrenderowanym HTML: naglowek 2931 < dane 3033 < kosmogram 3158 < natalna 26544 < predykcje 26575. Testy: 16 nowych. Poprawione tez trzy wlasne testy, ktore lapaly nazwy plikow w KOMENTARZACH zamiast w tagach skryptow. Calosc: prezentacja 117 passed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit was merged in pull request #31.
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
// Zakładka „Skompiluj" — składanie raportu (PRE-23).
|
||||
//
|
||||
// Raport ma trzy kawałki liczone w różnych miejscach:
|
||||
// 1. horoskop — liczy serwer przy wysłaniu tego formularza,
|
||||
// 2. interpretacja natalna — z zakładki Interpretacje (natal.js),
|
||||
// 3. predykcje okresowe — z zakładki Kalendarz (predictions.js).
|
||||
//
|
||||
// Punkty 2 i 3 mieszkają w magazynie przeglądarki, więc to tutaj je dokładamy.
|
||||
// Odczytujemy je przez API tamtych modułów, a nie sięgając wprost do
|
||||
// localStorage — dzięki temu format danych ma JEDNEGO właściciela.
|
||||
//
|
||||
// Pokazujemy też, CZEGO BRAKUJE. Bez tego użytkownik złożyłby niekompletny raport
|
||||
// i dowiedział się o tym dopiero po otwarciu PDF-a.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function esc(s) {
|
||||
return String(s == null ? '' : s)
|
||||
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
}
|
||||
|
||||
function readNatal() {
|
||||
return (window.astrololoNatal && window.astrololoNatal.read()) || null;
|
||||
}
|
||||
|
||||
function readPredictions() {
|
||||
return (window.astrololoPredictions && window.astrololoPredictions.read()) || [];
|
||||
}
|
||||
|
||||
function item(ok, label, hint) {
|
||||
return '<li class="' + (ok ? 'rdy-ok' : 'rdy-missing') + '">' +
|
||||
(ok ? '✓ ' : '✗ ') + esc(label) +
|
||||
(ok ? '' : ' <span class="muted small">— ' + esc(hint) + '</span>') + '</li>';
|
||||
}
|
||||
|
||||
function renderReadiness(hasChart) {
|
||||
var host = document.getElementById('readiness');
|
||||
if (!host) return;
|
||||
var natal = readNatal();
|
||||
var preds = readPredictions();
|
||||
var parts = [
|
||||
item(hasChart, 'Policzony horoskop', 'wypełnij dane i kliknij „Złóż podsumowanie"'),
|
||||
item(!!natal, 'Interpretacja natalna',
|
||||
'wygeneruj ją na zakładce Interpretacje — zapamięta się sama'),
|
||||
item(preds.length > 0,
|
||||
'Predykcje okresowe' + (preds.length ? ' (' + preds.length + ')' : ''),
|
||||
'policz horoskop na wybrany okres w Kalendarzu')
|
||||
];
|
||||
host.innerHTML = '<div class="meta">Materiał do raportu</div><ul class="readiness">' +
|
||||
parts.join('') + '</ul>';
|
||||
}
|
||||
|
||||
function renderNatal() {
|
||||
var host = document.getElementById('reportNatal');
|
||||
if (!host) return;
|
||||
var natal = readNatal();
|
||||
if (!natal) {
|
||||
host.innerHTML = '<div class="meta">Interpretacja natalna</div>' +
|
||||
'<p class="muted small">Brak — wygeneruj ją na zakładce Interpretacje.</p>';
|
||||
return;
|
||||
}
|
||||
host.innerHTML = '<div class="meta">Interpretacja natalna ' +
|
||||
'<span class="muted small">· zapamiętana ' + esc(String(natal.saved_at).slice(0, 10)) +
|
||||
'</span></div><div class="report-text">' + esc(natal.text) + '</div>';
|
||||
}
|
||||
|
||||
function renderPredictions() {
|
||||
var host = document.getElementById('reportPredictions');
|
||||
if (!host) return;
|
||||
var preds = readPredictions();
|
||||
if (!preds.length) {
|
||||
host.innerHTML = '<div class="meta">Predykcje okresowe</div>' +
|
||||
'<p class="muted small">Brak — policz horoskop na wybrany okres w Kalendarzu.</p>';
|
||||
return;
|
||||
}
|
||||
var blocks = preds.map(function (p) {
|
||||
return '<div class="meta">' + esc(p.from_date) + ' – ' + esc(p.to_date) + '</div>' +
|
||||
'<div class="report-text">' + esc(p.text) + '</div>';
|
||||
}).join('');
|
||||
host.innerHTML = '<div class="meta">Predykcje okresowe (' + preds.length + ')</div>' + blocks;
|
||||
}
|
||||
|
||||
function ready(fn) {
|
||||
if (document.readyState !== 'loading') fn();
|
||||
else document.addEventListener('DOMContentLoaded', fn);
|
||||
}
|
||||
|
||||
ready(function () {
|
||||
if (!document.getElementById('readiness')) return; // nie ta zakładka
|
||||
// Horoskop jest w dokumencie tylko po wysłaniu formularza.
|
||||
renderReadiness(!!document.getElementById('reportPerson'));
|
||||
renderNatal();
|
||||
renderPredictions();
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,97 @@
|
||||
// Zapamiętana interpretacja natalna (PRE-23).
|
||||
//
|
||||
// Odpowiednik predictions.js, tylko że natalna jest JEDNA — dotyczy momentu
|
||||
// urodzenia, nie wybranego okresu. Ponowne wygenerowanie podmienia poprzednią.
|
||||
//
|
||||
// Po co magazyn: zakładka „Skompiluj" składa raport z trzech kawałków liczonych
|
||||
// w różnych miejscach (horoskop, interpretacja natalna, predykcje okresowe).
|
||||
// Bez zapamiętania trzeba by je generować od nowa na jednej stronie.
|
||||
//
|
||||
// localStorage, tak jak reszta stanu (PRE-21/22) — serwer zostaje bezstanowy.
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var KEY = 'astrololo.natal.v1';
|
||||
|
||||
function read() {
|
||||
try {
|
||||
var v = JSON.parse(localStorage.getItem(KEY) || 'null');
|
||||
return (v && typeof v === 'object' && v.text) ? v : null;
|
||||
} catch (e) {
|
||||
return null; // uszkodzony wpis nie może zablokować strony
|
||||
}
|
||||
}
|
||||
|
||||
function clear() {
|
||||
try { localStorage.removeItem(KEY); } catch (e) { /* trudno */ }
|
||||
}
|
||||
|
||||
function val(sel) {
|
||||
var el = document.querySelector(sel);
|
||||
return el ? el.value.trim() : '';
|
||||
}
|
||||
|
||||
function save() {
|
||||
var text = val('#horoscopeText');
|
||||
if (!text) return false; // nie ma czego zapamiętać
|
||||
var entry = {
|
||||
text: text,
|
||||
person: val('input[name=person]'),
|
||||
date: val('input[name=date]'),
|
||||
time: val('input[name=time]'),
|
||||
tz_offset: val('input[name=tz_offset]'),
|
||||
lat: val('input[name=lat]'),
|
||||
lon: val('input[name=lon]'),
|
||||
saved_at: new Date().toISOString()
|
||||
};
|
||||
try {
|
||||
localStorage.setItem(KEY, JSON.stringify(entry));
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false; // przepełniony magazyn — zgłaszamy wyżej
|
||||
}
|
||||
}
|
||||
|
||||
function note(msg) {
|
||||
var el = document.getElementById('natalNote');
|
||||
if (el) el.textContent = msg;
|
||||
}
|
||||
|
||||
function saveCurrent() {
|
||||
var text = val('#horoscopeText');
|
||||
if (!text) return;
|
||||
if (save()) {
|
||||
note('Interpretacja natalna zapamiętana — trafi do raportu (zakładka Skompiluj).');
|
||||
} else {
|
||||
// Interpretacje bywają długie; cicha strata byłaby najgorsza.
|
||||
note('Nie udało się zapamiętać — magazyn przeglądarki pełny. '
|
||||
+ 'Usuń starsze predykcje i spróbuj ponownie.');
|
||||
}
|
||||
}
|
||||
|
||||
function ready(fn) {
|
||||
if (document.readyState !== 'loading') fn();
|
||||
else document.addEventListener('DOMContentLoaded', fn);
|
||||
}
|
||||
|
||||
ready(function () {
|
||||
if (!document.getElementById('natalNote')) return; // nie ta zakładka
|
||||
|
||||
// 1) interpretacja policzona przez okno postępu (strumień)
|
||||
document.addEventListener('astrololo:horoscope', function (e) {
|
||||
if (!e.detail || e.detail.profile === 'natal') saveCurrent();
|
||||
});
|
||||
|
||||
// 2) wariant bez strumienia: strona wróciła z gotowym wynikiem po zwykłym
|
||||
// POST. Zapis nadpisuje jeden slot, więc odświeżenie niczego nie mnoży.
|
||||
if (document.querySelector('#horoscopeText')) saveCurrent();
|
||||
|
||||
var status = read();
|
||||
if (status) {
|
||||
note('W raporcie jest zapamiętana interpretacja natalna z '
|
||||
+ String(status.saved_at).slice(0, 10) + '.');
|
||||
}
|
||||
});
|
||||
|
||||
window.astrololoNatal = { read: read, clear: clear, key: KEY };
|
||||
})();
|
||||
@@ -152,3 +152,15 @@ textarea.prompt:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
|
||||
.progress-log li.log-ok { color: #7fd18b; }
|
||||
.progress-log li.log-warn { color: #e0c060; }
|
||||
.progress-log li.log-err { color: #ef6b6b; }
|
||||
|
||||
/* Zakładka „Skompiluj" (PRE-23) — składanie raportu z trzech źródeł. */
|
||||
.readiness { list-style: none; margin: .3rem 0 1rem; padding: 0; }
|
||||
.readiness li { padding: .2rem 0; }
|
||||
.readiness .rdy-ok { color: #7fd18b; }
|
||||
.readiness .rdy-missing { color: #e0c060; }
|
||||
.report-head { margin: 1.5rem 0 .5rem; }
|
||||
.report-head h2 { margin: 0; font-size: 1.4rem; }
|
||||
/* Treść od AI bywa długa — white-space:pre-wrap zachowuje akapity modelu,
|
||||
bez przepisywania ich na HTML. */
|
||||
.report-text { white-space: pre-wrap; background: var(--panel); border: 1px solid var(--line);
|
||||
border-radius: 10px; padding: .8rem 1rem; margin-top: .4rem; line-height: 1.6; }
|
||||
|
||||
Reference in New Issue
Block a user