---
phase: 85-status-group-filter
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - resources/views/components/order-status-panel.php
  - resources/scss/app.scss
  - src/Modules/Orders/OrdersController.php
  - src/Modules/Orders/OrdersRepository.php
autonomous: true
delegation: off
---

<objective>
## Goal
Umozliwic filtrowanie zamowien po calej grupie statusow — klikniecie w nazwe grupy na panelu statusow filtruje liste zamowien do wszystkich statusow nalezacych do tej grupy.

## Purpose
Uzytkownik moze szybko zobaczyc np. wszystkie zamowienia "w realizacji" (processing + packed + shipped) jednym kliknieciem zamiast sprawdzac kazdy status osobno.

## Output
- Nazwa grupy statusow na panelu bocznym jest klikalna i filtruje zamowienia po wszystkich statusach z grupy
- URL parametr `status_group` obslugiwany przez kontroler i repozytorium
- Suma zamowien wyswietlana obok nazwy grupy
</objective>

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

## Source Files
@resources/views/components/order-status-panel.php
@src/Modules/Orders/OrdersController.php (buildStatusPanel, statusFilterUrl)
@src/Modules/Orders/OrdersRepository.php (buildPaginateFilters, statusPanelConfig)
@resources/scss/app.scss (order-status-group styles)
</context>

<skills>
No specialized flows required.
</skills>

<acceptance_criteria>

## AC-1: Klikniecie nazwy grupy filtruje zamowienia
```gherkin
Given panel statusow na /orders/list z grupami (np. "Realizacja" zawierajaca "processing", "packed")
When uzytkownik kliknie nazwe grupy "Realizacja"
Then lista zamowien pokazuje tylko zamowienia o statusach "processing" LUB "packed"
And URL zawiera parametr status_group z identyfikatorem grupy
```

## AC-2: Grupa pokazuje sume zamowien
```gherkin
Given grupa "Realizacja" zawiera statusy "processing" (5 zamowien) i "packed" (3 zamowienia)
When panel statusow jest renderowany
Then obok nazwy grupy wyswietla sie suma "8"
```

## AC-3: Aktywna grupa jest wizualnie wyrozniiona
```gherkin
Given uzytkownik filtruje po grupie "Realizacja"
When panel statusow jest renderowany
Then nazwa grupy "Realizacja" ma klase is-active
And poszczegolne statusy w grupie NIE sa oznaczone jako is_active (aktywna jest grupa)
```

## AC-4: Filtr grupy i filtr statusu sa wzajemnie wylaczne
```gherkin
Given uzytkownik filtruje po grupie "Realizacja" (status_group=X)
When uzytkownik kliknie konkretny status "packed"
Then filtr zmienia sie na pojedynczy status (status=packed, bez status_group)
And odwrotnie: klikniecie grupy usuwa parametr status
```

</acceptance_criteria>

<tasks>

<task type="auto">
  <name>Task 1: Backend — obsluga filtra status_group w repozytorium i kontrolerze</name>
  <files>src/Modules/Orders/OrdersRepository.php, src/Modules/Orders/OrdersController.php</files>
  <action>
    1. **OrdersRepository::buildPaginateFilters()** — dodac obsluge filtra `status_group`:
       - Nowy parametr `status_group` (string, ID grupy)
       - Jezeli `status_group` nie jest pusty: pobrac kody statusow nalezacych do tej grupy z `statusPanelConfig()` lub osobnym query do `order_statuses WHERE group_id = :gid`
       - Zbudowac warunek `effectiveStatusSql IN (:sg0, :sg1, ...)` z dynamicznymi parametrami
       - Filtr `status_group` ma priorytet nad `status` — jezeli oba sa podane, uzyj `status_group`

    2. **OrdersController::index()** — dodac odczyt `status_group` z requestu:
       - `'status_group' => trim((string) $request->input('status_group', ''))`
       - Przekazac do `$filters` i dalej do `paginate()`

    3. **OrdersController::buildStatusPanel()** — rozszerzyc:
       - Dodac do kazdej grupy (ktora ma `name`) element klikalny z URL zawierajacym `status_group=ID`
       - Obliczyc `group_count` jako sume countow statusow w grupie
       - Ustawic `is_active_group` jezeli `currentStatusGroup` odpowiada tej grupie
       - Gdy grupa jest aktywna, poszczegolne statusy w niej NIE maja `is_active`

    4. **OrdersController::statusFilterUrl()** — rozszerzyc o wariant grupowy:
       - Nowa metoda `groupFilterUrl(array $query, string $groupId): string`
       - Ustawia `status_group=ID`, usuwa `status`, resetuje `page=1`
       - Klikniecie statusu (istniejace `statusFilterUrl`) musi usuwac `status_group`
  </action>
  <verify>
    - GET /orders/list?status_group=1 zwraca zamowienia z wszystkimi statusami z grupy 1
    - GET /orders/list?status=packed nie zawiera parametru status_group
    - Filtr status_group ma priorytet nad status gdy oba podane
  </verify>
  <done>AC-1 i AC-4 satisfied: filtr grupowy dziala, jest wzajemnie wylaczny z filtrem statusu</done>
</task>

<task type="auto">
  <name>Task 2: Frontend — klikalna nazwa grupy z licznikiem i stanem aktywnym</name>
  <files>resources/views/components/order-status-panel.php, resources/scss/app.scss</files>
  <action>
    1. **order-status-panel.php** — zmodyfikowac rendering nazwy grupy:
       - Jezeli grupa ma `url` (nowy klucz z buildStatusPanel), renderowac nazwe jako `<a>` zamiast `<div>`
       - Dodac `group_count` obok nazwy grupy (jak count przy statusach)
       - Dodac klase `is-active` do `order-status-group__name` gdy `is_active_group` jest true
       - Struktura: `<a href="..." class="order-status-group__name [is-active]">Nazwa <span class="order-status-group__count">8</span></a>`

    2. **app.scss** — dodac style:
       - `.order-status-group__name` jako klikalny element: cursor pointer, hover effect
       - `.order-status-group__name.is-active` — wyroznienie (np. bold + lewa krawedz kolorem grupy)
       - `.order-status-group__count` — styl licznika analogiczny do `.order-status-row__count`
       - Zachowac kompaktowy uklad (zgodnie z CLAUDE.md)
  </action>
  <verify>
    - Nazwa grupy jest klikalna i prowadzi do /orders/list?status_group=ID
    - Obok nazwy grupy wyswietla sie suma zamowien
    - Aktywna grupa jest wizualnie wyrozniiona
    - Na mobile panel dziala tak jak dotychczas (zwijany)
  </verify>
  <done>AC-2 i AC-3 satisfied: grupa pokazuje sume, aktywna grupa jest wyrozniiona</done>
</task>

</tasks>

<boundaries>

## DO NOT CHANGE
- database/migrations/* (brak zmian schematu — grupy i statusy juz istnieja w DB)
- src/Modules/Orders/OrdersRepository::statusPanelConfig() — nie zmieniac struktury zwracanej, tylko konsumowac
- Logika istniejacych filtrow (search, source, date_from, date_to, payment_status) — nie ruszac

## SCOPE LIMITS
- Nie dodawac mozliwosci wielokrotnego wyboru grup (multi-select)
- Nie zmieniac sposobu liczenia statusow w statusCounts()
- Nie dodawac nowych tabel ani kolumn w bazie danych

</boundaries>

<verification>
Before declaring plan complete:
- [ ] GET /orders/list?status_group=1 filtruje po wszystkich statusach z grupy
- [ ] GET /orders/list?status=new filtruje po jednym statusie (bez zmian)
- [ ] Klikniecie nazwy grupy na panelu ustawia status_group w URL
- [ ] Klikniecie statusu w grupie usuwa status_group i ustawia status
- [ ] Suma zamowien obok nazwy grupy jest poprawna
- [ ] Aktywna grupa ma wizualne wyrozniienie
- [ ] Brak bledow PHP na /orders/list bez parametrow
- [ ] Mobile: panel statusow dalej sie zwija/rozwija
</verification>

<success_criteria>
- Wszystkie taski wykonane
- Wszystkie verification checks przechodzą
- Brak nowych bledow PHP ani JS
- Filtrowanie po grupie i po statusie sa wzajemnie wylaczne
</success_criteria>

<output>
After completion, create `.paul/phases/85-status-group-filter/85-01-SUMMARY.md`
</output>
