---
phase: 01-historia-cen
plan: 02
type: execute
wave: 1
depends_on: ["01-01"]
files_modified:
  - wp-content/plugins/elementor-addon/widgets/apartaments.php
  - wp-content/plugins/elementor-addon/assets/css/main.scss
  - wp-content/plugins/elementor-addon/assets/css/main.css
  - wp-content/plugins/elementor-addon/assets/js/main.js
autonomous: false
---

<objective>
## Goal
Zbudować popup „Historia cen" — klikalny przycisk na karcie apartamentu otwiera modal
z aktualną ceną i tabelą historii zmian, zasilany przez AJAX endpoint z planu 01-01.

## Purpose
Użytkownik może zobaczyć historię zmian cen apartamentu bez opuszczania strony.
Popup pokazuje nazwę apartamentu, aktualną cenę brutto i za m², oraz tabelę dat ze zmianami.

## Output
- Przycisk „HISTORIA CEN" z `data-post-id` w widgecie
- Globalny popup HTML (overlay + modal) w widgecie
- CSS modal pasujący do projektu (font Barlow, kolor #192c44, border 4px solid)
- JS: fetch AJAX → wypełnienie popupa → pokaż/ukryj
</objective>

<context>
## Project Context
@.paul/PROJECT.md
@.paul/STATE.md

## Prior Work
@.paul/phases/01-historia-cen/01-01-SUMMARY.md

## Source Files
@wp-content/plugins/elementor-addon/widgets/apartaments.php
@wp-content/plugins/elementor-addon/assets/css/main.scss
@wp-content/plugins/elementor-addon/assets/js/main.js

## API Contract (z planu 01-01)
POST admin-ajax.php
body: action=apartamenty_get_price_history&post_id=ID&nonce=NONCE
response: {
  success: true,
  data: {
    title: "Apartament X",
    price: "677 920",       // cena brutto
    price_m2: "19 000",     // cena za m²
    floor_space: "35,68",   // metraż
    history: [
      { recorded_at: "2026-01-16", price: "677 920", price_m2: "19 000" }
    ]
  }
}

## JS globals dostępne na stronie
window.apartamentsData.ajaxUrl  — URL do admin-ajax.php
window.apartamentsData.nonce    — nonce 'apartamenty_price_history_nonce'

## Design (z mockupu Group 68.png)
- Białe tło, border matching kart (#192c44)
- Tytuł (bold, duży) + X w prawym górnym rogu
- "Cena brutto:" (bold) → wartość bold po prawej z " zł"
- "Cena m²:" (normal) → wartość normal po prawej z " zł"
- Separator
- Tabela: data | cena_m2 (format "X zł/m²") | cena brutto (format "X,00 zł")
- Overlay ciemne tło półprzezroczyste

## Istniejące style CSS
- Font: 'Barlow', sans-serif
- Kolor główny: #192c44
- Border kart: 4px solid #192c44
- Wiersz .apartament-card__price-history już ma cursor: pointer
</context>

<acceptance_criteria>

## AC-1: Przycisk "Historia cen" jest klikalny
```gherkin
Given apartament ma dane cen w ACF
When użytkownik widzi kartę apartamentu
Then wiersz "HISTORIA CEN" jest klikalny i posiada atrybut data-post-id z ID apartamentu
```

## AC-2: Popup otwiera się z danymi
```gherkin
Given użytkownik klika "HISTORIA CEN" przy apartamencie
When request AJAX zakończy się sukcesem
Then pojawia się modal z:
  - tytułem apartamentu
  - aktualną ceną brutto (bold)
  - aktualną ceną m² (normal)
  - tabelą historii (data | cena m² | cena brutto)
```

## AC-3: Popup zamyka się
```gherkin
Given popup jest otwarty
When użytkownik klika przycisk X lub klika poza modalem (na overlay)
Then popup znika
```

## AC-4: Stan ładowania i błędu
```gherkin
Given użytkownik kliknął "Historia cen"
When AJAX jest w trakcie
Then popup pokazuje "Ładowanie..."
And jeśli AJAX zwróci błąd, popup pokazuje "Brak danych"
```

## AC-5: Historia jest pusta
```gherkin
Given apartament nie ma jeszcze rekordów w tabeli historii
When użytkownik otworzy popup
Then widoczna jest sekcja z aktualną ceną, a tabela historii jest pusta lub pokazuje komunikat "Brak historii cen"
```

</acceptance_criteria>

<tasks>

<task type="auto">
  <name>Task 1: Dodaj data-post-id do przycisku i popup HTML do widgetu</name>
  <files>wp-content/plugins/elementor-addon/widgets/apartaments.php</files>
  <action>
    **Zmiana 1: Wiersz "HISTORIA CEN"**

    Znajdź wiersz z klasą `apartament-card__price-history` (linia ~157).
    Zmień `<td class="apartament-card__info_table-value">` na:
    ```php
    <td class="apartament-card__info_table-value btn-historia-cen"
        data-post-id="<?php echo esc_attr( get_the_ID() ); ?>">
    ```
    Reszta wiersza (tekst "HISTORIA CEN" + SVG) pozostaje bez zmian.

    **Zmiana 2: Globalny popup HTML**

    Dodaj PRZED `<?php wp_reset_postdata(); ?>` (czyli po zamknięciu pętli while)
    następujący HTML popupa (jeden egzemplarz dla całej strony):

    ```php
    <?php // Popup historia cen — jeden globalny, wypełniany przez JS ?>
    <div class="price-history-overlay" id="price-history-overlay" aria-hidden="true">
        <div class="price-history-modal" role="dialog" aria-modal="true">
            <button class="price-history-modal__close" id="price-history-close" aria-label="Zamknij">
                <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
                    <path d="M13 1L1 13M1 1L13 13" stroke="#192C44" stroke-width="2" stroke-linecap="round"/>
                </svg>
            </button>
            <h3 class="price-history-modal__title" id="price-history-title"></h3>
            <div class="price-history-modal__current">
                <div class="price-history-modal__row price-history-modal__row--bold">
                    <span>Cena brutto:</span>
                    <span class="price-history-modal__val" id="price-history-price"></span>
                </div>
                <div class="price-history-modal__row">
                    <span>Cena m<sup>2</sup>:</span>
                    <span class="price-history-modal__val" id="price-history-price-m2"></span>
                </div>
            </div>
            <div class="price-history-modal__table-wrap">
                <table class="price-history-modal__table">
                    <tbody id="price-history-tbody"></tbody>
                </table>
            </div>
        </div>
    </div>
    ```

    Unikaj: dodawania popup wewnątrz pętli while — tylko jeden egzemplarz na stronę.
  </action>
  <verify>
    Sprawdź PHP syntax: `php -l wp-content/plugins/elementor-addon/widgets/apartaments.php`
    Sprawdź czy data-post-id jest w HTML widgetu przez DevTools lub view-source.
  </verify>
  <done>AC-1 spełnione: przycisk ma data-post-id; popup HTML istnieje w DOM</done>
</task>

<task type="auto">
  <name>Task 2: CSS popup — main.scss i main.css</name>
  <files>
    wp-content/plugins/elementor-addon/assets/css/main.scss,
    wp-content/plugins/elementor-addon/assets/css/main.css
  </files>
  <action>
    Dodaj na końcu pliku `main.scss` (po zamknięciu `.apartaments { }`) poniższe style.
    Następnie dodaj **te same skompilowane style** (bez SCSS zagnieżdżeń, rozwinięte)
    na końcu pliku `main.css`.

    **Style do dodania w main.scss:**
    ```scss
    // Historia cen — popup overlay
    .price-history-overlay {
        display: none;
        position: fixed;
        inset: 0;
        z-index: 99999;
        background: rgba(25, 44, 68, 0.55);
        align-items: center;
        justify-content: center;
        padding: 20px;

        &.is-open {
            display: flex;
        }
    }

    .price-history-modal {
        position: relative;
        background: #fff;
        border: 4px solid #192c44;
        padding: 32px 36px 28px;
        max-width: 560px;
        width: 100%;
        max-height: 80vh;
        overflow-y: auto;
        font-family: 'Barlow', sans-serif;
        color: #192c44;

        @media (max-width: 600px) {
            padding: 24px 20px 20px;
        }

        &__close {
            position: absolute;
            top: 14px;
            right: 14px;
            background: none;
            border: 2px solid #192c44;
            width: 30px;
            height: 30px;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            padding: 0;
            line-height: 1;
        }

        &__title {
            font-size: 22px;
            font-weight: 700;
            margin: 0 0 18px;
            padding-right: 40px;
            color: #192c44;
        }

        &__current {
            margin-bottom: 16px;
        }

        &__row {
            display: flex;
            justify-content: space-between;
            font-size: 18px;
            line-height: 1.5;
            color: #192c44;

            &--bold {
                font-weight: 700;
            }
        }

        &__val {
            text-align: right;
        }

        &__table-wrap {
            border-top: 1px solid #192c44;
            padding-top: 12px;
            margin-top: 4px;
        }

        &__table {
            width: 100%;
            border-collapse: collapse;

            tr {
                border: none;
                background: transparent;

                td {
                    padding: 4px 0;
                    font-size: 15px;
                    color: #192c44;
                    font-family: 'Barlow', sans-serif;
                    font-weight: 400;
                    border: none;
                    background: transparent;

                    &:last-child {
                        text-align: right;
                    }

                    &:nth-child(2) {
                        text-align: center;
                    }
                }
            }
        }
    }
    ```

    **Skompilowana wersja CSS do dodania na końcu main.css** (rozwinięte selektory, bez &):

    ```css
    /* Historia cen — popup */
    .price-history-overlay {
        display: none;
        position: fixed;
        inset: 0;
        z-index: 99999;
        background: rgba(25, 44, 68, 0.55);
        align-items: center;
        justify-content: center;
        padding: 20px;
    }
    .price-history-overlay.is-open {
        display: flex;
    }
    .price-history-modal {
        position: relative;
        background: #fff;
        border: 4px solid #192c44;
        padding: 32px 36px 28px;
        max-width: 560px;
        width: 100%;
        max-height: 80vh;
        overflow-y: auto;
        font-family: 'Barlow', sans-serif;
        color: #192c44;
    }
    @media (max-width: 600px) {
        .price-history-modal {
            padding: 24px 20px 20px;
        }
    }
    .price-history-modal__close {
        position: absolute;
        top: 14px;
        right: 14px;
        background: none;
        border: 2px solid #192c44;
        width: 30px;
        height: 30px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        padding: 0;
        line-height: 1;
    }
    .price-history-modal__title {
        font-size: 22px;
        font-weight: 700;
        margin: 0 0 18px;
        padding-right: 40px;
        color: #192c44;
    }
    .price-history-modal__current {
        margin-bottom: 16px;
    }
    .price-history-modal__row {
        display: flex;
        justify-content: space-between;
        font-size: 18px;
        line-height: 1.5;
        color: #192c44;
    }
    .price-history-modal__row--bold {
        font-weight: 700;
    }
    .price-history-modal__val {
        text-align: right;
    }
    .price-history-modal__table-wrap {
        border-top: 1px solid #192c44;
        padding-top: 12px;
        margin-top: 4px;
    }
    .price-history-modal__table {
        width: 100%;
        border-collapse: collapse;
    }
    .price-history-modal__table tr {
        border: none;
        background: transparent;
    }
    .price-history-modal__table td {
        padding: 4px 0;
        font-size: 15px;
        color: #192c44;
        font-family: 'Barlow', sans-serif;
        font-weight: 400;
        border: none;
        background: transparent;
    }
    .price-history-modal__table td:last-child {
        text-align: right;
    }
    .price-history-modal__table td:nth-child(2) {
        text-align: center;
    }
    ```

    Unikaj: modyfikowania istniejących reguł CSS — tylko append na końcu.
    Unikaj: zmian w mapie .css.map — pozostaw jak jest.
  </action>
  <verify>
    Sprawdź że klasy `.price-history-overlay` i `.price-history-modal` są obecne w main.css.
    Sprawdź że nie ma błędów składni SCSS (ręczna inspekcja nawiasów).
  </verify>
  <done>AC-2, AC-3 (style): modal wygląda zgodnie z projektem</done>
</task>

<task type="auto">
  <name>Task 3: JS — obsługa kliknięcia, AJAX, render popupa</name>
  <files>wp-content/plugins/elementor-addon/assets/js/main.js</files>
  <action>
    Dodaj na końcu pliku `main.js` (po zamknięciu istniejącego DOMContentLoaded)
    nowy blok obsługi historii cen.

    **Kod do dodania:**
    ```javascript
    // Historia cen
    document.addEventListener('DOMContentLoaded', function () {
        var overlay  = document.getElementById('price-history-overlay');
        var closeBtn = document.getElementById('price-history-close');

        if (!overlay) return; // popup nie istnieje na tej stronie

        function openPopup() {
            overlay.setAttribute('aria-hidden', 'false');
            overlay.classList.add('is-open');
            document.body.style.overflow = 'hidden';
        }

        function closePopup() {
            overlay.setAttribute('aria-hidden', 'true');
            overlay.classList.remove('is-open');
            document.body.style.overflow = '';
        }

        // Zamknij przyciskiem X
        closeBtn.addEventListener('click', closePopup);

        // Zamknij klikając na overlay (poza modalem)
        overlay.addEventListener('click', function (e) {
            if (e.target === overlay) closePopup();
        });

        // Zamknij klawiszem Escape
        document.addEventListener('keydown', function (e) {
            if (e.key === 'Escape' && overlay.classList.contains('is-open')) closePopup();
        });

        // Kliknięcie w przycisk Historia cen
        document.querySelectorAll('.btn-historia-cen').forEach(function (btn) {
            btn.addEventListener('click', function () {
                var postId = this.dataset.postId;
                if (!postId) return;

                // Reset i pokaż "Ładowanie..."
                document.getElementById('price-history-title').textContent   = 'Ładowanie...';
                document.getElementById('price-history-price').textContent   = '';
                document.getElementById('price-history-price-m2').textContent = '';
                document.getElementById('price-history-tbody').innerHTML     = '';
                openPopup();

                // Sprawdź dostępność danych globalnych (wp_localize_script)
                if (typeof apartamentsData === 'undefined') {
                    document.getElementById('price-history-title').textContent = 'Błąd konfiguracji';
                    return;
                }

                // Buduj FormData
                var formData = new FormData();
                formData.append('action',  'apartamenty_get_price_history');
                formData.append('post_id', postId);
                formData.append('nonce',   apartamentsData.nonce);

                fetch(apartamentsData.ajaxUrl, {
                    method: 'POST',
                    body: formData,
                    credentials: 'same-origin',
                })
                .then(function (res) { return res.json(); })
                .then(function (json) {
                    if (!json.success) {
                        document.getElementById('price-history-title').textContent = 'Brak danych';
                        return;
                    }

                    var d = json.data;

                    document.getElementById('price-history-title').textContent =
                        d.title || '';
                    document.getElementById('price-history-price').textContent =
                        d.price ? d.price + ' zł' : '—';
                    document.getElementById('price-history-price-m2').textContent =
                        d.price_m2 ? d.price_m2 + ' zł' : '—';

                    var tbody = document.getElementById('price-history-tbody');
                    if (!d.history || d.history.length === 0) {
                        tbody.innerHTML = '<tr><td colspan="3">Brak historii cen</td></tr>';
                        return;
                    }

                    tbody.innerHTML = d.history.map(function (row) {
                        return '<tr>' +
                            '<td>' + (row.recorded_at || '') + '</td>' +
                            '<td>' + (row.price_m2 ? row.price_m2 + ' zł/m²' : '—') + '</td>' +
                            '<td>' + (row.price ? row.price + ' zł' : '—') + '</td>' +
                        '</tr>';
                    }).join('');
                })
                .catch(function () {
                    document.getElementById('price-history-title').textContent = 'Błąd ładowania';
                });
            });
        });
    });
    ```

    Unikaj: modyfikowania istniejącego bloku DOMContentLoaded (Swiper/Fancybox) — tylko append.
    Unikaj: jQuery — używaj vanilla JS zgodnie z istniejącym stylem kodu.
  </action>
  <verify>
    `php -l` nie jest tu potrzebny — sprawdź składnię JS ręcznie (nawiasy, cudzysłowy).
    Po wgraniu: otwórz stronę /apartamenty/, otwórz DevTools Console,
    kliknij "HISTORIA CEN" → popup powinien się pojawić z danymi lub "Ładowanie...".
  </verify>
  <done>AC-2, AC-3, AC-4, AC-5 spełnione: popup otwiera się z danymi AJAX, zamyka się poprawnie</done>
</task>

<task type="checkpoint:human-verify" gate="blocking">
  <what-built>
    Popup „Historia cen" — kliknięcie przycisku otwiera modal z danymi z AJAX.
    Przycisk ma data-post-id, popup zamyka się przez X / klik overlay / Escape.
  </what-built>
  <how-to-verify>
    1. Odwiedź: https://wyszynskiego12.pagedev.pl/apartamenty/
    2. Odszukaj wiersz „HISTORIA CEN" przy dowolnym apartamencie i kliknij go
    3. Sprawdź czy pojawia się modal z:
       - Tytułem apartamentu (np. „Apartament 15")
       - Ceną brutto (bold)
       - Ceną m² (normal)
       - Tabelą historii (lub „Brak historii cen" jeśli tabela pusta)
    4. Kliknij X → popup zamknięty
    5. Kliknij poza modalem → popup zamknięty
    6. Naciśnij Escape → popup zamknięty
    7. Otwórz DevTools → Console → brak błędów JavaScript
  </how-to-verify>
  <resume-signal>Wpisz "zatwierdzone" lub opisz problemy do poprawienia</resume-signal>
</task>

</tasks>

<boundaries>

## DO NOT CHANGE
- wp-content/plugins/elementor-addon/elementor-addon.php (ukończony w planie 01-01)
- wp-content/plugins/elementor-addon/plugins/ (biblioteki zewnętrzne)
- wp-config.php

## SCOPE LIMITS
- Nie dodawaj animacji CSS poza prostym display:flex/none
- Nie dodawaj nowych zależności JS (bez jQuery, bez bibliotek)
- Popup ma jeden egzemplarz na stronę — nie w pętli
- Nie modyfikuj istniejących reguł CSS — tylko append

</boundaries>

<verification>
Before declaring plan complete:
- [ ] PHP syntax OK: `php -l widgets/apartaments.php`
- [ ] Klasa `.price-history-overlay` istnieje w main.css
- [ ] Klasa `.btn-historia-cen` jest na wierszu HISTORIA CEN w HTML
- [ ] `data-post-id` jest ustawiony poprawnie dla każdego apartamentu
- [ ] JS nie wyrzuca błędów w konsoli
- [ ] Checkpoint human-verify zatwierdzony
</verification>

<success_criteria>
- Kliknięcie "HISTORIA CEN" otwiera popup z danymi apartamentu
- Popup zamyka się przez X, klik overlay i Escape
- Stan ładowania i błędu jest obsługiwany
- Brak błędów JS w konsoli
- Wygląd zgodny z projektem (font Barlow, kolor #192c44, border 4px)
</success_criteria>

<output>
Po ukończeniu utwórz `.paul/phases/01-historia-cen/01-02-SUMMARY.md`
</output>
