feat(52-mobile-main-menu): hamburger + slide-in overlay sidebar na mobile
Zastapienie niedzialajacej nawigacji horyzontalnej pelnoekranowym overlay sidebar z hamburgerem, backdrop i animacja CSS transform. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -60,10 +60,11 @@ Sprzedawca może obsługiwać zamówienia ze wszystkich kanałów
|
|||||||
- [x] Automatyzacja: tab Historia z filtrowaniem/paginacja + retencja 30 dni + akcja update_order_status - Phase 49
|
- [x] Automatyzacja: tab Historia z filtrowaniem/paginacja + retencja 30 dni + akcja update_order_status - Phase 49
|
||||||
- [x] Allegro: automatyczne przekazywanie numeru przesylki do checkout form po utworzeniu paczki (tylko source=allegro) - Phase 50
|
- [x] Allegro: automatyczne przekazywanie numeru przesylki do checkout form po utworzeniu paczki (tylko source=allegro) - Phase 50
|
||||||
- [x] Email HTML Layout: header/footer HTML per skrzynka pocztowa, dual-mode edytor (Quill + HTML source), kompozycja header+body+footer, podglad — Phase 51
|
- [x] Email HTML Layout: header/footer HTML per skrzynka pocztowa, dual-mode edytor (Quill + HTML source), kompozycja header+body+footer, podglad — Phase 51
|
||||||
|
- [x] Mobile Main Menu: hamburger, slide-in overlay sidebar, backdrop na mobile <=768px — Phase 52
|
||||||
|
|
||||||
### Active (In Progress)
|
### Active (In Progress)
|
||||||
|
|
||||||
- [ ] Brak aktywnych faz
|
- [ ] Wersja mobilna — modul po module (v3.0)
|
||||||
|
|
||||||
### Planned (Next)
|
### Planned (Next)
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,17 @@ orderPRO to narzedzie do wielokanalowego zarzadzania sprzedaza. Projekt przechod
|
|||||||
|
|
||||||
## Current Milestone
|
## Current Milestone
|
||||||
|
|
||||||
No active milestone - Ready to define next scope
|
### v3.0 Mobile Responsive — In progress
|
||||||
|
|
||||||
Next action: uruchom /paul:milestone (lub /paul:plan) dla kolejnego celu biznesowego.
|
Wersja mobilna aplikacji, modul po module. Cel: pelna uzywalnosc orderPRO na telefonach i tabletach.
|
||||||
|
|
||||||
|
| Phase | Name | Plans | Status |
|
||||||
|
|-------|------|-------|--------|
|
||||||
|
| 52 | Mobile Main Menu | 1/1 | Complete |
|
||||||
|
| TBD | Mobile Orders List | - | Not started |
|
||||||
|
| TBD | Mobile Order Details | - | Not started |
|
||||||
|
| TBD | Mobile Settings | - | Not started |
|
||||||
|
| ... | Kolejne moduly wg potrzeb | - | Not started |
|
||||||
|
|
||||||
## Completed Milestones
|
## Completed Milestones
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,19 @@
|
|||||||
See: .paul/PROJECT.md (updated 2026-03-28)
|
See: .paul/PROJECT.md (updated 2026-03-28)
|
||||||
|
|
||||||
**Core value:** Sprzedawca moze obslugiwac zamowienia ze wszystkich kanalow sprzedazy i nadawac przesylki bez przelaczania sie miedzy platformami.
|
**Core value:** Sprzedawca moze obslugiwac zamowienia ze wszystkich kanalow sprzedazy i nadawac przesylki bez przelaczania sie miedzy platformami.
|
||||||
**Current focus:** Milestone v2.3 completed; ready for next PLAN / next milestone
|
**Current focus:** Milestone v3.0 Mobile Responsive — Phase 52 (Mobile Main Menu) planning
|
||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Milestone: v2.3 Email HTML Layout - Complete
|
Milestone: v3.0 Mobile Responsive — In progress
|
||||||
Phase: 1 of 1 (51 - Email HTML Layout) — Complete
|
Phase: 1 of N (52 - Mobile Main Menu) — Complete
|
||||||
Plan: 51-01 complete
|
Plan: 52-01 complete
|
||||||
Status: Loop complete - ready for next PLAN
|
Status: Loop complete — phase 52 done, ready for next PLAN
|
||||||
Last activity: 2026-03-28 — UNIFY closed for 51-01, SUMMARY created
|
Last activity: 2026-03-29 — UNIFY closed for 52-01
|
||||||
|
|
||||||
Progress:
|
Progress:
|
||||||
- Milestone: [##########] 100%
|
- Milestone: [#░░░░░░░░░] ~10%
|
||||||
- Phase 51: [##########] 100%
|
- Phase 52: [##########] 100%
|
||||||
|
|
||||||
## Loop Position
|
## Loop Position
|
||||||
|
|
||||||
@@ -29,24 +29,21 @@ PLAN ──▶ APPLY ──▶ UNIFY
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-03-28
|
Last session: 2026-03-29
|
||||||
Stopped at: Phase 51 complete, milestone v2.3 complete
|
Stopped at: Phase 52 complete
|
||||||
Next action: Uruchom /paul:milestone (lub /paul:plan) dla kolejnego celu
|
Next action: /paul:plan dla kolejnego modulu mobilnego (np. lista zamowien)
|
||||||
Resume file: .paul/phases/51-email-html-layout/51-01-SUMMARY.md
|
Resume file: .paul/phases/52-mobile-main-menu/52-01-SUMMARY.md
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
### Decisions
|
### Decisions
|
||||||
| Date | Decision | Impact |
|
| Date | Decision | Impact |
|
||||||
|------|----------|--------|
|
|------|----------|--------|
|
||||||
| 2026-03-28 | Header/footer HTML na poziomie skrzynki (nie szablonu) | Spojny branding bez duplikacji w kazdym szablonie |
|
| 2026-03-29 | Mobile menu jako slide-in overlay (nie horizontal scroll) | Pelna nawigacja na mobile bez kompromisow |
|
||||||
| 2026-03-28 | Quill.js z ograniczonym toolbar (email-safe) zamiast MJML/dedykowanego buildera | Prostota; brak build pipeline w projekcie |
|
| 2026-03-29 | Hamburger w topbarze, sidebar fixed z transform slide | Plynna animacja CSS, zero zaleznosci JS |
|
||||||
| 2026-03-28 | Zmienne resolver dziala tez w header/footer | Mozliwosc uzycia {{firma.nazwa}} w naglowku |
|
|
||||||
| 2026-03-28 | Tryb HTML source omija Quill — surowy HTML zachowany | Wklejanie gotowych szablonow email bez sanityzacji |
|
|
||||||
| 2026-03-28 | Auto-detekcja rich HTML przy ladowaniu edytora | Edytor startuje w source mode jesli HTML zawiera div+style/table |
|
|
||||||
|
|
||||||
## Git State
|
## Git State
|
||||||
|
|
||||||
Last commit: 572643a
|
Last commit: cbc2058
|
||||||
Branch: main
|
Branch: main
|
||||||
Feature branches merged: none
|
Feature branches merged: none
|
||||||
|
|||||||
209
.paul/phases/52-mobile-main-menu/52-01-PLAN.md
Normal file
209
.paul/phases/52-mobile-main-menu/52-01-PLAN.md
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
---
|
||||||
|
phase: 52-mobile-main-menu
|
||||||
|
plan: 01
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- resources/views/layouts/app.php
|
||||||
|
- resources/scss/app.scss
|
||||||
|
- public/assets/css/app.css
|
||||||
|
autonomous: false
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
## Goal
|
||||||
|
Zamiana obecnego sidebara na pelnoekranowe menu mobilne z hamburgerem, overlay i plynnym otwieraniem/zamykaniem na urzadzeniach <= 768px.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Obecne menu na mobile jest nieuzywalne — sidebar staje sie horyzontalnym paskiem z overflow-x, ktory nie miesci wszystkich linkow i wymaga przewijania. Uzytkownicy mobilni nie moga sprawnie nawigowac po aplikacji.
|
||||||
|
|
||||||
|
## Output
|
||||||
|
- Hamburger button w topbarze (widoczny tylko na mobile)
|
||||||
|
- Sidebar jako fullscreen overlay z animacja slide-in z lewej
|
||||||
|
- Zamykanie przez X, tap na overlay lub nawigacje do linku
|
||||||
|
- Zachowanie pelnej struktury menu (grupy, sublinki)
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
## Project Context
|
||||||
|
@.paul/PROJECT.md
|
||||||
|
@.paul/ROADMAP.md
|
||||||
|
@.paul/STATE.md
|
||||||
|
|
||||||
|
## Source Files
|
||||||
|
@resources/views/layouts/app.php
|
||||||
|
@resources/scss/app.scss
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<acceptance_criteria>
|
||||||
|
|
||||||
|
## AC-1: Hamburger widoczny na mobile
|
||||||
|
```gherkin
|
||||||
|
Given urzadzenie z szerokosc viewportu <= 768px
|
||||||
|
When strona sie laduje
|
||||||
|
Then w topbarze widoczny jest przycisk hamburger (3 kreski)
|
||||||
|
And sidebar jest domyslnie ukryty
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-2: Otwarcie menu
|
||||||
|
```gherkin
|
||||||
|
Given menu mobilne jest zamkniete
|
||||||
|
When uzytkownik klika hamburger
|
||||||
|
Then sidebar wysuwa sie z lewej strony jako fullscreen overlay
|
||||||
|
And tlo jest przyciemnione (backdrop)
|
||||||
|
And body nie scrolluje sie pod overlayem
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-3: Zamkniecie menu
|
||||||
|
```gherkin
|
||||||
|
Given menu mobilne jest otwarte
|
||||||
|
When uzytkownik klika X lub backdrop lub link w menu
|
||||||
|
Then menu zamyka sie z animacja
|
||||||
|
And body odzyskuje scroll
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-4: Desktop bez zmian
|
||||||
|
```gherkin
|
||||||
|
Given urzadzenie z szerokosc viewportu > 768px
|
||||||
|
When strona sie laduje
|
||||||
|
Then sidebar wyglada i dziala identycznie jak dotychczas
|
||||||
|
And hamburger nie jest widoczny
|
||||||
|
```
|
||||||
|
|
||||||
|
</acceptance_criteria>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Hamburger button + mobile JS w app.php</name>
|
||||||
|
<files>resources/views/layouts/app.php</files>
|
||||||
|
<action>
|
||||||
|
1. Dodaj przycisk hamburger w topbarze (przed div z nazwa uzytkownika):
|
||||||
|
- Klasa: `.topbar__hamburger`
|
||||||
|
- SVG 3 kreski (24x24), display: none na desktop
|
||||||
|
- aria-label="Otworz menu"
|
||||||
|
|
||||||
|
2. Dodaj backdrop div po sidebar: `<div class="sidebar-backdrop" id="js-sidebar-backdrop"></div>`
|
||||||
|
|
||||||
|
3. W bloku `<script>` na dole dodaj logike mobile menu:
|
||||||
|
- Klik hamburger -> sidebar.classList.add('is-mobile-open'), backdrop show, body overflow hidden
|
||||||
|
- Klik backdrop -> zamknij
|
||||||
|
- Klik X (collapse-btn na mobile pelni role X) -> zamknij
|
||||||
|
- Klik na sidebar__link / sidebar__sublink -> zamknij (nawigacja)
|
||||||
|
- Funkcja closeMobileMenu() wydzielona
|
||||||
|
- Detekcja mobile: window.matchMedia('(max-width: 768px)')
|
||||||
|
|
||||||
|
Unikaj: addEventListener na kazdym renderze (uzyj jednorazowego IIFE)
|
||||||
|
</action>
|
||||||
|
<verify>Otworz strone na urzadzeniu/emulatorze mobilnym, hamburger widoczny, klik otwiera sidebar overlay, klik backdrop/link zamyka</verify>
|
||||||
|
<done>AC-1, AC-2, AC-3 satisfied</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Mobile menu SCSS — overlay, animacje, hamburger</name>
|
||||||
|
<files>resources/scss/app.scss</files>
|
||||||
|
<action>
|
||||||
|
1. Zastap obecny blok `@media (max-width: 768px)` nowa wersja:
|
||||||
|
|
||||||
|
Hamburger (`.topbar__hamburger`):
|
||||||
|
- display: none na desktop
|
||||||
|
- display: flex na mobile (w media query)
|
||||||
|
- 36x36px, transparent bg, border none, kolor ikony currentColor
|
||||||
|
|
||||||
|
Sidebar na mobile:
|
||||||
|
- position: fixed, top: 0, left: 0, bottom: 0
|
||||||
|
- width: 280px (nie 100%)
|
||||||
|
- transform: translateX(-100%) domyslnie
|
||||||
|
- transition: transform 0.25s ease
|
||||||
|
- z-index: 1000
|
||||||
|
- &.is-mobile-open { transform: translateX(0) }
|
||||||
|
- Zachowaj obecny ciemny styl (#111a28)
|
||||||
|
- overflow-y: auto (scroll dla dlugiego menu)
|
||||||
|
|
||||||
|
Backdrop (`.sidebar-backdrop`):
|
||||||
|
- display: none domyslnie
|
||||||
|
- Na mobile: position: fixed, inset: 0, background rgba(0,0,0,0.5)
|
||||||
|
- z-index: 999
|
||||||
|
- &.is-visible { display: block }
|
||||||
|
- transition: opacity 0.25s
|
||||||
|
|
||||||
|
Sidebar__nav na mobile:
|
||||||
|
- Powrot do display: grid (pionowo), nie flex horizontal
|
||||||
|
- Usun overflow-x: auto
|
||||||
|
|
||||||
|
Sidebar__collapse-btn na mobile:
|
||||||
|
- Wyswietl jako przycisk X (zamknij) zamiast ukrywania
|
||||||
|
- Obrot ikony 180deg (strzalka w prawo = zamknij)
|
||||||
|
|
||||||
|
2. Zachowaj wszystkie pozostale regusy z obecnego media query (settings-grid, page-head, orders-stats itd.)
|
||||||
|
|
||||||
|
Unikaj: !important (usun obecne !important z .sidebar width)
|
||||||
|
</action>
|
||||||
|
<verify>Resize okna przegladarki do <= 768px — sidebar ukryty, hamburger widoczny, slide-in dziala, desktop bez zmian</verify>
|
||||||
|
<done>AC-1, AC-2, AC-3, AC-4 satisfied</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 3: Build CSS</name>
|
||||||
|
<files>public/assets/css/app.css</files>
|
||||||
|
<action>
|
||||||
|
Skompiluj SCSS do CSS. Jezeli brak SASS compiler w srodowisku, skopiuj wynikowy CSS odpowiadajacy zmianom SCSS do pliku wynikowego.
|
||||||
|
</action>
|
||||||
|
<verify>Porownaj app.css z app.scss — zmiany media query obecne w wynikowym CSS</verify>
|
||||||
|
<done>Plik CSS aktualny z SCSS</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="checkpoint:human-verify" gate="blocking">
|
||||||
|
<what-built>Menu mobilne z hamburgerem, overlay sidebar, animacja slide-in</what-built>
|
||||||
|
<how-to-verify>
|
||||||
|
1. Otworz aplikacje w przegladarce
|
||||||
|
2. Wlacz DevTools > Device Toolbar (Ctrl+Shift+M) > wybierz iPhone 14 lub 375px
|
||||||
|
3. Sprawdz: hamburger widoczny w topbarze, sidebar ukryty
|
||||||
|
4. Kliknij hamburger — sidebar wysuwa sie z lewej z backdrop
|
||||||
|
5. Kliknij backdrop — menu sie zamyka
|
||||||
|
6. Otworz ponownie, kliknij link "Zamowienia" — nawigacja + menu sie zamyka
|
||||||
|
7. Przelacz na desktop (> 768px) — sidebar normalny, bez hamburgera
|
||||||
|
</how-to-verify>
|
||||||
|
<resume-signal>Type "approved" to continue, or describe issues to fix</resume-signal>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<boundaries>
|
||||||
|
|
||||||
|
## DO NOT CHANGE
|
||||||
|
- resources/views/layouts/auth.php (layout logowania osobny)
|
||||||
|
- resources/scss/shared/_ui-components.scss (zmienne CSS nietykane)
|
||||||
|
- resources/scss/modules/* (moduly SCSS osobne)
|
||||||
|
- Logika collapse/localStorage na desktop (zachowac w calosci)
|
||||||
|
|
||||||
|
## SCOPE LIMITS
|
||||||
|
- Tylko menu glowne (sidebar + topbar) — zadne inne moduly mobilne
|
||||||
|
- Nie zmieniaj struktury HTML menu (kolejnosc linkow, klasy is-active)
|
||||||
|
- Nie dodawaj nowych zaleznosci JS (vanilla JS only)
|
||||||
|
|
||||||
|
</boundaries>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
Before declaring plan complete:
|
||||||
|
- [ ] Hamburger widoczny na <= 768px, ukryty na desktop
|
||||||
|
- [ ] Sidebar slide-in z lewej z animacja
|
||||||
|
- [ ] Backdrop przyciemnia tlo i zamyka menu na klik
|
||||||
|
- [ ] Klik na link zamyka menu
|
||||||
|
- [ ] Body nie scrolluje pod overlayem
|
||||||
|
- [ ] Desktop layout identyczny jak przed zmianami
|
||||||
|
- [ ] Collapse button na desktop dziala jak dotychczas
|
||||||
|
- [ ] Brak bledow JS w konsoli
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- Wszystkie 4 acceptance criteria spelnione
|
||||||
|
- Menu mobilne uzywalne na ekranach 320px-768px
|
||||||
|
- Animacje plynne (CSS transitions, nie JS)
|
||||||
|
- Zero regresji na desktop
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
After completion, create `.paul/phases/52-mobile-main-menu/52-01-SUMMARY.md`
|
||||||
|
</output>
|
||||||
111
.paul/phases/52-mobile-main-menu/52-01-SUMMARY.md
Normal file
111
.paul/phases/52-mobile-main-menu/52-01-SUMMARY.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
---
|
||||||
|
phase: 52-mobile-main-menu
|
||||||
|
plan: 01
|
||||||
|
subsystem: ui
|
||||||
|
tags: [mobile, responsive, sidebar, hamburger, css-animation]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: none
|
||||||
|
provides: n/a
|
||||||
|
provides:
|
||||||
|
- Mobile-friendly main menu with hamburger toggle and slide-in overlay sidebar
|
||||||
|
affects: [mobile-orders-list, mobile-order-details, mobile-settings]
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns: [mobile-overlay-sidebar, hamburger-toggle, css-transform-slide, backdrop-overlay]
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- resources/views/layouts/app.php
|
||||||
|
- resources/scss/app.scss
|
||||||
|
- public/assets/css/app.css
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Slide-in overlay (280px) zamiast horizontal scroll — pelna nawigacja na mobile"
|
||||||
|
- "Collapse button na mobile dziala jako X (zamknij) — reuse istniejacego elementu"
|
||||||
|
- "Vanilla JS matchMedia — zero nowych zaleznosci"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Mobile overlay pattern: fixed sidebar + backdrop + body.no-scroll + is-mobile-open class"
|
||||||
|
- "Hamburger w topbarze: .topbar__hamburger ukryty na desktop, widoczny na mobile"
|
||||||
|
|
||||||
|
duration: ~15min
|
||||||
|
started: 2026-03-29
|
||||||
|
completed: 2026-03-29
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 52 Plan 01: Mobile Main Menu Summary
|
||||||
|
|
||||||
|
**Slide-in overlay sidebar z hamburgerem na mobile (<=768px) — zastapienie niedzialajacej nawigacji horyzontalnej**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|--------|-------|
|
||||||
|
| Duration | ~15min |
|
||||||
|
| Started | 2026-03-29 |
|
||||||
|
| Completed | 2026-03-29 |
|
||||||
|
| Tasks | 4 completed (3 auto + 1 checkpoint) |
|
||||||
|
| Files modified | 3 |
|
||||||
|
|
||||||
|
## Acceptance Criteria Results
|
||||||
|
|
||||||
|
| Criterion | Status | Notes |
|
||||||
|
|-----------|--------|-------|
|
||||||
|
| AC-1: Hamburger widoczny na mobile | Pass | Przycisk 36x36 w topbarze, display:flex na <=768px |
|
||||||
|
| AC-2: Otwarcie menu | Pass | Slide-in z lewej (280px), backdrop, body scroll lock |
|
||||||
|
| AC-3: Zamkniecie menu | Pass | X / backdrop / link click — wszystkie zamykaja |
|
||||||
|
| AC-4: Desktop bez zmian | Pass | Sidebar i collapse dzialaja identycznie |
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- Hamburger button w topbarze z SVG ikonka (widoczny tylko na mobile)
|
||||||
|
- Sidebar jako fixed overlay 280px z CSS transform slide-in (0.25s ease)
|
||||||
|
- Backdrop overlay z rgba(0,0,0,0.5) zamykajacy menu na klik
|
||||||
|
- Body scroll lock (class no-scroll) gdy menu otwarte
|
||||||
|
- Collapse button pelni role X na mobile (ikona obrocona 180deg)
|
||||||
|
- Zamykanie menu przy kliknieciu linku nawigacyjnego
|
||||||
|
- Reset stanu przy resize do desktop (matchMedia change listener)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
| File | Change | Purpose |
|
||||||
|
|------|--------|---------|
|
||||||
|
| `resources/views/layouts/app.php` | Modified | Hamburger button, backdrop div, mobile JS logic |
|
||||||
|
| `resources/scss/app.scss` | Modified | Nowe klasy mobile (hamburger, backdrop, overlay sidebar), zastapienie starego media query |
|
||||||
|
| `public/assets/css/app.css` | Modified | Kompilacja SCSS |
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
| Decision | Rationale | Impact |
|
||||||
|
|----------|-----------|--------|
|
||||||
|
| Sidebar 280px fixed zamiast 100% fullscreen | Widoczny kontekst strony za menu, lepszy UX | Naturalny pattern znany z aplikacji mobilnych |
|
||||||
|
| Reuse collapse-btn jako X na mobile | Mniej nowych elementow HTML, istniejacy SVG strzalki obraca sie | Jednoczesnie zachowany collapse na desktop |
|
||||||
|
| Usuniecie !important z sidebar width | Czystszy CSS, nie koliduje z fixed positioning | Latwiejsze utrzymanie |
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None — plan executed exactly as written
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
**Ready:**
|
||||||
|
- Layout mobilny dziala — sidebar, topbar, container dostosowane
|
||||||
|
- Pattern mobile overlay gotowy do reuse w przyszlych modulach
|
||||||
|
- Wszystkie istniejace mobile overrides (gridy, formularze) zachowane
|
||||||
|
|
||||||
|
**Concerns:**
|
||||||
|
- Kolejne moduly (lista zamowien, szczegoly, ustawienia) wymagaja osobnych planow mobilnych
|
||||||
|
|
||||||
|
**Blockers:**
|
||||||
|
- None
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 52-mobile-main-menu, Plan: 01*
|
||||||
|
*Completed: 2026-03-29*
|
||||||
File diff suppressed because one or more lines are too long
@@ -2251,37 +2251,85 @@ h4.section-title {
|
|||||||
color: #334155;
|
color: #334155;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hamburger button (hidden on desktop)
|
||||||
|
.topbar__hamburger {
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: var(--c-text-strong);
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 6px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--c-bg-subtle, #f1f5f9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mobile backdrop overlay
|
||||||
|
.sidebar-backdrop {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 999;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.25s ease;
|
||||||
|
|
||||||
|
&.is-visible {
|
||||||
|
display: block;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body scroll lock
|
||||||
|
body.no-scroll {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.app-shell {
|
.topbar__hamburger {
|
||||||
flex-direction: column;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
width: 100% !important;
|
position: fixed;
|
||||||
min-width: 0 !important;
|
top: 0;
|
||||||
border-right: 0;
|
left: 0;
|
||||||
border-bottom: 1px solid #243041;
|
bottom: 0;
|
||||||
padding: 14px;
|
width: 280px;
|
||||||
overflow-x: auto;
|
min-width: 280px;
|
||||||
|
z-index: 1000;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
transition: transform 0.25s ease;
|
||||||
|
border-right: 1px solid #243041;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
&.is-mobile-open {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar__brand {
|
.sidebar__brand {
|
||||||
margin: 0 0 10px;
|
margin: 4px 4px 12px;
|
||||||
font-size: 22px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar__collapse-btn {
|
.sidebar__collapse-btn {
|
||||||
display: none;
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar__collapse-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar__nav {
|
.sidebar__nav {
|
||||||
display: flex;
|
display: grid;
|
||||||
gap: 8px;
|
gap: 4px;
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar__link {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.topbar {
|
.topbar {
|
||||||
|
|||||||
@@ -115,8 +115,17 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
|
<div class="sidebar-backdrop" id="js-sidebar-backdrop"></div>
|
||||||
|
|
||||||
<div class="app-main">
|
<div class="app-main">
|
||||||
<header class="topbar">
|
<header class="topbar">
|
||||||
|
<button class="topbar__hamburger" id="js-hamburger" type="button" aria-label="Otwórz menu">
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<line x1="3" y1="6" x2="21" y2="6"/>
|
||||||
|
<line x1="3" y1="12" x2="21" y2="12"/>
|
||||||
|
<line x1="3" y1="18" x2="21" y2="18"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
<div>
|
<div>
|
||||||
<strong><?= $e((string) (($user['name'] ?? '') !== '' ? $user['name'] : ($user['email'] ?? ''))) ?></strong>
|
<strong><?= $e((string) (($user['name'] ?? '') !== '' ? $user['name'] : ($user['email'] ?? ''))) ?></strong>
|
||||||
</div>
|
</div>
|
||||||
@@ -167,6 +176,60 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Mobile menu
|
||||||
|
var hamburger = document.getElementById('js-hamburger');
|
||||||
|
var backdrop = document.getElementById('js-sidebar-backdrop');
|
||||||
|
var mobileQuery = window.matchMedia('(max-width: 768px)');
|
||||||
|
|
||||||
|
function closeMobileMenu() {
|
||||||
|
sidebar.classList.remove('is-mobile-open');
|
||||||
|
backdrop.classList.remove('is-visible');
|
||||||
|
document.body.classList.remove('no-scroll');
|
||||||
|
}
|
||||||
|
|
||||||
|
function openMobileMenu() {
|
||||||
|
sidebar.classList.add('is-mobile-open');
|
||||||
|
backdrop.classList.add('is-visible');
|
||||||
|
document.body.classList.add('no-scroll');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hamburger) {
|
||||||
|
hamburger.addEventListener('click', function () {
|
||||||
|
if (sidebar.classList.contains('is-mobile-open')) {
|
||||||
|
closeMobileMenu();
|
||||||
|
} else {
|
||||||
|
openMobileMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backdrop) {
|
||||||
|
backdrop.addEventListener('click', closeMobileMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close button (collapse-btn acts as X on mobile)
|
||||||
|
collapseBtn.addEventListener('click', function () {
|
||||||
|
if (mobileQuery.matches) {
|
||||||
|
closeMobileMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close on navigation link click (mobile only)
|
||||||
|
sidebar.querySelectorAll('.sidebar__link, .sidebar__sublink').forEach(function (link) {
|
||||||
|
link.addEventListener('click', function () {
|
||||||
|
if (mobileQuery.matches) {
|
||||||
|
closeMobileMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Reset state on resize to desktop
|
||||||
|
mobileQuery.addEventListener('change', function (e) {
|
||||||
|
if (!e.matches) {
|
||||||
|
closeMobileMenu();
|
||||||
|
}
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user