diff --git a/.gitignore b/.gitignore
index 8b6721e..584de4f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
.scannerwork/
+.env
diff --git a/.paul/ROADMAP.md b/.paul/ROADMAP.md
index 3c2d564..0030758 100644
--- a/.paul/ROADMAP.md
+++ b/.paul/ROADMAP.md
@@ -1,42 +1,43 @@
-# Roadmap: crmPRO
+# Roadmap: crmPRO
## Overview
-Stabilizacja i poprawa jakości kodu crmPRO — identyfikacja i naprawa błędów, analiza jakości kodu przez SonarQube.
+Stabilizacja i poprawa jakosci kodu crmPRO oraz rozwoj finansow o automatyczny import faktur z Fakturowni.
## Current Milestone
-**v0.1 Stabilizacja i jakość kodu** (v0.1.0)
+**v0.1 Stabilizacja i jakosc kodu + import finansow** (v0.1.0)
Status: In progress
-Phases: 1 of 4 complete
+Phases: 1 of 5 complete
## Phases
| Phase | Name | Plans | Status | Completed |
|-------|------|-------|--------|-----------|
-| 1 | Konfiguracja SonarQube i baseline | 1/1 | ✅ Complete | 2026-03-15 |
-| 2 | Naprawa błędów krytycznych | TBD | 🔵 Next | - |
-| 3 | Naprawa błędów głównych | TBD | Not started | - |
+| 1 | Konfiguracja SonarQube i baseline | 1/1 | Complete | 2026-03-15 |
+| 2 | Naprawa bledow krytycznych | TBD | Next | - |
+| 3 | Naprawa bledow glownych | TBD | Not started | - |
| 4 | Poprawa pokrycia testami | TBD | Not started | - |
+| 5 | Import finansow z Fakturowni | 0/1 | Planning | - |
## Phase Details
-### Phase 1: Konfiguracja SonarQube i baseline ✅
+### Phase 1: Konfiguracja SonarQube i baseline
-**Goal:** Skonfigurować projekt w SonarQube, uruchomić pierwszy skan i uzyskać baseline jakości kodu
+**Goal:** Skonfigurowac projekt w SonarQube, uruchomic pierwszy skan i uzyskac baseline jakosci kodu
**Depends on:** Nothing (first phase)
**Completed:** 2026-03-15
**Results:**
- sonar-project.properties skonfigurowany
-- Pierwszy skan: 88 plików, 9356 LoC
+- Pierwszy skan: 88 plikow, 9356 LoC
- Baseline: 58 bugs, 1649 code smells, 0% coverage, 5.6% duplikacji
- Reliability: D, Security: A, Maintainability: A
**Plans:**
-- [x] 01-01: Konfiguracja SonarQube i analiza wyników pierwszego skanu
+- [x] 01-01: Konfiguracja SonarQube i analiza wynikow pierwszego skanu
-### Phase 2: Naprawa błędów krytycznych
+### Phase 2: Naprawa bledow krytycznych
-**Goal:** Naprawić wszystkie bugs i vulnerabilities o priorytecie Critical/Blocker
+**Goal:** Naprawic wszystkie bugs i vulnerabilities o priorytecie Critical/Blocker
**Depends on:** Phase 1 (wyniki skanu)
**Research:** Unlikely
@@ -46,11 +47,11 @@ Phases: 1 of 4 complete
- Reskan po naprawach
**Plans:**
-- [ ] 02-01: TBD (na podstawie wyników Phase 1)
+- [ ] 02-01: TBD (na podstawie wynikow Phase 1)
-### Phase 3: Naprawa błędów głównych
+### Phase 3: Naprawa bledow glownych
-**Goal:** Naprawić bugs o priorytecie Major i code smells wpływające na stabilność
+**Goal:** Naprawic bugs o priorytecie Major i code smells wplywajace na stabilnosc
**Depends on:** Phase 2
**Research:** Unlikely
@@ -60,21 +61,36 @@ Phases: 1 of 4 complete
- Reskan po naprawach
**Plans:**
-- [ ] 03-01: TBD (na podstawie wyników Phase 2)
+- [ ] 03-01: TBD (na podstawie wynikow Phase 2)
### Phase 4: Poprawa pokrycia testami
-**Goal:** Dodać testy dla kluczowych modułów zidentyfikowanych przez SonarQube
+**Goal:** Dodac testy dla kluczowych modulow zidentyfikowanych przez SonarQube
**Depends on:** Phase 3
**Research:** Unlikely
**Scope:**
-- Testy dla modułów o najniższym pokryciu
-- Testy regresji dla naprawionych bugów
+- Testy dla modulow o najnizszym pokryciu
+- Testy regresji dla naprawionych bugow
**Plans:**
-- [ ] 04-01: TBD (na podstawie wyników Phase 3)
+- [ ] 04-01: TBD (na podstawie wynikow Phase 3)
+
+### Phase 5: Import finansow z Fakturowni
+
+**Goal:** Wdrozyc automatyczny import faktur przychodowych i kosztowych z Fakturowni do finansow crmPRO
+**Depends on:** None (moze byc realizowane niezaleznie od prac SonarQube)
+**Research:** Likely (szczegoly endpointow API i semantyka pol dokumentow)
+
+**Scope:**
+- Integracja API Fakturownia (dane z `.env` + data startu importu)
+- Trwale mapowanie klientow i produktow/uslug do struktur finansowych CRM
+- Import cykliczny przez cron z idempotencja i obsluga bledow
+- Panel mapowania brakow w `/finances/main_view/`
+
+**Plans:**
+- [ ] 05-01: Integracja Fakturownia i automatyczny import do finansow
---
*Roadmap created: 2026-03-15*
-*Last updated: 2026-03-15 — Phase 1 complete*
+*Last updated: 2026-04-02 - Phase 5 planned*
diff --git a/.paul/STATE.md b/.paul/STATE.md
index af23936..bbd1048 100644
--- a/.paul/STATE.md
+++ b/.paul/STATE.md
@@ -1,57 +1,38 @@
-# Project State
+# Project State
## Project Reference
See: .paul/PROJECT.md (updated 2026-03-15)
-**Core value:** Użytkownicy mogą efektywnie zarządzać projektami, zadaniami i klientami w jednym systemie CRM
-**Current focus:** Faza 2 — Naprawa błędów krytycznych
+**Core value:** Uzytkownicy moga efektywnie zarzadzac projektami, zadaniami i klientami w jednym systemie CRM
+**Current focus:** Faza 5 - Import finansow z Fakturowni
## Current Position
-Milestone: v0.1 Stabilizacja i jakość kodu
-Phase: 2 of 4 (Naprawa błędów krytycznych) — In Progress
-Plan: 02-02 complete, 02-01 awaiting approval
-Status: Loop closed for 02-02, ready for next plan
-Last activity: 2026-03-15 — Completed .paul/phases/02-critical-bugs-fix/02-02-SUMMARY.md
+Milestone: v0.1 Stabilizacja i jakosc kodu
+Phase: 5 of 5 (Import finansow z Fakturowni) - Apply complete
+Plan: 05-01 executed, awaiting unify
+Status: APPLY complete, ready for UNIFY
+Last activity: 2026-04-02 11:03 - Executed .paul/phases/05-finances-fakturownia-import/05-01-PLAN.md
Progress:
-- Milestone: [██░░░░░░░░] 25%
-- Phase 2: [█████░░░░░] 50% (1/2 plans complete)
+- Milestone: [#######---] 35%
+- Phase 5: [########--] 80%
## Loop Position
Current loop state:
```
-PLAN ──▶ APPLY ──▶ UNIFY
- ✓ ✓ ✓ [Loop complete for 02-02 — ready for next PLAN]
+PLAN --> APPLY --> UNIFY
+ ✓ ✓ ○ [Apply completed, ready for reconciliation]
```
-## Accumulated Context
-
-### Decisions
-- 2026-03-15: SonarQube URL = https://sonar.project-pro.pl (nie localhost)
-- 2026-03-15: Skan automatyczny via sonar-scanner CLI + MCP do odczytu wyników
-- 2026-03-15: Usunięto nawigację z layout-cron zamiast ukrywania CSS
-- 2026-03-15: JSON.parse zamiast deprecated jQuery.parseJSON
-
-### Deferred Issues
-None yet.
-
-### Blockers/Concerns
-None.
-
-### Git State
-Last commit: e92c9fe
-Branch: main
-Feature branches merged: none
-
## Session Continuity
-Last session: 2026-03-15
-Stopped at: Plan 02-02 UNIFY complete
-Next action: Approve and execute plan 02-01 (SonarQube bugs fix) — run /paul:apply .paul/phases/02-critical-bugs-fix/02-01-PLAN.md
-Resume file: .paul/phases/02-critical-bugs-fix/02-02-SUMMARY.md
+Last session: 2026-04-02 11:03
+Stopped at: Apply finished for plan 05-01
+Next action: Run $paul-unify .paul/phases/05-finances-fakturownia-import/05-01-PLAN.md
+Resume file: .paul/phases/05-finances-fakturownia-import/05-01-PLAN.md
---
-*STATE.md — Updated after every significant action*
+*STATE.md - Updated after every significant action*
diff --git a/.paul/phases/05-finances-fakturownia-import/05-01-PLAN.md b/.paul/phases/05-finances-fakturownia-import/05-01-PLAN.md
new file mode 100644
index 0000000..2fbb3c8
--- /dev/null
+++ b/.paul/phases/05-finances-fakturownia-import/05-01-PLAN.md
@@ -0,0 +1,223 @@
+---
+phase: 05-finances-fakturownia-import
+plan: 01
+type: execute
+wave: 1
+depends_on: []
+files_modified:
+ - cron.php
+ - autoload/class.Cron.php
+ - autoload/Controllers/FinancesController.php
+ - autoload/Domain/Finances/FinanceRepository.php
+ - autoload/Domain/Finances/FakturowniaApiClient.php
+ - autoload/Domain/Finances/FakturowniaImportRepository.php
+ - autoload/Domain/Finances/FakturowniaInvoiceImporter.php
+ - templates/finances/main-view.php
+ - templates/finances/fakturownia-import-panel.php
+ - .env.example
+autonomous: true
+---
+
+
+## Goal
+Dodac automatyczny import faktur przychodowych i kosztowych z Fakturowni do finansow crmPRO, z mechanizmem uczenia mapowan klientow i produktow/uslug.
+
+## Purpose
+Zminimalizowac reczna prace w finansach: pierwsze faktury wymagaja mapowania, ale kolejne dokumenty z tymi samymi klientami i pozycjami maja importowac sie juz calkowicie automatycznie.
+
+## Output
+- Warstwa integracji API Fakturowni z konfiguracja przez `.env`
+- Trwale mapowania klientow i produktow/uslug do struktur finansowych crmPRO
+- Automatyczny import przez cron z idempotencja i data startu
+- Panel w finansach do obslugi brakujacych mapowan
+
+
+
+## Project Context
+@.paul/PROJECT.md
+@.paul/ROADMAP.md
+@.paul/STATE.md
+
+## Source Files
+@cron.php
+@autoload/class.Cron.php
+@autoload/Controllers/FinancesController.php
+@autoload/Domain/Finances/FinanceRepository.php
+@templates/finances/main-view.php
+@config.php
+
+
+
+
+## AC-1: Konfiguracja API i data startu importu
+```gherkin
+Given w pliku .env ustawiono dane dostepowe Fakturowni oraz date startu importu
+When cron uruchamia proces importu
+Then importer laczy sie z API Fakturowni i pobiera tylko dokumenty od skonfigurowanej daty
+ And brakujaca konfiguracja zwraca czytelny blad bez przerwania calego crona
+```
+
+## AC-2: Import przychodow i kosztow z idempotencja
+```gherkin
+Given faktura przychodowa lub kosztowa istnieje w Fakturowni
+When dokument ma komplet mapowan klienta i pozycji
+Then powstaje operacja finansowa w crmPRO z poprawnym znakiem kwoty (przychod > 0, koszt < 0)
+ And ponowne uruchomienie importu nie tworzy duplikatu tej samej faktury
+```
+
+## AC-3: Mechanizm uczenia mapowan
+```gherkin
+Given dokument zawiera klienta lub pozycje bez mapowania
+When importer przetwarza dokument
+Then dokument nie jest importowany do finansow, a brakujace mapowania trafiaja na liste do recznego przypisania
+ And po zapisaniu mapowania kolejne faktury z tym klientem/pozycja importuja sie automatycznie
+```
+
+## AC-4: Obsluga mapowan w zakladce finansow
+```gherkin
+Given uzytkownik jest na /finances/main_view/
+When otwiera panel importu Fakturownia
+Then widzi brakujace mapowania klientow i produktow/uslug
+ And moze przypisac klienta CRM i kategorie finansowa
+ And zapis mapowania jest chroniony tokenem CSRF
+```
+
+
+
+
+
+
+ Task 1: Zbudowac warstwe integracji Fakturownia + trwawe mapowania
+
+ autoload/Domain/Finances/FakturowniaApiClient.php,
+ autoload/Domain/Finances/FakturowniaImportRepository.php,
+ autoload/Domain/Finances/FinanceRepository.php,
+ .env.example
+
+
+ 1. Dodac loader `.env` (bez nowych bibliotek) i zdefiniowac klucze:
+ - `FAKTUROWNIA_API_DOMAIN`
+ - `FAKTUROWNIA_API_TOKEN`
+ - `FAKTUROWNIA_START_DATE`
+ - `FAKTUROWNIA_PAGE_LIMIT` (opcjonalnie)
+ 2. Dodac klienta API Fakturowni z obsluga paginacji i timeoutow:
+ - pobieranie faktur przychodowych (np. endpoint invoices)
+ - pobieranie faktur kosztowych (np. endpoint costs/expenses)
+ 3. Dodac repozytorium importu z tabelami tworzonymi przez `CREATE TABLE IF NOT EXISTS`:
+ - tabela mapowania klientow Fakturownia -> crm_client.id
+ - tabela mapowania pozycji (nazwa produktu/uslugi) -> finance_categories.id
+ - tabela stanu importu i idempotencji (external_id + typ dokumentu)
+ - tabela kolejki brakujacych mapowan do panelu finansow
+ 4. Wszystkie zapytania SQL wykonywac przez medoo/query z parametrami bindowanymi (bez sklejania SQL z danymi wejsciowymi).
+ 5. W `FinanceRepository` dodac metody pomocnicze do pobierania kategorii i klientow dla panelu mapowan.
+
+ Unikac: trzymania tokenu API w `config.php`, mapowan w sesji i importu bez kontroli duplikatow.
+
+
+ - Odczyt `.env.example` potwierdza nowe klucze integracji.
+ - Odczyt nowych klas potwierdza osobne odpowiedzialnosci (API, repo mapowan, state importu).
+ - Test manualny: dwukrotne wywolanie zapisu importu dla tego samego external_id nie tworzy duplikatu.
+
+ AC-1 i AC-2 i AC-3 satisfied: konfiguracja, idempotencja i struktury mapowan gotowe
+
+
+
+ Task 2: Dodac importer dokumentow i podpiac go pod cron
+
+ autoload/Domain/Finances/FakturowniaInvoiceImporter.php,
+ autoload/class.Cron.php,
+ cron.php
+
+
+ 1. Dodac serwis importera, ktory:
+ - pobiera dokumenty od `FAKTUROWNIA_START_DATE`,
+ - scala dane klienta i pozycji,
+ - sprawdza mapowania klienta i pozycji,
+ - przy komplecie mapowan zapisuje operacje finansowe,
+ - przy brakach wpisuje rekordy do kolejki brakow mapowan i pomija import dokumentu.
+ 2. Dodac polityke znaku kwoty:
+ - przychodowe -> dodatnie `amount`
+ - kosztowe -> ujemne `amount`
+ 3. Wprowadzic idempotencje na poziomie zrodlowego `external_id` + typ dokumentu.
+ 4. Rozszerzyc `Cron` i `cron.php` o krok `import_finances_from_fakturownia()`:
+ - uruchamiany przy kazdym cyklu crona,
+ - zwraca statusy `ok|empty|error` analogicznie do obecnych zadan,
+ - loguje krotki komunikat o liczbie zaimportowanych i pominietych dokumentow.
+
+ Unikac: przerywania calego crona przy pojedynczym bledzie faktury.
+
+
+ - Suchy przebieg importera zwraca licznik imported/skipped/unmapped.
+ - Uruchomienie `php cron.php` wykonuje nowy krok i nie psuje istniejacych zadan cron.
+ - Powtorne uruchomienie dla tych samych danych nie dubluje wpisow w `finance_operations`.
+
+ AC-1 i AC-2 i AC-3 satisfied: cron importuje faktury cyklicznie i bez duplikatow
+
+
+
+ Task 3: Dodac panel mapowan Fakturowni w finansach i zapis mapowan
+
+ autoload/Controllers/FinancesController.php,
+ templates/finances/main-view.php,
+ templates/finances/fakturownia-import-panel.php
+
+
+ 1. Rozszerzyc `FinancesController` o akcje:
+ - pobranie brakujacych mapowan do widoku finansow,
+ - zapis mapowania klienta,
+ - zapis mapowania produktu/uslugi do kategorii,
+ - wszystkie zapisy z walidacja i `S::csrf_verify()`.
+ 2. W `templates/finances/main-view.php` dolaczyc panel importu (partial) pokazujacy:
+ - liste nieprzypisanych klientow z Fakturowni + select klienta CRM,
+ - liste nieprzypisanych pozycji + select kategorii finansowej,
+ - status ostatniego importu (czas, liczba imported/skipped/unmapped).
+ 3. W panelu uzyc escapingu danych wyjsciowych (np. `htmlspecialchars`) i komunikatow zgodnych z UI crmPRO.
+
+ Unikac: logiki biznesowej bezposrednio w widoku.
+
+
+ - Wejscie na `/finances/main_view/` pokazuje panel mapowan bez regresji istniejacych statystyk.
+ - Zapis mapowania bez tokenu CSRF jest odrzucany.
+ - Po zapisaniu mapowania i ponownym imporcie dokument znika z listy brakow i tworzy operacje automatycznie.
+
+ AC-3 i AC-4 satisfied: mapowania sa obslugiwane z UI i kolejne faktury wpadaja automatycznie
+
+
+
+
+
+
+## DO NOT CHANGE
+- modules niezwiązane z finansami (tasks, projects, wiki)
+- mechanizm logowania i sesji poza niezbednym CSRF check
+- istniejace endpointy email importera zadan
+
+## SCOPE LIMITS
+- Ten plan obejmuje tylko import i mapowania Fakturownia -> Finanse
+- Bez refaktoryzacji calego modulu finansow
+- Bez zmian w zewnetrznym harmonogramie systemowym (zakladamy, ze cron systemowy juz wywoluje `cron.php`)
+- Bez automatycznego tworzenia nowych klientow CRM (tylko mapowanie do istniejacych)
+
+
+
+
+Before declaring plan complete:
+- [ ] `.env.example` zawiera komplet nowych zmiennych Fakturowni
+- [ ] Importer obsluguje dokumenty przychodowe i kosztowe
+- [ ] Idempotencja blokuje duplikaty importu
+- [ ] Brakujace mapowania sa kolejkowane i widoczne w finansach
+- [ ] Zapis mapowan wymaga poprawnego tokenu CSRF
+- [ ] `php cron.php` wykonuje import bez zatrzymywania pozostalych krokow
+- [ ] All acceptance criteria met
+
+
+
+- Faktury przychodowe i kosztowe importuja sie automatycznie po uzupelnieniu mapowan
+- Pierwszy import nie robi blednych przypisan: nieznane rekordy trafiaja do kolejki mapowania
+- Kolejne dokumenty z tym samym klientem i pozycja sa przypisywane bez interwencji recznej
+- Import uruchamia sie cyklicznie przez cron i jest bezpieczny na ponowne wykonanie
+
+
+
diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json
index b5893c6..d5fbc20 100644
--- a/.vscode/ftp-kr.sync.cache.json
+++ b/.vscode/ftp-kr.sync.cache.json
@@ -681,8 +681,8 @@
},
"main_view.php": {
"type": "-",
- "size": 47213,
- "lmtime": 1773530856493,
+ "size": 49131,
+ "lmtime": 1774532986644,
"modified": false
},
"task_edit.php": {
@@ -693,9 +693,9 @@
},
"task_popup.php": {
"type": "-",
- "size": 42366,
+ "size": 45012,
"lmtime": 1773530848546,
- "modified": false
+ "modified": true
},
"task_single.php": {
"type": "-",
@@ -703,11 +703,17 @@
"lmtime": 1772276304856,
"modified": false
},
+ "task_work_logs_popup.php": {
+ "type": "-",
+ "size": 2629,
+ "lmtime": 0,
+ "modified": false
+ },
"work-time.php": {
"type": "-",
- "size": 12763,
+ "size": 15966,
"lmtime": 1771236164971,
- "modified": false
+ "modified": true
}
},
"users": {
diff --git a/__tmp_count.php b/__tmp_count.php
new file mode 100644
index 0000000..2f06d81
--- /dev/null
+++ b/__tmp_count.php
@@ -0,0 +1,47 @@
+= strtotime($start) && (($doc['income'] ?? true) !== false)) $sf[] = $doc;
+}
+
+$cf = [];
+foreach ($costs as $doc) {
+ $date = normalizeDate($doc);
+ if ($date && strtotime($date) >= strtotime($start)) $cf[] = $doc;
+}
+
+echo 'sales_from_start(issue_date_first)=' . count($sf) . PHP_EOL;
+echo 'costs_from_start(issue_date_first)=' . count($cf) . PHP_EOL;
diff --git a/__tmp_diag.php b/__tmp_diag.php
new file mode 100644
index 0000000..39086ff
--- /dev/null
+++ b/__tmp_diag.php
@@ -0,0 +1,54 @@
+= strtotime($start)) $sf[] = $doc;
+}
+
+$cf = [];
+foreach ($costs as $doc) {
+ $date = isset($doc['sell_date']) && $doc['sell_date'] ? $doc['sell_date'] : (isset($doc['issue_date']) ? $doc['issue_date'] : '');
+ if ($date && strtotime(substr($date,0,10)) >= strtotime($start)) $cf[] = $doc;
+}
+
+echo 'sales_all=' . count($sales) . PHP_EOL;
+echo 'costs_all=' . count($costs) . PHP_EOL;
+echo 'sales_from_start=' . count($sf) . PHP_EOL;
+echo 'costs_from_start=' . count($cf) . PHP_EOL;
+
+echo "-- sales_from_start --" . PHP_EOL;
+foreach ($sf as $d) {
+ echo $d['id'] . ' | ' . ($d['number'] ?? '-') . ' | ' . ($d['sell_date'] ?? '-') . ' | ' . ($d['issue_date'] ?? '-') . PHP_EOL;
+}
+
+echo "-- costs_from_start --" . PHP_EOL;
+foreach ($cf as $d) {
+ echo $d['id'] . ' | ' . ($d['number'] ?? '-') . ' | ' . ($d['sell_date'] ?? '-') . ' | ' . ($d['issue_date'] ?? '-') . PHP_EOL;
+}
diff --git a/autoload/Controllers/FinancesController.php b/autoload/Controllers/FinancesController.php
index 6c5c0f1..82ee9d3 100644
--- a/autoload/Controllers/FinancesController.php
+++ b/autoload/Controllers/FinancesController.php
@@ -8,6 +8,11 @@ class FinancesController
return new \Domain\Finances\FinanceRepository();
}
+ private static function importRepo()
+ {
+ return new \Domain\Finances\FakturowniaImportRepository();
+ }
+
private static function requireAuth()
{
global $user;
@@ -53,6 +58,8 @@ class FinancesController
return false;
$repo = self::repo();
+ $importRepo = self::importRepo();
+ $importRepo -> ensureTables();
if ( \S::get( 'tag-clear' ) )
unset( $_SESSION['finance-tag-id'] );
@@ -93,10 +100,121 @@ class FinancesController
'wallet_summary' => $repo -> walletSummary( $group_id ),
'wallet_summary_this_month' => $repo -> walletSummaryThisMonth( $group_id ),
'wallet_income_this_month' => $repo -> walletIncomeThisMonth( $group_id ),
- 'wallet_expenses_this_month' => $repo -> walletExpensesThisMonth( $group_id )
+ 'wallet_expenses_this_month' => $repo -> walletExpensesThisMonth( $group_id ),
+ 'fakturownia_pending_clients' => self::preparePendingRows( $importRepo -> pendingClientMappings() ),
+ 'fakturownia_pending_items' => self::preparePendingRows( $importRepo -> pendingItemMappings() ),
+ 'fakturownia_crm_clients' => $repo -> clientsList(),
+ 'fakturownia_categories' => self::prepareCategoryOptions( $repo -> categoriesFlatList() ),
+ 'fakturownia_last_summary' => self::lastImportSummary( $importRepo )
] );
}
+ private static function preparePendingRows( $rows )
+ {
+ $output = [];
+
+ if ( !is_array( $rows ) )
+ return $output;
+
+ foreach ( $rows as $row )
+ {
+ $payload = [];
+ if ( isset( $row['payload_json'] ) && $row['payload_json'] )
+ {
+ $decoded = json_decode( $row['payload_json'], true );
+ if ( is_array( $decoded ) )
+ $payload = $decoded;
+ }
+
+ $output[] = [
+ 'external_key' => (string)$row['external_key'],
+ 'external_name' => (string)$row['external_name'],
+ 'hits' => (int)$row['hits'],
+ 'last_seen_at' => (string)$row['last_seen_at'],
+ 'payload' => $payload
+ ];
+ }
+
+ return $output;
+ }
+
+ private static function lastImportSummary( $importRepo )
+ {
+ $raw = $importRepo -> getState( 'last_import_summary' );
+ if ( !$raw )
+ return null;
+
+ $decoded = json_decode( $raw, true );
+ return is_array( $decoded ) ? $decoded : null;
+ }
+
+ private static function prepareCategoryOptions( $categories )
+ {
+ $options = [];
+ if ( !is_array( $categories ) || empty( $categories ) )
+ return $options;
+
+ $byId = [];
+ foreach ( $categories as $category )
+ {
+ $id = isset( $category['id'] ) ? (int)$category['id'] : 0;
+ if ( $id <= 0 )
+ continue;
+
+ $byId[ $id ] = $category;
+ }
+
+ foreach ( $categories as $category )
+ {
+ $id = isset( $category['id'] ) ? (int)$category['id'] : 0;
+ if ( $id <= 0 )
+ continue;
+
+ $label = self::buildCategoryPathLabel( $id, $byId );
+ $options[] = [
+ 'id' => $id,
+ 'name' => $label,
+ 'group_id' => isset( $category['group_id'] ) ? (int)$category['group_id'] : 0
+ ];
+ }
+
+ usort( $options, function( $left, $right )
+ {
+ return strcmp( $left['name'], $right['name'] );
+ } );
+
+ return $options;
+ }
+
+ private static function buildCategoryPathLabel( $categoryId, $byId )
+ {
+ $parts = [];
+ $guard = 0;
+ $currentId = (int)$categoryId;
+
+ while ( $currentId > 0 && isset( $byId[ $currentId ] ) )
+ {
+ $category = $byId[ $currentId ];
+ $name = trim( (string)( $category['name'] ?? '' ) );
+ if ( $name !== '' )
+ array_unshift( $parts, $name );
+
+ $parentId = isset( $category['parent_id'] ) ? (int)$category['parent_id'] : 0;
+ if ( $parentId <= 0 || $parentId === $currentId )
+ break;
+
+ $currentId = $parentId;
+ $guard++;
+ if ( $guard > 20 )
+ break;
+ }
+
+ if ( empty( $parts ) )
+ return 'Kategoria #' . (int)$categoryId;
+
+ return implode( ' > ', $parts );
+ }
+
public static function operationEdit()
{
if ( !self::requireAuth() )
@@ -230,4 +348,70 @@ class FinancesController
'date_to' => $date_to
] );
}
+
+ public static function fakturowniaClientMappingSave()
+ {
+ if ( !self::requireAuth() )
+ return false;
+
+ if ( !\S::csrf_verify() )
+ {
+ \S::alert( 'Nieprawidlowy token bezpieczenstwa. Odswiez strone i sproboj ponownie.' );
+ header( 'Location: /finances/main_view/' );
+ exit;
+ }
+
+ $externalKey = trim( (string)\S::get( 'external_key' ) );
+ $externalName = trim( (string)\S::get( 'external_name' ) );
+ $crmClientId = (int)\S::get( 'crm_client_id' );
+ $repo = self::repo();
+
+ if ( $externalKey === '' || $externalName === '' || $crmClientId <= 0 || !$repo -> clientExists( $crmClientId ) )
+ {
+ \S::alert( 'Nie udalo sie zapisac mapowania klienta. Uzupelnij wszystkie pola.' );
+ header( 'Location: /finances/main_view/' );
+ exit;
+ }
+
+ $importRepo = self::importRepo();
+ $importRepo -> ensureTables();
+ $importRepo -> saveClientMapping( $externalKey, $externalName, $crmClientId );
+
+ \S::alert( 'Mapowanie klienta zostalo zapisane.' );
+ header( 'Location: /finances/main_view/' );
+ exit;
+ }
+
+ public static function fakturowniaItemMappingSave()
+ {
+ if ( !self::requireAuth() )
+ return false;
+
+ if ( !\S::csrf_verify() )
+ {
+ \S::alert( 'Nieprawidlowy token bezpieczenstwa. Odswiez strone i sproboj ponownie.' );
+ header( 'Location: /finances/main_view/' );
+ exit;
+ }
+
+ $externalKey = trim( (string)\S::get( 'external_key' ) );
+ $externalName = trim( (string)\S::get( 'external_name' ) );
+ $financeCategoryId = (int)\S::get( 'finance_category_id' );
+ $repo = self::repo();
+
+ if ( $externalKey === '' || $externalName === '' || $financeCategoryId <= 0 || !$repo -> categoryExists( $financeCategoryId ) )
+ {
+ \S::alert( 'Nie udalo sie zapisac mapowania pozycji. Uzupelnij wszystkie pola.' );
+ header( 'Location: /finances/main_view/' );
+ exit;
+ }
+
+ $importRepo = self::importRepo();
+ $importRepo -> ensureTables();
+ $importRepo -> saveItemMapping( $externalKey, $externalName, $financeCategoryId );
+
+ \S::alert( 'Mapowanie pozycji zostalo zapisane.' );
+ header( 'Location: /finances/main_view/' );
+ exit;
+ }
}
diff --git a/autoload/Domain/Finances/FakturowniaApiClient.php b/autoload/Domain/Finances/FakturowniaApiClient.php
new file mode 100644
index 0000000..4d4365e
--- /dev/null
+++ b/autoload/Domain/Finances/FakturowniaApiClient.php
@@ -0,0 +1,162 @@
+ baseUrl = rtrim( (string)$baseUrl, '/' );
+ $this -> apiToken = (string)$apiToken;
+ $this -> pageLimit = max( 1, (int)$pageLimit );
+ $this -> timeout = max( 5, (int)$timeout );
+ }
+
+ public function fetchSalesDocuments( $startDate, $page = 1 )
+ {
+ $query = [
+ 'page' => (int)$page,
+ 'per_page' => $this -> pageLimit
+ ];
+
+ if ( $this -> canUseCurrentMonthPeriod( $startDate ) )
+ $query['period'] = 'this_month';
+
+ return $this -> requestList( '/invoices.json', $query );
+ }
+
+ public function fetchCostDocuments( $startDate, $page = 1 )
+ {
+ $queries = [
+ [
+ 'page' => (int)$page,
+ 'per_page' => $this -> pageLimit,
+ 'income' => 'no'
+ ]
+ ];
+
+ if ( $this -> canUseCurrentMonthPeriod( $startDate ) )
+ $queries[0]['period'] = 'this_month';
+
+ $paths = [ '/costs.json', '/expenses.json', '/invoices.json' ];
+
+ foreach ( $paths as $path )
+ {
+ foreach ( $queries as $query )
+ {
+ $response = $this -> requestList( $path, $query, true );
+ if ( $response['ok'] )
+ return $response['data'];
+ }
+ }
+
+ throw new \RuntimeException( 'Nie udalo sie pobrac faktur kosztowych z API Fakturowni.' );
+ }
+
+ public function fetchInvoiceDetails( $invoiceId )
+ {
+ $invoiceId = (int)$invoiceId;
+ if ( $invoiceId <= 0 )
+ return null;
+
+ $result = $this -> request( '/invoices/' . $invoiceId . '.json', [] );
+ if ( $result['http_code'] >= 400 )
+ return null;
+
+ $data = json_decode( $result['body'], true );
+ return is_array( $data ) ? $data : null;
+ }
+
+ private function requestList( $path, $query, $softFail = false )
+ {
+ $result = $this -> request( $path, $query );
+
+ if ( $result['http_code'] >= 400 )
+ {
+ if ( $softFail )
+ return [ 'ok' => false, 'data' => [] ];
+
+ throw new \RuntimeException( 'Blad API Fakturowni: HTTP ' . $result['http_code'] . ' dla ' . $path );
+ }
+
+ $data = json_decode( $result['body'], true );
+ if ( !is_array( $data ) )
+ {
+ if ( $softFail )
+ return [ 'ok' => false, 'data' => [] ];
+
+ throw new \RuntimeException( 'API Fakturowni zwrocilo niepoprawny JSON.' );
+ }
+
+ $list = $this -> extractList( $data );
+ return $softFail ? [ 'ok' => true, 'data' => $list ] : $list;
+ }
+
+ private function request( $path, $query )
+ {
+ $query['api_token'] = $this -> apiToken;
+ $url = $this -> baseUrl . $path . '?' . http_build_query( $query );
+
+ $ch = curl_init( $url );
+ curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
+ curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $this -> timeout );
+ curl_setopt( $ch, CURLOPT_TIMEOUT, $this -> timeout );
+ curl_setopt( $ch, CURLOPT_HTTPHEADER, [
+ 'Accept: application/json'
+ ] );
+
+ $body = curl_exec( $ch );
+ $httpCode = (int)curl_getinfo( $ch, CURLINFO_HTTP_CODE );
+ $error = curl_error( $ch );
+ curl_close( $ch );
+
+ if ( $body === false )
+ throw new \RuntimeException( 'Blad polaczenia z API Fakturowni: ' . $error );
+
+ return [
+ 'http_code' => $httpCode,
+ 'body' => $body
+ ];
+ }
+
+ private function extractList( $data )
+ {
+ if ( $this -> isList( $data ) )
+ return $data;
+
+ $keys = [ 'invoices', 'costs', 'expenses', 'data' ];
+ foreach ( $keys as $key )
+ {
+ if ( isset( $data[ $key ] ) && is_array( $data[ $key ] ) )
+ {
+ if ( $this -> isList( $data[ $key ] ) )
+ return $data[ $key ];
+ }
+ }
+
+ return [];
+ }
+
+ private function isList( $value )
+ {
+ if ( !is_array( $value ) )
+ return false;
+
+ if ( $value === [] )
+ return true;
+
+ return array_keys( $value ) === range( 0, count( $value ) - 1 );
+ }
+
+ private function canUseCurrentMonthPeriod( $startDate )
+ {
+ if ( !is_string( $startDate ) || !preg_match( '/^\d{4}-\d{2}-\d{2}$/', $startDate ) )
+ return false;
+
+ return $startDate === date( 'Y-m-01' );
+ }
+}
diff --git a/autoload/Domain/Finances/FakturowniaImportRepository.php b/autoload/Domain/Finances/FakturowniaImportRepository.php
new file mode 100644
index 0000000..6553f26
--- /dev/null
+++ b/autoload/Domain/Finances/FakturowniaImportRepository.php
@@ -0,0 +1,318 @@
+ mdb = $mdb;
+ else
+ {
+ global $mdb;
+ $this -> mdb = $mdb;
+ }
+ }
+
+ public function ensureTables()
+ {
+ if ( $this -> tablesReady )
+ return;
+
+ $this -> mdb -> query(
+ 'CREATE TABLE IF NOT EXISTS `fakturownia_client_mappings` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `external_client_key` VARCHAR(191) NOT NULL,
+ `external_name` VARCHAR(255) NOT NULL,
+ `crm_client_id` INT UNSIGNED NOT NULL,
+ `created_at` DATETIME NOT NULL,
+ `updated_at` DATETIME NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uniq_external_client_key` (`external_client_key`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8'
+ );
+
+ $this -> mdb -> query(
+ 'CREATE TABLE IF NOT EXISTS `fakturownia_item_mappings` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `external_item_key` VARCHAR(191) NOT NULL,
+ `external_name` VARCHAR(255) NOT NULL,
+ `finance_category_id` INT UNSIGNED NOT NULL,
+ `created_at` DATETIME NOT NULL,
+ `updated_at` DATETIME NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uniq_external_item_key` (`external_item_key`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8'
+ );
+
+ $this -> mdb -> query(
+ 'CREATE TABLE IF NOT EXISTS `fakturownia_imported_documents` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `external_document_key` VARCHAR(191) NOT NULL,
+ `document_type` VARCHAR(32) NOT NULL,
+ `external_id` VARCHAR(64) NOT NULL,
+ `source_date` DATE NULL,
+ `amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
+ `finance_operation_ids` TEXT NULL,
+ `meta_json` LONGTEXT NULL,
+ `imported_at` DATETIME NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uniq_external_document_key` (`external_document_key`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8'
+ );
+
+ $this -> mdb -> query(
+ 'CREATE TABLE IF NOT EXISTS `fakturownia_unmapped_queue` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `queue_type` VARCHAR(32) NOT NULL,
+ `external_key` VARCHAR(191) NOT NULL,
+ `external_name` VARCHAR(255) NOT NULL,
+ `payload_json` LONGTEXT NULL,
+ `hits` INT UNSIGNED NOT NULL DEFAULT 1,
+ `resolved` TINYINT(1) NOT NULL DEFAULT 0,
+ `first_seen_at` DATETIME NOT NULL,
+ `last_seen_at` DATETIME NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uniq_type_key` (`queue_type`, `external_key`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8'
+ );
+
+ $this -> mdb -> query(
+ 'CREATE TABLE IF NOT EXISTS `fakturownia_import_state` (
+ `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ `state_key` VARCHAR(191) NOT NULL,
+ `state_value` LONGTEXT NULL,
+ `updated_at` DATETIME NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `uniq_state_key` (`state_key`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8'
+ );
+
+ $this -> tablesReady = true;
+ }
+
+ public function getClientMapping( $externalClientKey )
+ {
+ $this -> ensureTables();
+ return $this -> mdb -> get( 'fakturownia_client_mappings', '*', [
+ 'external_client_key' => $externalClientKey
+ ] );
+ }
+
+ public function saveClientMapping( $externalClientKey, $externalName, $crmClientId )
+ {
+ $this -> ensureTables();
+
+ $current = $this -> getClientMapping( $externalClientKey );
+ $now = date( 'Y-m-d H:i:s' );
+
+ if ( $current )
+ {
+ $this -> mdb -> update( 'fakturownia_client_mappings', [
+ 'external_name' => $externalName,
+ 'crm_client_id' => (int)$crmClientId,
+ 'updated_at' => $now
+ ], [ 'id' => (int)$current['id'] ] );
+ }
+ else
+ {
+ $this -> mdb -> insert( 'fakturownia_client_mappings', [
+ 'external_client_key' => $externalClientKey,
+ 'external_name' => $externalName,
+ 'crm_client_id' => (int)$crmClientId,
+ 'created_at' => $now,
+ 'updated_at' => $now
+ ] );
+ }
+
+ $this -> resolveQueueItem( 'client', $externalClientKey );
+ }
+
+ public function getItemMapping( $externalItemKey )
+ {
+ $this -> ensureTables();
+ return $this -> mdb -> get( 'fakturownia_item_mappings', '*', [
+ 'external_item_key' => $externalItemKey
+ ] );
+ }
+
+ public function saveItemMapping( $externalItemKey, $externalName, $financeCategoryId )
+ {
+ $this -> ensureTables();
+
+ $current = $this -> getItemMapping( $externalItemKey );
+ $now = date( 'Y-m-d H:i:s' );
+
+ if ( $current )
+ {
+ $this -> mdb -> update( 'fakturownia_item_mappings', [
+ 'external_name' => $externalName,
+ 'finance_category_id' => (int)$financeCategoryId,
+ 'updated_at' => $now
+ ], [ 'id' => (int)$current['id'] ] );
+ }
+ else
+ {
+ $this -> mdb -> insert( 'fakturownia_item_mappings', [
+ 'external_item_key' => $externalItemKey,
+ 'external_name' => $externalName,
+ 'finance_category_id' => (int)$financeCategoryId,
+ 'created_at' => $now,
+ 'updated_at' => $now
+ ] );
+ }
+
+ $this -> resolveQueueItem( 'item', $externalItemKey );
+ }
+
+ public function isDocumentImported( $externalDocumentKey )
+ {
+ $this -> ensureTables();
+ return (bool)$this -> mdb -> has( 'fakturownia_imported_documents', [
+ 'external_document_key' => $externalDocumentKey
+ ] );
+ }
+
+ public function markDocumentImported( $externalDocumentKey, $documentType, $externalId, $sourceDate, $amount, $operationIds, $meta )
+ {
+ $this -> ensureTables();
+
+ $now = date( 'Y-m-d H:i:s' );
+ $data = [
+ 'external_document_key' => $externalDocumentKey,
+ 'document_type' => $documentType,
+ 'external_id' => (string)$externalId,
+ 'source_date' => $sourceDate,
+ 'amount' => (float)$amount,
+ 'finance_operation_ids' => implode( ',', $operationIds ),
+ 'meta_json' => json_encode( $meta, JSON_UNESCAPED_UNICODE ),
+ 'imported_at' => $now
+ ];
+
+ $existing = $this -> mdb -> get( 'fakturownia_imported_documents', 'id', [
+ 'external_document_key' => $externalDocumentKey
+ ] );
+
+ if ( $existing )
+ {
+ $this -> mdb -> update( 'fakturownia_imported_documents', $data, [
+ 'id' => (int)$existing
+ ] );
+ return;
+ }
+
+ $this -> mdb -> insert( 'fakturownia_imported_documents', $data );
+ }
+
+ public function queueUnmapped( $queueType, $externalKey, $externalName, $payload )
+ {
+ $this -> ensureTables();
+
+ $existing = $this -> mdb -> get( 'fakturownia_unmapped_queue', '*', [
+ 'AND' => [
+ 'queue_type' => $queueType,
+ 'external_key' => $externalKey
+ ]
+ ] );
+
+ $now = date( 'Y-m-d H:i:s' );
+ $payloadJson = json_encode( $payload, JSON_UNESCAPED_UNICODE );
+
+ if ( $existing )
+ {
+ $this -> mdb -> update( 'fakturownia_unmapped_queue', [
+ 'external_name' => $externalName,
+ 'payload_json' => $payloadJson,
+ 'hits[+]' => 1,
+ 'resolved' => 0,
+ 'last_seen_at' => $now
+ ], [ 'id' => (int)$existing['id'] ] );
+ return;
+ }
+
+ $this -> mdb -> insert( 'fakturownia_unmapped_queue', [
+ 'queue_type' => $queueType,
+ 'external_key' => $externalKey,
+ 'external_name' => $externalName,
+ 'payload_json' => $payloadJson,
+ 'hits' => 1,
+ 'resolved' => 0,
+ 'first_seen_at' => $now,
+ 'last_seen_at' => $now
+ ] );
+ }
+
+ public function pendingClientMappings()
+ {
+ $this -> ensureTables();
+ return $this -> mdb -> select( 'fakturownia_unmapped_queue', '*', [
+ 'AND' => [
+ 'queue_type' => 'client',
+ 'resolved' => 0
+ ],
+ 'ORDER' => [ 'last_seen_at' => 'DESC' ]
+ ] );
+ }
+
+ public function pendingItemMappings()
+ {
+ $this -> ensureTables();
+ return $this -> mdb -> select( 'fakturownia_unmapped_queue', '*', [
+ 'AND' => [
+ 'queue_type' => 'item',
+ 'resolved' => 0,
+ 'external_key[!]' => 'name:faktura bez pozycji'
+ ],
+ 'ORDER' => [ 'last_seen_at' => 'DESC' ]
+ ] );
+ }
+
+ public function saveState( $stateKey, $stateValue )
+ {
+ $this -> ensureTables();
+
+ $existing = $this -> mdb -> get( 'fakturownia_import_state', '*', [
+ 'state_key' => $stateKey
+ ] );
+ $now = date( 'Y-m-d H:i:s' );
+
+ if ( $existing )
+ {
+ $this -> mdb -> update( 'fakturownia_import_state', [
+ 'state_value' => $stateValue,
+ 'updated_at' => $now
+ ], [ 'id' => (int)$existing['id'] ] );
+ return;
+ }
+
+ $this -> mdb -> insert( 'fakturownia_import_state', [
+ 'state_key' => $stateKey,
+ 'state_value' => $stateValue,
+ 'updated_at' => $now
+ ] );
+ }
+
+ public function getState( $stateKey )
+ {
+ $this -> ensureTables();
+ return $this -> mdb -> get( 'fakturownia_import_state', 'state_value', [
+ 'state_key' => $stateKey
+ ] );
+ }
+
+ private function resolveQueueItem( $queueType, $externalKey )
+ {
+ $this -> mdb -> update( 'fakturownia_unmapped_queue', [
+ 'resolved' => 1,
+ 'last_seen_at' => date( 'Y-m-d H:i:s' )
+ ], [
+ 'AND' => [
+ 'queue_type' => $queueType,
+ 'external_key' => $externalKey
+ ]
+ ] );
+ }
+}
diff --git a/autoload/Domain/Finances/FakturowniaInvoiceImporter.php b/autoload/Domain/Finances/FakturowniaInvoiceImporter.php
new file mode 100644
index 0000000..fe79ba9
--- /dev/null
+++ b/autoload/Domain/Finances/FakturowniaInvoiceImporter.php
@@ -0,0 +1,461 @@
+ mdb = $mdb;
+ else
+ {
+ global $mdb;
+ $this -> mdb = $mdb;
+ }
+
+ $this -> repo = new FakturowniaImportRepository( $this -> mdb );
+ }
+
+ public function import()
+ {
+ $this -> repo -> ensureTables();
+
+ $config = $this -> resolveConfig();
+ if ( !$config['ok'] )
+ return $config;
+
+ $this -> startDate = $config['start_date'];
+ $this -> apiClient = new FakturowniaApiClient(
+ $config['api_url'],
+ $config['token'],
+ $config['page_limit']
+ );
+ $this -> pageLimit = (int)$config['page_limit'];
+
+ $summary = [
+ 'imported' => 0,
+ 'skipped' => 0,
+ 'unmapped' => 0,
+ 'errors' => 0
+ ];
+
+ $summary = $this -> processDocumentType( 'income', $summary );
+ $summary = $this -> processDocumentType( 'cost', $summary );
+
+ $lastSummary = json_encode( [
+ 'at' => date( 'Y-m-d H:i:s' ),
+ 'summary' => $summary
+ ], JSON_UNESCAPED_UNICODE );
+ $this -> repo -> saveState( 'last_import_summary', $lastSummary );
+
+ if ( $summary['imported'] === 0 && $summary['unmapped'] === 0 && $summary['errors'] === 0 )
+ return [ 'status' => 'empty', 'msg' => 'Import Fakturownia: brak nowych dokumentow.' ];
+
+ if ( $summary['errors'] > 0 )
+ return [ 'status' => 'error', 'msg' => $this -> formatMessage( $summary ), 'summary' => $summary ];
+
+ return [ 'status' => 'ok', 'msg' => $this -> formatMessage( $summary ), 'summary' => $summary ];
+ }
+
+ private function processDocumentType( $documentType, $summary )
+ {
+ $page = 1;
+
+ while ( true )
+ {
+ try
+ {
+ if ( $documentType === 'income' )
+ $documents = $this -> apiClient -> fetchSalesDocuments( $this -> startDate, $page );
+ else
+ $documents = $this -> apiClient -> fetchCostDocuments( $this -> startDate, $page );
+ }
+ catch ( \Throwable $e )
+ {
+ $summary['errors']++;
+ break;
+ }
+
+ if ( !is_array( $documents ) || empty( $documents ) )
+ break;
+
+ $hasRelevantDateInPage = false;
+
+ foreach ( $documents as $document )
+ {
+ if ( $this -> isDateRelevantForImport( $document ) )
+ $hasRelevantDateInPage = true;
+
+ $result = $this -> processSingleDocument( $document, $documentType );
+ $summary[ $result ]++;
+ }
+
+ if ( count( $documents ) < $this -> pageLimit )
+ break;
+
+ // API zwraca dokumenty malejaco po czasie. Gdy cala strona jest starsza niz startDate,
+ // kolejne strony tez beda starsze i nie ma sensu pobierac dalej.
+ if ( !$hasRelevantDateInPage )
+ break;
+
+ $page++;
+ if ( $page > 100 )
+ break;
+ }
+
+ return $summary;
+ }
+
+ private function processSingleDocument( $rawDocument, $documentType )
+ {
+ if ( !$this -> matchesDocumentType( $rawDocument, $documentType ) )
+ return 'skipped';
+
+ $document = $this -> normalizeDocument( $rawDocument, $documentType );
+ if ( !$document )
+ return 'skipped';
+
+ if ( $this -> repo -> isDocumentImported( $document['document_key'] ) )
+ return 'skipped';
+
+ if ( strtotime( $document['date'] ) < strtotime( $this -> startDate ) )
+ return 'skipped';
+
+ $clientMap = $this -> repo -> getClientMapping( $document['client_key'] );
+ if ( !$clientMap )
+ {
+ $this -> repo -> queueUnmapped( 'client', $document['client_key'], $document['client_name'], [
+ 'document_id' => $document['external_id'],
+ 'document_number' => $document['number'],
+ 'document_type' => $documentType,
+ 'tax_no' => $document['client_tax_no']
+ ] );
+ return 'unmapped';
+ }
+
+ $resolvedPositions = [];
+ foreach ( $document['positions'] as $position )
+ {
+ $itemMap = $this -> repo -> getItemMapping( $position['item_key'] );
+ if ( !$itemMap )
+ {
+ $this -> repo -> queueUnmapped( 'item', $position['item_key'], $position['name'], [
+ 'document_id' => $document['external_id'],
+ 'document_number' => $document['number'],
+ 'document_type' => $documentType
+ ] );
+ return 'unmapped';
+ }
+
+ $amount = $this -> normalizeAmount( $position['amount'], $documentType );
+ if ( $amount == 0.0 )
+ continue;
+
+ $resolvedPositions[] = [
+ 'category_id' => (int)$itemMap['finance_category_id'],
+ 'amount' => $amount,
+ 'description' => $this -> buildDescription( $document, $position )
+ ];
+ }
+
+ if ( empty( $resolvedPositions ) )
+ return 'skipped';
+
+ $operationIds = [];
+
+ // Cala faktura importuje sie atomowo: albo wszystkie pozycje, albo nic.
+ $this -> mdb -> pdo -> beginTransaction();
+ try
+ {
+ foreach ( $resolvedPositions as $resolvedPosition )
+ {
+ $this -> mdb -> insert( 'finance_operations', [
+ 'date' => $document['date'],
+ 'category_id' => $resolvedPosition['category_id'],
+ 'amount' => $resolvedPosition['amount'],
+ 'description' => $resolvedPosition['description'],
+ 'client_id' => (int)$clientMap['crm_client_id']
+ ] );
+
+ $operationIds[] = (int)$this -> mdb -> id();
+ }
+
+ $this -> repo -> markDocumentImported(
+ $document['document_key'],
+ $documentType,
+ $document['external_id'],
+ $document['date'],
+ $document['total_amount'],
+ $operationIds,
+ [
+ 'number' => $document['number'],
+ 'client_name' => $document['client_name']
+ ]
+ );
+
+ $this -> mdb -> pdo -> commit();
+ }
+ catch ( \Throwable $e )
+ {
+ if ( $this -> mdb -> pdo ->inTransaction() )
+ $this -> mdb -> pdo -> rollBack();
+
+ throw $e;
+ }
+
+ return 'imported';
+ }
+
+ private function matchesDocumentType( $rawDocument, $documentType )
+ {
+ if ( isset( $rawDocument['invoice'] ) && is_array( $rawDocument['invoice'] ) )
+ $rawDocument = $rawDocument['invoice'];
+
+ if ( !is_array( $rawDocument ) )
+ return false;
+
+ if ( !array_key_exists( 'income', $rawDocument ) )
+ return true;
+
+ $incomeFlag = $rawDocument['income'];
+ $isIncome = !in_array( $incomeFlag, [ false, 0, '0', 'false', 'FALSE' ], true );
+
+ if ( $documentType === 'income' )
+ return $isIncome;
+
+ return !$isIncome;
+ }
+
+ private function isDateRelevantForImport( $rawDocument )
+ {
+ if ( isset( $rawDocument['invoice'] ) && is_array( $rawDocument['invoice'] ) )
+ $rawDocument = $rawDocument['invoice'];
+
+ if ( !is_array( $rawDocument ) )
+ return false;
+
+ $date = (string)( $rawDocument['issue_date'] ?? $rawDocument['sell_date'] ?? $rawDocument['created_at'] ?? '' );
+ $date = substr( $date, 0, 10 );
+ if ( !$date )
+ return false;
+
+ return strtotime( $date ) >= strtotime( $this -> startDate );
+ }
+
+ private function normalizeDocument( $rawDocument, $documentType )
+ {
+ if ( isset( $rawDocument['invoice'] ) && is_array( $rawDocument['invoice'] ) )
+ $rawDocument = $rawDocument['invoice'];
+
+ if ( !is_array( $rawDocument ) )
+ return null;
+
+ $externalId = isset( $rawDocument['id'] ) ? (string)$rawDocument['id'] : '';
+ if ( $externalId === '' )
+ return null;
+
+ $number = (string)( $rawDocument['number'] ?? $rawDocument['full_number'] ?? '' );
+ $date = (string)( $rawDocument['issue_date'] ?? $rawDocument['sell_date'] ?? $rawDocument['created_at'] ?? date( 'Y-m-d' ) );
+ $date = substr( $date, 0, 10 );
+
+ if ( $documentType === 'income' )
+ {
+ $clientName = (string)( $rawDocument['buyer_name'] ?? $rawDocument['client_name'] ?? 'Nieznany klient' );
+ $clientTaxNo = (string)( $rawDocument['buyer_tax_no'] ?? $rawDocument['tax_no'] ?? '' );
+ }
+ else
+ {
+ $clientName = (string)( $rawDocument['seller_name'] ?? $rawDocument['client_name'] ?? 'Nieznany kontrahent' );
+ $clientTaxNo = (string)( $rawDocument['seller_tax_no'] ?? $rawDocument['tax_no'] ?? '' );
+ }
+
+ $positions = [];
+ $totalAmount = 0.0;
+
+ $rawPositions = $this -> resolvePositions( $rawDocument );
+ foreach ( $rawPositions as $rawPosition )
+ {
+ if ( !is_array( $rawPosition ) )
+ continue;
+
+ $name = trim( (string)( $rawPosition['name'] ?? '' ) );
+ if ( $name === '' )
+ $name = 'Pozycja';
+
+ $amount = $this -> resolvePositionAmount( $rawPosition );
+ $totalAmount += $amount;
+
+ $positions[] = [
+ 'item_key' => $this -> buildItemKey( $rawPosition, $name ),
+ 'name' => $name,
+ 'amount' => $amount
+ ];
+ }
+
+ if ( empty( $positions ) )
+ {
+ $fallback = (float)( $rawDocument['price_gross'] ?? $rawDocument['price'] ?? 0 );
+ $fallbackName = trim( (string)( $rawDocument['product_cache'] ?? '' ) );
+ if ( $fallbackName === '' )
+ $fallbackName = 'Faktura bez pozycji';
+
+ if ( $fallback != 0.0 )
+ {
+ $positions[] = [
+ 'item_key' => $this -> buildItemKey( [], $fallbackName ),
+ 'name' => $fallbackName,
+ 'amount' => $fallback
+ ];
+ $totalAmount = $fallback;
+ }
+ }
+
+ if ( empty( $positions ) )
+ return null;
+
+ return [
+ 'external_id' => $externalId,
+ 'document_key' => $documentType . ':' . $externalId,
+ 'number' => $number,
+ 'date' => $date,
+ 'client_name' => $clientName,
+ 'client_tax_no' => $clientTaxNo,
+ 'client_key' => $this -> buildClientKey( $rawDocument, $clientName, $clientTaxNo ),
+ 'positions' => $positions,
+ 'total_amount' => $this -> normalizeAmount( $totalAmount, $documentType )
+ ];
+ }
+
+ private function resolvePositions( $rawDocument )
+ {
+ if ( isset( $rawDocument['positions'] ) && is_array( $rawDocument['positions'] ) && !empty( $rawDocument['positions'] ) )
+ return $rawDocument['positions'];
+
+ $invoiceId = isset( $rawDocument['id'] ) ? (int)$rawDocument['id'] : 0;
+ if ( $invoiceId <= 0 )
+ return [];
+
+ $details = $this -> apiClient -> fetchInvoiceDetails( $invoiceId );
+ if ( is_array( $details ) && isset( $details['positions'] ) && is_array( $details['positions'] ) )
+ return $details['positions'];
+
+ return [];
+ }
+
+ private function resolvePositionAmount( $position )
+ {
+ $quantity = (float)( $position['quantity'] ?? 1 );
+ if ( $quantity <= 0 )
+ $quantity = 1;
+
+ $totalNet = (float)( $position['total_price_net'] ?? 0 );
+ if ( $totalNet != 0.0 )
+ return $totalNet;
+
+ $unitNet = (float)( $position['price'] ?? $position['price_net'] ?? 0 );
+ if ( $unitNet != 0.0 )
+ return $unitNet * $quantity;
+
+ // Fallback dla pozycji, ktore nie maja netto w payloadzie.
+ $totalGross = (float)( $position['total_price_gross'] ?? 0 );
+ if ( $totalGross != 0.0 )
+ return $totalGross;
+
+ $unitGross = (float)( $position['price_gross'] ?? 0 );
+ if ( $unitGross != 0.0 )
+ return $unitGross * $quantity;
+
+ return 0.0;
+ }
+
+ private function buildClientKey( $rawDocument, $clientName, $clientTaxNo )
+ {
+ if ( isset( $rawDocument['client_id'] ) && (string)$rawDocument['client_id'] !== '' )
+ return 'id:' . (string)$rawDocument['client_id'];
+
+ if ( $clientTaxNo !== '' )
+ return 'tax:' . preg_replace( '/\s+/', '', $clientTaxNo );
+
+ return 'name:' . $this -> normalizeKeyValue( $clientName );
+ }
+
+ private function buildItemKey( $rawPosition, $name )
+ {
+ if ( isset( $rawPosition['product_id'] ) && (string)$rawPosition['product_id'] !== '' )
+ return 'product:' . (string)$rawPosition['product_id'];
+
+ return 'name:' . $this -> normalizeKeyValue( $name );
+ }
+
+ private function normalizeKeyValue( $value )
+ {
+ $value = trim( (string)$value );
+ if ( function_exists( 'mb_strtolower' ) )
+ return mb_strtolower( $value, 'UTF-8' );
+
+ return strtolower( $value );
+ }
+
+ private function normalizeAmount( $amount, $documentType )
+ {
+ $amount = (float)$amount;
+ if ( $documentType === 'cost' )
+ return abs( $amount ) * -1;
+
+ return abs( $amount );
+ }
+
+ private function buildDescription( $document, $position )
+ {
+ $parts = [
+ 'Fakturownia'
+ ];
+
+ if ( $document['number'] !== '' )
+ $parts[] = 'FV: ' . $document['number'];
+
+ $parts[] = $position['name'];
+ $parts[] = $document['client_name'];
+
+ return implode( ' | ', $parts );
+ }
+
+ private function resolveConfig()
+ {
+ $domain = trim( (string)\Env::get( 'FAKTUROWNIA_API_DOMAIN', '' ) );
+ $token = trim( (string)\Env::get( 'FAKTUROWNIA_API_TOKEN', '' ) );
+ $startDate = trim( (string)\Env::get( 'FAKTUROWNIA_START_DATE', '' ) );
+ $pageLimit = (int)\Env::get( 'FAKTUROWNIA_PAGE_LIMIT', 100 );
+
+ if ( $domain === '' || $token === '' || $startDate === '' )
+ return [ 'status' => 'error', 'ok' => false, 'msg' => 'Import Fakturownia: brak konfiguracji w .env.' ];
+
+ if ( !preg_match( '/^\d{4}-\d{2}-\d{2}$/', $startDate ) )
+ return [ 'status' => 'error', 'ok' => false, 'msg' => 'Import Fakturownia: nieprawidlowa data FAKTUROWNIA_START_DATE.' ];
+
+ if ( strpos( $domain, 'http://' ) !== 0 && strpos( $domain, 'https://' ) !== 0 )
+ $domain = 'https://' . $domain;
+
+ return [
+ 'ok' => true,
+ 'api_url' => rtrim( $domain, '/' ),
+ 'token' => $token,
+ 'start_date' => $startDate,
+ 'page_limit' => $pageLimit > 0 ? $pageLimit : 100
+ ];
+ }
+
+ private function formatMessage( $summary )
+ {
+ return 'Import Fakturownia: zaimportowano ' . (int)$summary['imported']
+ . ', pominieto ' . (int)$summary['skipped']
+ . ', brak mapowan ' . (int)$summary['unmapped']
+ . ', bledy ' . (int)$summary['errors'] . '.';
+ }
+}
diff --git a/autoload/Domain/Finances/FinanceRepository.php b/autoload/Domain/Finances/FinanceRepository.php
index 7d7966e..3566bc5 100644
--- a/autoload/Domain/Finances/FinanceRepository.php
+++ b/autoload/Domain/Finances/FinanceRepository.php
@@ -55,6 +55,23 @@ class FinanceRepository
return $this -> mdb -> select( 'crm_client', [ 'id', 'firm' ], [ 'ORDER' => [ 'firm' => 'ASC' ] ] );
}
+ public function categoriesFlatList()
+ {
+ return $this -> mdb -> select( 'finance_categories', [ 'id', 'name', 'group_id', 'parent_id' ], [
+ 'ORDER' => [ 'name' => 'ASC' ]
+ ] );
+ }
+
+ public function clientExists( $clientId )
+ {
+ return (bool)$this -> mdb -> has( 'crm_client', [ 'id' => (int)$clientId ] );
+ }
+
+ public function categoryExists( $categoryId )
+ {
+ return (bool)$this -> mdb -> has( 'finance_categories', [ 'id' => (int)$categoryId ] );
+ }
+
public function clientsWithRevenue( $date_from, $date_to, $group_id )
{
return $this -> mdb -> query(
diff --git a/autoload/class.Cron.php b/autoload/class.Cron.php
index 4758384..2225c50 100644
--- a/autoload/class.Cron.php
+++ b/autoload/class.Cron.php
@@ -2,6 +2,22 @@
class Cron
{
+ public static function import_finances_from_fakturownia()
+ {
+ try
+ {
+ $importer = new \Domain\Finances\FakturowniaInvoiceImporter();
+ return $importer -> import();
+ }
+ catch ( \Throwable $e )
+ {
+ return [
+ 'status' => 'error',
+ 'msg' => 'Import Fakturownia: ' . $e -> getMessage()
+ ];
+ }
+ }
+
public static function recursive_tasks()
{
global $mdb;
diff --git a/autoload/class.Env.php b/autoload/class.Env.php
new file mode 100644
index 0000000..69737ee
--- /dev/null
+++ b/autoload/class.Env.php
@@ -0,0 +1,64 @@
+= 2 )
+ {
+ $first = $value[0];
+ $last = $value[strlen( $value ) - 1];
+ if ( ( $first === '"' && $last === '"' ) || ( $first === "'" && $last === "'" ) )
+ $value = substr( $value, 1, -1 );
+ }
+
+ self::$values[ $key ] = $value;
+ $_ENV[ $key ] = $value;
+ putenv( $key . '=' . $value );
+ }
+ }
+
+ public static function get( $key, $default = null )
+ {
+ self::load();
+
+ $value = getenv( $key );
+ if ( $value !== false )
+ return $value;
+
+ if ( isset( self::$values[ $key ] ) )
+ return self::$values[ $key ];
+
+ return $default;
+ }
+}
diff --git a/cron.php b/cron.php
index 9f09c5d..4d6a32d 100644
--- a/cron.php
+++ b/cron.php
@@ -1,4 +1,4 @@
- dispense( $type );
} );
+/* diagnostyka: wymuszenie pojedynczego joba cron */
+if ( \S::get( 'job' ) === 'fakturownia' )
+{
+ $response = \Cron::import_finances_from_fakturownia();
+ echo json_encode( $response );
+ exit;
+}
+
+/* import faktur z Fakturowni */
+$response = \Cron::import_finances_from_fakturownia();
+if ( $response['status'] == 'ok' )
+{
+ echo json_encode( $response );
+ exit;
+}
+if ( $response['status'] == 'error' )
+{
+ echo json_encode( $response );
+ exit;
+}
+
/* import zadan z email */
$response = \Cron::import_tasks_from_email();
if ( $response['status'] == 'ok' )
@@ -66,10 +88,9 @@ if ( $response['status'] == 'error' )
exit;
}
-
if ( date( 'G' ) > 6 )
{
- /* wysyłanie przypomnnień do zadań */
+ /* wysylanie przypomnien do zadan */
$response = \Cron::tasks_emails();
if ( $response['status'] == 'ok' )
{
@@ -78,7 +99,7 @@ if ( date( 'G' ) > 6 )
}
}
-/* dodawanie zadań rekursywnych */
+/* dodawanie zadan rekursywnych */
$response = \Cron::recursive_tasks();
if ( $response['status'] == 'ok' )
{
diff --git a/layout/style.css b/layout/style.css
index 2244b99..52a4e9b 100644
--- a/layout/style.css
+++ b/layout/style.css
@@ -1 +1 @@
-.default-btn,.task_popup .task_details .content .right .time a:not(.time_worked_toggle),.task_popup .task_details .content .right .time a.time_worked_toggle{display:flex;align-items:center;justify-content:center;height:40px;border-radius:6px;padding:0 15px;transition:all .3s ease}.default-btn:hover,.task_popup .task_details .content .right .time a:hover:not(.time_worked_toggle),.task_popup .task_details .content .right .time a.time_worked_toggle:hover{text-decoration:none}.animate{animation:mymove 3s infinite}.text-right{text-align:right}.nowrap{white-space:nowrap}table{border-collapse:collapse;font-size:13px}small{font-size:.75em}@keyframes mymove{50%{opacity:.33}}@keyframes gradient-animation{0%{background-position:15% 0%}50%{background-position:85% 100%}100%{background-position:15% 0%}}@keyframes frame-enter{0%{clip-path:polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) calc(100% - 3px), 3px calc(100% - 3px), 3px 100%, 100% 100%, 100% 0%, 0% 0%)}25%{clip-path:polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) calc(100% - 3px), calc(100% - 3px) calc(100% - 3px), calc(100% - 3px) 100%, 100% 100%, 100% 0%, 0% 0%)}50%{clip-path:polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, 100% 0%, 0% 0%)}75%{-webkit-clip-path:polygon(0% 100%, 3px 100%, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 0%, 0% 0%)}100%{-webkit-clip-path:polygon(0% 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 0% 100%)}}*{box-sizing:border-box}body{font-family:"Open Sans",sans-serif;margin:0;padding:0;font-size:15px;color:#4e5e6a}.btn{padding:9px 25px;transition:all .3s ease;color:#fff;border:0;border-radius:6px;cursor:pointer;display:inline-flex;text-decoration:none;gap:5px;justify-content:center;align-items:center}.btn.btn_small,.btn.btn-xs,.btn.btn-sm{padding:5px 7px;font-size:13px}.btn.btn_small i,.btn.btn-xs i,.btn.btn-sm i{font-size:12px}.btn.btn-success{background:#099885}.btn.btn-success:hover{background:#4a9c3b}.btn.btn-primary{background:#6690f4}.btn.btn-primary:hover{background:#3164db}.btn.btn-danger{background:#cc563d}.btn.btn-danger:hover{background:#b30000}.hide{display:none}.form-error{color:#cc563d;font-size:13px}.input-group{margin-bottom:10px}.form-field{margin-bottom:15px}.form-field label{display:block;font-size:13px;font-weight:600;margin-bottom:4px;color:#4e5e6a}.password-wrap{position:relative}.password-wrap .form-control{padding-right:40px}.password-wrap .password-eye{position:absolute;right:10px;top:50%;transform:translateY(-50%);color:#999;text-decoration:none;z-index:2}.password-wrap .password-eye:hover{color:#333}input[type=checkbox]{border:1px solid #cdcdcd}.form-control{border:1px solid #cdcdcd;border-radius:6px;height:35px;width:100%;padding:5px;font-family:"Open Sans",sans-serif}.form-control option{padding:5px}.form-control:focus{border:1px solid #6690f4;outline:none}.unlogged{background:#eef1f9;display:flex;align-items:center;justify-content:center;height:100vh}.unlogged .box-login{background:#fff;padding:25px;border-radius:6px;width:400px}.unlogged .box-login .title{text-align:center;padding:10px 10px 25px;border-bottom:1px solid #cdcdcd;font-size:20px;margin-bottom:25px}.sidebar{position:fixed;top:0;left:0;width:220px;height:100vh;background:#1e2a3a;display:flex;flex-direction:column;z-index:1000;transition:width .3s ease;overflow:hidden}.sidebar.collapsed{width:60px}.sidebar.collapsed .sidebar-header .sidebar-logo span,.sidebar.collapsed .sidebar-nav ul li a span,.sidebar.collapsed .sidebar-footer span,.sidebar.collapsed .sidebar-footer .sidebar-user span{display:none}.sidebar.collapsed .sidebar-header .sidebar-logo{font-size:0}.sidebar.collapsed .sidebar-header .sidebar-logo::first-letter{font-size:16px}.sidebar.collapsed .sidebar-nav ul li a{justify-content:center;padding:10px}.sidebar.collapsed .sidebar-nav ul li a i{margin-right:0}.sidebar.collapsed .sidebar-nav ul li.has-submenu .submenu-arrow{display:none}.sidebar.collapsed .sidebar-nav ul li.has-submenu .sidebar-submenu{display:none}.sidebar.collapsed .sidebar-footer .sidebar-footer-link,.sidebar.collapsed .sidebar-footer .sidebar-user{justify-content:center;padding:8px 10px}.sidebar.collapsed .sidebar-footer .sidebar-footer-link i,.sidebar.collapsed .sidebar-footer .sidebar-user i{margin-right:0}.sidebar .sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:15px;border-bottom:1px solid hsla(0,0%,100%,.1)}.sidebar .sidebar-header .sidebar-logo{color:#6690f4;text-decoration:none;font-size:16px;white-space:nowrap}.sidebar .sidebar-header .sidebar-logo span{font-weight:700}.sidebar .sidebar-header .sidebar-toggle{cursor:pointer;color:#c2c7d0;font-size:16px;transition:color .2s ease}.sidebar .sidebar-header .sidebar-toggle:hover{color:#fff}.sidebar .sidebar-nav{flex:1;overflow-y:auto;padding:10px 0}.sidebar .sidebar-nav ul{list-style:none;margin:0;padding:0}.sidebar .sidebar-nav ul li a{display:flex;align-items:center;padding:10px 15px;color:#c2c7d0;text-decoration:none;font-size:14px;transition:all .2s ease;white-space:nowrap}.sidebar .sidebar-nav ul li a i{width:20px;text-align:center;margin-right:10px;font-size:15px}.sidebar .sidebar-nav ul li a:hover{background:hsla(0,0%,100%,.08);color:#fff}.sidebar .sidebar-nav ul li.active a{background:hsla(0,0%,100%,.08);color:#fff;font-weight:600}.sidebar .sidebar-nav ul li.has-submenu>a .submenu-arrow{margin-left:auto;font-size:12px;transition:transform .2s ease;width:auto}.sidebar .sidebar-nav ul li.has-submenu.open>a .submenu-arrow{transform:rotate(180deg)}.sidebar .sidebar-nav ul li.has-submenu .sidebar-submenu{max-height:0;overflow:hidden;transition:max-height .25s ease;background:rgba(0,0,0,.15)}.sidebar .sidebar-nav ul li.has-submenu .sidebar-submenu li a{padding:8px 15px 8px 45px;font-size:13px}.sidebar .sidebar-nav ul li.has-submenu .sidebar-submenu li a i{font-size:13px;width:16px}.sidebar .sidebar-nav ul li.has-submenu.open .sidebar-submenu{max-height:200px}.sidebar .sidebar-footer{border-top:1px solid hsla(0,0%,100%,.1);padding:10px 0}.sidebar .sidebar-footer .sidebar-user{display:flex;align-items:center;padding:8px 15px;color:#c2c7d0;font-size:13px;white-space:nowrap;overflow:hidden}.sidebar .sidebar-footer .sidebar-user i{margin-right:10px;color:#6690f4}.sidebar .sidebar-footer .sidebar-footer-link{display:flex;align-items:center;padding:8px 15px;color:#c2c7d0;text-decoration:none;font-size:13px;transition:all .2s ease;white-space:nowrap}.sidebar .sidebar-footer .sidebar-footer-link i{width:20px;text-align:center;margin-right:10px}.sidebar .sidebar-footer .sidebar-footer-link:hover{background:hsla(0,0%,100%,.08);color:#fff}.sidebar .sidebar-footer .sidebar-footer-link.logout{color:#cc563d}.sidebar .sidebar-footer .sidebar-footer-link.logout:hover{color:#e07a66}.content-wrapper{margin-left:220px;min-height:100vh;transition:margin-left .3s ease}.content-wrapper.expanded{margin-left:60px}.top-bar{background:#fff;border-bottom:1px solid #e8e8e8;padding:10px 20px;display:flex;align-items:center}.top-bar .top-bar-left{display:flex;align-items:center;gap:15px}.top-bar .top-bar-left i{cursor:pointer;font-size:18px;color:#4e5e6a}.top-bar .top-bar-left i:hover{color:#000}.main{padding:25px;background:#d9dee2;min-height:calc(100vh - 45px)}.tasks_container{display:grid;grid-template-columns:repeat(5, 1fr);gap:20px}.tasks_container .column{width:100%}.tasks_container .column h2{display:flex;padding:10px;background:#fff;margin-bottom:10px;font-size:15px;font-weight:300;border-radius:3px 3px 0 0;justify-content:space-between;align-items:center}.tasks_container .column h2 i{cursor:pointer}.tasks_container .column.tasks_suspended h2{border-bottom:5px solid #cc563d}.tasks_container .column.tasks_fvat h2{border-bottom:5px solid #a900fc}.tasks_container .column.tasks_new h2{border-bottom:5px solid #ccc}.tasks_container .column.tasks_bulk h2{border-bottom:5px solid #ff8c00}.tasks_container .column.tasks_to_do h2{border-bottom:5px solid #2aaf47}.tasks_container .column.tasks_to_review h2{border-bottom:5px solid #2535c9}.tasks_container .column.tasks_closed h2{border-bottom:5px solid #000}.tasks_container .column ul{list-style-type:none;margin:0;padding:0}.tasks_container .column ul .task{margin-bottom:5px;background:#fff;padding:10px;border-radius:0;display:flex;position:relative;border-radius:6px;flex-wrap:wrap}.tasks_container .column ul .task.notopened{border:2px solid #cc563d}.tasks_container .column ul .task .top{display:flex;justify-content:space-between;margin-bottom:5px;width:100%}.tasks_container .column ul .task .top ._users{display:flex;gap:5px;flex-wrap:wrap}.tasks_container .column ul .task .top ._users .user{display:flex;width:25px;height:25px;border-radius:6px;justify-content:center;align-items:center;color:#fff;font-size:12px}.tasks_container .column ul .task .top ._timer{display:flex;gap:5px}.tasks_container .column ul .task .top ._timer .recursively{color:#fff;background:#405189;border-radius:3px;cursor:pointer;margin-bottom:5px;width:25px;height:25px;text-align:center;display:block}.tasks_container .column ul .task .top ._timer .recursively i{font-size:12px}.tasks_container .column ul .task .top ._timer .task_start{display:block;background:#099885;color:#fff;border-radius:6px;cursor:pointer;margin-bottom:5px;width:25px;height:25px;text-align:center}.tasks_container .column ul .task .top ._timer .task_start.hidden{display:none}.tasks_container .column ul .task .top ._timer .task_start i{font-size:12px}.tasks_container .column ul .task .top ._timer .task_end{background:#cc563d;display:block;color:#fff;border-radius:6px;cursor:pointer;margin-bottom:5px;width:25px;height:25px;text-align:center}.tasks_container .column ul .task .top ._timer .task_end.hidden{display:none}.tasks_container .column ul .task .top ._timer .task_end i{font-size:12px}.tasks_container .column ul .task .middle{width:100%}.tasks_container .column ul .task .name{font-size:14px;color:#333;text-decoration:none;display:block;margin-bottom:5px}.tasks_container .column ul .task .bottom{display:flex;justify-content:space-between}.tasks_container .column ul .task .client_info,.tasks_container .column ul .task .current_status{font-size:12px;font-weight:400}.tasks_container .column ul .task .client_info strong,.tasks_container .column ul .task .current_status strong{font-weight:600}.tasks_container .column ul .task .current_status{position:relative;cursor:pointer}.tasks_container .column ul .task .current_status .status_change{position:absolute;left:0;top:20px;background:#fff;padding:15px;border:1px solid #dfdfdf;border-radius:3px;cursor:pointer;box-shadow:0 0 15px rgba(0,0,0,.1);z-index:99;display:none}.tasks_container .column ul .task .current_status .status_change select{width:250px;padding:10px;border:1px solid #cdcdcd;border-radius:3px}.tasks_container .column ul .task .current_status .status_change select option{font-size:15px;padding:3px}.tasks_container .column ul .task .dates{margin-bottom:5px;display:flex;justify-content:space-between;font-size:12px}.tasks_container .column ul .task .dates .danger{color:#cc563d;font-weight:600}.tasks_container .column ul .task .dates .warning{color:#ff8c00}.tasks_container .column ul .task .dates i{font-size:12px;color:#c9ced4;margin-right:5px}.block-header{margin-bottom:20px}.block-header h2{font-size:20px;font-weight:400;color:#4e5e6a;margin:0;padding-bottom:12px;border-bottom:2px solid #e2e6ec}.block-header h2 strong{font-weight:700}.filters-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:24px;padding:12px 16px;background:#f5f7fa;border-radius:8px;border:1px solid #e2e6ec}.filters-bar select,.filters-bar input[type=text],.filters-bar input[type=date],.filters-bar input[type=number]{height:36px;min-width:170px;padding:0 10px;border:1px solid #d0d5dd;border-radius:6px;background:#fff;font-size:13px;color:#4e5e6a;font-family:"Open Sans",sans-serif;transition:border-color .2s}.filters-bar select:focus,.filters-bar input[type=text]:focus,.filters-bar input[type=date]:focus,.filters-bar input[type=number]:focus{border-color:#6690f4;outline:none}.filters-bar .btn{height:36px;display:inline-flex;align-items:center;gap:5px;padding:0 14px;border-radius:6px;font-size:13px;font-weight:500;border:none;cursor:pointer;transition:background .2s,box-shadow .2s;text-decoration:none;color:#fff}.filters-bar .btn.btn-primary{background:#6690f4}.filters-bar .btn.btn-primary:hover{background:#4a74d4}.filters-bar .btn.btn-success{background:#099885}.filters-bar .btn.btn-success:hover{background:#077a6b}.section-title{font-size:14px;font-weight:600;color:#4e5e6a;margin:28px 0 12px;padding-bottom:8px;border-bottom:1px solid #e2e6ec}.action_menu{display:flex;margin-bottom:25px;gap:20px}.action_menu .btn{display:inline-flex;padding:7px 15px;color:#fff;text-decoration:none;align-items:center;justify-content:center;gap:5px}.action_menu .btn.btn_add{background:#099885}.action_menu .btn.btn_add:hover{background:#4a9c3b}.action_menu .btn.btn_cancel{background:#cc563d}.action_menu .btn.btn_cancel:hover{background:#b30000}.action_menu .btn.disabled{opacity:.5}.form_container{background:#fff;padding:25px;max-width:1300px}.form_container.full{max-width:100%}.form_container .form_group{margin-bottom:10px;display:flex}.form_container .form_group>.label{width:300px;display:inline-flex;align-items:flex-start;justify-content:right;padding-right:10px}.form_container .form_group .input{width:calc(100% - 300px)}.fullscreen_description{position:fixed !important;top:25px;left:25px;right:25px;bottom:25px;z-index:9999;background:#fff;padding:20px;overflow:auto;border-radius:.25rem;box-shadow:0 0 20px rgba(0,0,0,.3)}.fullscreen{position:absolute;top:10px;right:10px;cursor:pointer;color:#fff;background:#cc563d;display:inline-flex;height:40px;width:40px;border-radius:6px;align-items:center;justify-content:center;transition:all .3s ease}.fullscreen:hover{transform:scale(1.05);text-decoration:none}.task_popup{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:none;z-index:9999}.task_popup .task_details{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);background:#fff;padding:25px;border-radius:6px;max-width:1140px;width:100%;transition:all .3s ease;height:90vh}.task_popup .task_details .content{height:calc(100% - 50px)}.task_popup .task_details.open_works_time{max-width:1540px}.task_popup .task_details.open_works_time .content{grid-template-columns:1fr 300px 350px}.task_popup .task_details.open_works_time .content .task_work_details{display:block}.task_popup .task_details .title{font-size:20px;margin-bottom:25px;display:flex;align-items:center;gap:10px}.task_popup .task_details .title a{border:1px solid #099885;display:inline-flex;height:30px;width:30px;border-radius:6px;align-items:center;justify-content:center}.task_popup .task_details .title a:hover{text-decoration:none}.task_popup .task_details .title a i{color:#099885}.task_popup .task_details .title a.task-delete{border:1px solid #cc563d}.task_popup .task_details .title a.task-delete i{color:#cc563d}.task_popup .task_details .title a i{font-size:14px}.task_popup .task_details .title .task-title-edit-box{align-items:center;gap:6px}.task_popup .task_details .title .task-title-edit-box .task-title-input{height:30px;font-size:14px;padding:2px 8px;width:300px;border:1px solid #ccc;border-radius:4px}.task_popup .task_details .title .task-title-edit-box a.task-title-save,.task_popup .task_details .title .task-title-edit-box a.task-title-cancel{height:30px;width:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:6px}.task_popup .task_details .title .task-title-edit-box a.task-title-save i,.task_popup .task_details .title .task-title-edit-box a.task-title-cancel i{font-size:13px}.task_popup .task_details .title .task-title-edit-box a.task-title-save{background:#099885;border-color:#099885}.task_popup .task_details .title .task-title-edit-box a.task-title-save i{color:#fff}.task_popup .task_details .title .task-title-edit-box a.task-title-cancel{background:#cc563d;border-color:#cc563d}.task_popup .task_details .title .task-title-edit-box a.task-title-cancel i{color:#fff}.task_popup .task_details .close{position:absolute;top:10px;right:10px;cursor:pointer}.task_popup .task_details .content{display:grid;font-size:14px;grid-template-columns:1fr 300px;gap:30px;transition:all .3s ease}.task_popup .task_details .content h3{width:100%;margin-top:0;margin-bottom:5px;font-weight:500;color:#000;font-size:17px}.task_popup .task_details .content .left{height:100%;overflow:hidden}.task_popup .task_details .content .left .users{display:flex;gap:20px}.task_popup .task_details .content .left .users .user{display:flex;gap:10px;align-items:center;margin-bottom:10px}.task_popup .task_details .content .left .users .user .avatar{height:30px;width:30px;border-radius:6px;background:#ccc;display:flex;justify-content:center;align-items:center;color:#fff;font-size:12px}.task_popup .task_details .content .left .comments{border-radius:3px;max-height:406px;overflow-y:auto}.task_popup .task_details .content .left .comments .new_comment{margin-bottom:10px}.task_popup .task_details .content .left .comments .new_comment textarea{height:75px;margin-bottom:10px;border-radius:6px}.task_popup .task_details .content .left .comments .new_comment .add_comment{background:#099885;color:#fff;padding:10px;border-radius:6px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:200px;text-decoration:none}.task_popup .task_details .content .left .comments .new_comment .add_comment:hover{background:#4a9c3b}.task_popup .task_details .content .left .comments ul{margin:0;padding:0;list-style-type:none}.task_popup .task_details .content .left .comments ul li{background:#ced4da;margin-bottom:5px;padding:15px;border-radius:6px;position:relative}.task_popup .task_details .content .left .comments ul li .delete_comment{position:absolute;top:10px;right:10px;cursor:pointer;color:#cc563d}.task_popup .task_details .content .left .comments ul li .author{font-weight:600;margin-bottom:5px;display:inline-flex;margin-right:10px}.task_popup .task_details .content .left .comments ul li .date{font-size:12px;margin-bottom:5px;display:inline-flex}.task_popup .task_details .content .left .comments ul li .text{margin-bottom:15px;font-size:13px}.task_popup .task_details .content .left .checklist{border-radius:3px;margin-bottom:10px}.task_popup .task_details .content .left .checklist .new_element{display:flex;margin-bottom:10px}.task_popup .task_details .content .left .checklist .new_element input{border-radius:6px 0 0 6px}.task_popup .task_details .content .left .checklist .new_element a{display:flex;align-items:center;justify-content:center;padding:10px;border-radius:0 6px 6px 0;text-decoration:none;width:35px;background:#099885;color:#fff}.task_popup .task_details .content .left .checklist ul{margin:0;padding:0;list-style-type:none;overflow-y:auto;max-height:calc(90vh - 400px)}.task_popup .task_details .content .left .checklist ul li{display:flex;gap:10px;margin-bottom:5px;background:#fff;border-radius:3px;padding:10px;border:1px solid #cdcdcd;font-size:13px;align-items:flex-start}.task_popup .task_details .content .left .checklist ul li a{margin-left:auto;margin-right:0;cursor:pointer;background:#cc563d;display:flex;height:25px;width:25px;min-width:25px;justify-content:center;align-items:center;border:0;border-radius:3px;transition:all .3s ease}.task_popup .task_details .content .left .checklist ul li a:hover{text-decoration:none;background:#b30000}.task_popup .task_details .content .left .checklist ul li a i{color:#fff;font-size:12px}.task_popup .task_details .content .left .attachments{margin-top:10px;border:1px solid #e6e9ed;border-radius:8px;padding:12px;background:#f9fbfd}.task_popup .task_details .content .left .attachments h3{margin-bottom:10px;font-size:16px;font-weight:600}.task_popup .task_details .content .left .attachments .attachments_upload{display:flex;gap:10px;align-items:center;margin-bottom:10px}.task_popup .task_details .content .left .attachments .attachments_upload .attachment_file_input{flex:1;margin-bottom:0;border-radius:6px;background:#fff}.task_popup .task_details .content .left .attachments .attachments_upload .attachment-upload-btn{white-space:nowrap;border-radius:6px;min-width:150px}.task_popup .task_details .content .left .attachments .attachments_upload .attachment-upload-btn.is-loading{pointer-events:none;opacity:.85}.task_popup .task_details .content .left .attachments .attachments_upload .attachment-upload-btn.is-loading i{margin-right:6px}.task_popup .task_details .content .left .attachments .attachments_list{margin:0;padding:0;list-style:none;display:grid;gap:8px;max-height:180px;overflow-y:auto}.task_popup .task_details .content .left .attachments .attachments_list li{display:flex;align-items:center;gap:8px;background:#fff;border:1px solid #e4e8ee;border-radius:6px;padding:8px 10px}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-link{color:#1f3d72;text-decoration:none;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:calc(100% - 140px)}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-link:hover{text-decoration:underline}.task_popup .task_details .content .left .attachments .attachments_list li small{color:#6b7280;margin-right:auto}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-rename,.task_popup .task_details .content .left .attachments .attachments_list li .attachment-delete{display:inline-flex;align-items:center;justify-content:center;height:28px;width:28px;border-radius:4px;text-decoration:none;transition:all .2s ease}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-rename{border:1px solid #d8e2f6;color:#6690f4;background:#f4f8ff}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-rename:hover{background:#e7f0ff}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-delete{border:1px solid #f1d3d1;color:#cc563d;background:#fff6f6}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-delete:hover{background:#ffeaea}.task_popup .task_details .content .left .attachments .attachments_list .attachments-empty{color:#6b7280;border-style:dashed;justify-content:center;font-size:13px}.task_popup .task_details .content .left .description{padding:15px;border-radius:.25rem;border:1px solid #cdcdcd;margin-bottom:15px;max-height:202px;overflow-x:hidden;position:relative}.task_popup .task_details .content .right .box{margin-bottom:15px}.task_popup .task_details .content .right .time a.time_worked_toggle{color:#299cdb;display:inline-flex;border:1px solid #299cdb}.task_popup .task_details .content .right .time a.time_worked_toggle:hover{background:#dff0fa;text-decoration:none}.task_popup .task_details .content .right .time a.time_worked_toggle:active,.task_popup .task_details .content .right .time a.time_worked_toggle:focus{text-decoration:none}.task_popup .task_details .content .right .time a:not(.time_worked_toggle){margin-top:10px;text-decoration:none;gap:10px}.task_popup .task_details .content .right .time a:not(.time_worked_toggle).task_start{background:#0ab39c;color:#fff}.task_popup .task_details .content .right .time a:not(.time_worked_toggle).task_start:hover{background:#099885}.task_popup .task_details .content .right .time a:not(.time_worked_toggle).task_end{background:#cc563d;color:#fff}.task_popup .task_details .content .right .time a:not(.time_worked_toggle).hidden{display:none}.task_popup .task_details .content .right .dates{display:flex;justify-content:space-between;flex-wrap:wrap}.task_popup .task_details .content .right .dates .danger{color:#cc563d;font-weight:600}.task_popup .task_details .content .right .dates .warning{color:#ff8c00}.task_popup .task_details .content .right .dates i{color:#c9ced4;margin-right:5px}.task_popup .task_details .content .task_work_details{display:none;overflow-y:auto;max-height:508px;width:100%;padding-right:10px;padding-top:4px}.task_popup .task_details .content .task_work_details ._line{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:5px}.task_popup .task_details .content .task_work_details ._line ._user{width:100%;font-size:13px}.task_popup .task_details .content .task_work_details ._line input{width:calc(50% - 25px);text-align:center;margin-left:2px;margin-right:2px}.task_popup .task_details .content .task_work_details ._work_delete{display:inline-flex;height:35px;width:35px;border-radius:6px;align-items:center;justify-content:center;cursor:pointer;border:1px solid #cc563d;margin-left:2px;transition:all .3s ease}.task_popup .task_details .content .task_work_details ._work_delete:hover{background:#cc563d}.task_popup .task_details .content .task_work_details ._work_delete:hover i{color:#fff}.task_popup .task_details .content .task_work_details ._work_delete i{transition:all .3s ease;color:#cc563d}.table{width:100%;border:none;border-radius:8px;overflow:hidden;box-shadow:0 1px 3px rgba(0,0,0,.06);background:#fff}.table th,.table td{padding:10px 14px;border:none;border-bottom:1px solid #eef0f3;text-align:left;vertical-align:middle}.table thead th{background:#f5f7fa;color:#4e5e6a;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.3px;white-space:nowrap;border-bottom:2px solid #e2e6ec}.table tbody tr{transition:background .15s ease}.table tbody tr:last-child td{border-bottom:none}.table tbody tr:hover{background:#f8fafd}.table td.center,.table th.center{text-align:center}.table td.left,.table th.left{text-align:left}.table td.right,.table th.right{text-align:right}.table td[colspan]{text-align:center;color:#8896a4;padding:24px 14px;font-style:italic}.projects_container{background:#fff;padding:15px;border-radius:6px;display:flex;gap:20px}.projects_container .left{width:calc(100% - 250px)}.projects_container .left ._projects,.projects_container .left ._users{display:flex;gap:20px;flex-wrap:wrap}.projects_container .right{width:250px;display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:center;gap:20px;border-left:1px solid #cdcdcd;padding-left:15px}.projects_container .right select{width:200px}.default_popup{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:none}.default_popup .popup_content{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);background:#fff;padding:25px;border-radius:0;max-width:1140px;width:100%}.default_popup .popup_content .close{position:absolute;top:10px;right:10px;cursor:pointer}#fg-cron{margin:10px 0}#fg-cron .countdown{background:#099885;color:#fff;padding:10px}#fg-cron #cron-container{max-height:300px;overflow-x:hidden;overflow-y:auto}#fg-cron #cron-container .msg{font-size:13px;padding:5px;border-bottom:1px solid #e8e8e8}.card{background:#fff;padding:25px;border-radius:6px;color:#000;font-size:15px;max-width:1280px}.card.mb25{margin-bottom:25px}.card .card-header{font-weight:600}.card .card-body{padding-top:10px}.card .card-body table{border-collapse:collapse}.card .card-body table th,.card .card-body table td{font-size:14px}.card .card-body table th.bold,.card .card-body table td.bold{font-weight:600}.card .card-body table th.text-right,.card .card-body table td.text-right{text-align:right}.card .card-body table th.text-center,.card .card-body table td.text-center{text-align:center}.card .card-body table th .close-task,.card .card-body table td .close-task{text-decoration:none;color:#6690f4}.card .card-body table th .close-task:hover,.card .card-body table td .close-task:hover{color:#cc563d}.finance-summary{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:10px}.finance-summary .panel{background:#fff;border-radius:6px;padding:15px}.finance-summary .panel h1{font-size:20px;margin:0}.finance-summary .panel span{font-size:.85em}.finance-manager{display:grid;gap:10px;grid-template-columns:200px 1fr 500px;padding-top:25px}.finance-manager .manage-menu{display:inline-block;margin-right:10px}.finance-manager .manage-menu a{color:#333;text-decoration:none;font-weight:300;display:block}.finance-manager .actions{width:100px;text-align:center}.finance-manager .actions a{display:inline-flex;margin:0 2px;height:25px;width:25px;align-items:center;justify-content:center;text-decoration:none;color:#000;border:1px solid #e7e7e7;font-size:11px;border-radius:3px;transition:all .3s ease}.finance-manager .actions a:hover{border:1px solid #6690f4}.bootstrap-tagsinput .tag{background:#6690f4;font-size:13px;padding:5px 10px;border-radius:12px}.bootstrap-tagsinput .tag [data-role=remove]{color:#fff !important}.bootstrap-tagsinput .tag [data-role=remove]:hover{box-shadow:none !important;color:#000 !important}.finance-tags{display:flex;flex-wrap:wrap;gap:5px}.finance-tags a:not(.btn){display:flex;width:100%;text-decoration:none;color:#4e5e6a}.finance-tags a:not(.btn).zoom-100{font-size:1.2em}.finance-tags a:not(.btn).zoom-90{font-size:1.15em}.finance-tags a:not(.btn).zoom-80{font-size:1.1em}.finance-tags a:not(.btn).zoom-70{font-size:1.05em}.finance-tags a:not(.btn).zoom-60{font-size:1em}.finance-tags a:not(.btn).zoom-50{font-size:.95em}.finance-tags a:not(.btn).zoom-40{font-size:.9em}.finance-tags a:not(.btn).zoom-30{font-size:.85em}.finance-tags a:not(.btn).zoom-20{font-size:.8em}.finance-tags a:not(.btn).zoom-10{font-size:.75em}.finance-tags a:not(.btn).zoom-0{font-size:.7em}.manage-menu{position:relative}.manage-menu .context-menu{border-left:4px dotted #000;width:1px;height:100%}.manage-menu .context-menu-container{position:absolute;display:none;background:#fff;box-shadow:5px 5px 15px rgba(0,0,0,.1);top:2px;left:2px}.manage-menu .context-menu-container ul{list-style-type:none;margin:0;padding:0}.manage-menu .context-menu-container ul li a{display:block;padding:7px 15px;white-space:nowrap}.manage-menu .context-menu-container ul li a:hover{background:#f8f8f8}.manage-menu:hover .context-menu-container{display:block}.wiki-categories{display:grid;gap:10px;margin-top:25px;grid-template-columns:1fr 1fr 1fr 1fr}.wiki-categories .category{background:#fff;padding:10px}.wiki-categories .category .users{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:5px}.wiki-categories .category .users .user{display:flex;height:25px;width:25px;border-radius:50%;background:#ccc;justify-content:center;align-items:center;color:#fff;font-size:12px}.wiki-categories .category .actions{display:grid;grid-template-columns:1fr 1fr}.wiki-categories .category .actions a{display:block;color:#4e5e6a;font-size:13px;text-align:center}.wiki-categories .category .title{margin-bottom:5px}.wiki-categories .category .title a{display:block;color:#4e5e6a;font-size:13px;font-weight:600}.bootstrap-datetimepicker-widget .picker-switch a{display:block;color:#000}.gantt_users{display:flex;gap:20px}#g-results{background:#fff;padding:25px}.g-menu-container{margin-bottom:15px}.g-menu-container .right-menu{display:none}.g-center{text-align:center}.alert{background:#099885;border:0;color:#fff}.tasks_main_view{display:flex;gap:20px}.tasks_main_view ._left_column{padding:25px;background:#fcfcfc;border-right:1px solid #e8e8e8;width:350px}.tasks_main_view ._left_column label{font-weight:400;font-size:14px}.tasks_main_view ._left_column select[name=filtr]{margin-bottom:10px}.tasks_main_view ._left_column ._buttons{display:flex;gap:10px;justify-content:space-between}.tasks_main_view ._left_column ._buttons .btn{flex:1}.tasks_main_view ._right_column{flex:1;max-width:calc(100% - 350px)}#billing-summary .card-header{padding:10px}#billing-summary .billing-kpi{border:1px solid #dee2e6;border-radius:6px;padding:10px 12px;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.04)}#billing-summary .billing-kpi-label{font-size:12px;color:#6c757d;margin-bottom:3px}#billing-summary .billing-kpi-value{font-size:21px;font-weight:700;line-height:1.1}#billing-summary .billing-details-row{display:none}#billing-summary .billing-client-name{font-weight:600}#billing-summary .billing-table>thead>tr>th{background:#f8f9fa}#billing-summary .billing-details-wrap{background:#f8fbff}.vacation-type-badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:500;background:#e3f0ff;color:#2563eb}.vacation-type-badge.type-chorobowe{background:#fff3e0;color:#e65100}.vacation-type-badge.type-inna_nieobecnosc{background:#f3e5f5;color:#7b1fa2}/*# sourceMappingURL=style.css.map */
\ No newline at end of file
+.default-btn,.task_popup .task_details .content .right .time a:not(.time_worked_toggle),.task_popup .task_details .content .right .time a.time_worked_toggle{display:flex;align-items:center;justify-content:center;height:40px;border-radius:6px;padding:0 15px;transition:all .3s ease}.default-btn:hover,.task_popup .task_details .content .right .time a:hover:not(.time_worked_toggle),.task_popup .task_details .content .right .time a.time_worked_toggle:hover{text-decoration:none}.animate{animation:mymove 3s infinite}.text-right{text-align:right}.nowrap{white-space:nowrap}table{border-collapse:collapse;font-size:13px}small{font-size:.75em}@keyframes mymove{50%{opacity:.33}}@keyframes gradient-animation{0%{background-position:15% 0%}50%{background-position:85% 100%}100%{background-position:15% 0%}}@keyframes frame-enter{0%{clip-path:polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) calc(100% - 3px), 3px calc(100% - 3px), 3px 100%, 100% 100%, 100% 0%, 0% 0%)}25%{clip-path:polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) calc(100% - 3px), calc(100% - 3px) calc(100% - 3px), calc(100% - 3px) 100%, 100% 100%, 100% 0%, 0% 0%)}50%{clip-path:polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, 100% 0%, 0% 0%)}75%{-webkit-clip-path:polygon(0% 100%, 3px 100%, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 0%, 0% 0%)}100%{-webkit-clip-path:polygon(0% 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 0% 100%)}}*{box-sizing:border-box}body{font-family:"Open Sans",sans-serif;margin:0;padding:0;font-size:15px;color:#4e5e6a}.btn{padding:9px 25px;transition:all .3s ease;color:#fff;border:0;border-radius:6px;cursor:pointer;display:inline-flex;text-decoration:none;gap:5px;justify-content:center;align-items:center}.btn.btn_small,.btn.btn-xs,.btn.btn-sm{padding:5px 7px;font-size:13px}.btn.btn_small i,.btn.btn-xs i,.btn.btn-sm i{font-size:12px}.btn.btn-success{background:#099885}.btn.btn-success:hover{background:#4a9c3b}.btn.btn-primary{background:#6690f4}.btn.btn-primary:hover{background:#3164db}.btn.btn-danger{background:#cc563d}.btn.btn-danger:hover{background:#b30000}.hide{display:none}.form-error{color:#cc563d;font-size:13px}.input-group{margin-bottom:10px}.form-field{margin-bottom:15px}.form-field label{display:block;font-size:13px;font-weight:600;margin-bottom:4px;color:#4e5e6a}.password-wrap{position:relative}.password-wrap .form-control{padding-right:40px}.password-wrap .password-eye{position:absolute;right:10px;top:50%;transform:translateY(-50%);color:#999;text-decoration:none;z-index:2}.password-wrap .password-eye:hover{color:#333}input[type=checkbox]{border:1px solid #cdcdcd}.form-control{border:1px solid #cdcdcd;border-radius:6px;height:35px;width:100%;padding:5px;font-family:"Open Sans",sans-serif}.form-control option{padding:5px}.form-control:focus{border:1px solid #6690f4;outline:none}.unlogged{background:#eef1f9;display:flex;align-items:center;justify-content:center;height:100vh}.unlogged .box-login{background:#fff;padding:25px;border-radius:6px;width:400px}.unlogged .box-login .title{text-align:center;padding:10px 10px 25px;border-bottom:1px solid #cdcdcd;font-size:20px;margin-bottom:25px}.sidebar{position:fixed;top:0;left:0;width:220px;height:100vh;background:#1e2a3a;display:flex;flex-direction:column;z-index:1000;transition:width .3s ease;overflow:hidden}.sidebar.collapsed{width:60px}.sidebar.collapsed .sidebar-header .sidebar-logo span,.sidebar.collapsed .sidebar-nav ul li a span,.sidebar.collapsed .sidebar-footer span,.sidebar.collapsed .sidebar-footer .sidebar-user span{display:none}.sidebar.collapsed .sidebar-header .sidebar-logo{font-size:0}.sidebar.collapsed .sidebar-header .sidebar-logo::first-letter{font-size:16px}.sidebar.collapsed .sidebar-nav ul li a{justify-content:center;padding:10px}.sidebar.collapsed .sidebar-nav ul li a i{margin-right:0}.sidebar.collapsed .sidebar-nav ul li.has-submenu .submenu-arrow{display:none}.sidebar.collapsed .sidebar-nav ul li.has-submenu .sidebar-submenu{display:none}.sidebar.collapsed .sidebar-footer .sidebar-footer-link,.sidebar.collapsed .sidebar-footer .sidebar-user{justify-content:center;padding:8px 10px}.sidebar.collapsed .sidebar-footer .sidebar-footer-link i,.sidebar.collapsed .sidebar-footer .sidebar-user i{margin-right:0}.sidebar .sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:15px;border-bottom:1px solid hsla(0,0%,100%,.1)}.sidebar .sidebar-header .sidebar-logo{color:#6690f4;text-decoration:none;font-size:16px;white-space:nowrap}.sidebar .sidebar-header .sidebar-logo span{font-weight:700}.sidebar .sidebar-header .sidebar-toggle{cursor:pointer;color:#c2c7d0;font-size:16px;transition:color .2s ease}.sidebar .sidebar-header .sidebar-toggle:hover{color:#fff}.sidebar .sidebar-nav{flex:1;overflow-y:auto;padding:10px 0}.sidebar .sidebar-nav ul{list-style:none;margin:0;padding:0}.sidebar .sidebar-nav ul li a{display:flex;align-items:center;padding:10px 15px;color:#c2c7d0;text-decoration:none;font-size:14px;transition:all .2s ease;white-space:nowrap}.sidebar .sidebar-nav ul li a i{width:20px;text-align:center;margin-right:10px;font-size:15px}.sidebar .sidebar-nav ul li a:hover{background:hsla(0,0%,100%,.08);color:#fff}.sidebar .sidebar-nav ul li.active a{background:hsla(0,0%,100%,.08);color:#fff;font-weight:600}.sidebar .sidebar-nav ul li.has-submenu>a .submenu-arrow{margin-left:auto;font-size:12px;transition:transform .2s ease;width:auto}.sidebar .sidebar-nav ul li.has-submenu.open>a .submenu-arrow{transform:rotate(180deg)}.sidebar .sidebar-nav ul li.has-submenu .sidebar-submenu{max-height:0;overflow:hidden;transition:max-height .25s ease;background:rgba(0,0,0,.15)}.sidebar .sidebar-nav ul li.has-submenu .sidebar-submenu li a{padding:8px 15px 8px 45px;font-size:13px}.sidebar .sidebar-nav ul li.has-submenu .sidebar-submenu li a i{font-size:13px;width:16px}.sidebar .sidebar-nav ul li.has-submenu.open .sidebar-submenu{max-height:200px}.sidebar .sidebar-footer{border-top:1px solid hsla(0,0%,100%,.1);padding:10px 0}.sidebar .sidebar-footer .sidebar-user{display:flex;align-items:center;padding:8px 15px;color:#c2c7d0;font-size:13px;white-space:nowrap;overflow:hidden}.sidebar .sidebar-footer .sidebar-user i{margin-right:10px;color:#6690f4}.sidebar .sidebar-footer .sidebar-footer-link{display:flex;align-items:center;padding:8px 15px;color:#c2c7d0;text-decoration:none;font-size:13px;transition:all .2s ease;white-space:nowrap}.sidebar .sidebar-footer .sidebar-footer-link i{width:20px;text-align:center;margin-right:10px}.sidebar .sidebar-footer .sidebar-footer-link:hover{background:hsla(0,0%,100%,.08);color:#fff}.sidebar .sidebar-footer .sidebar-footer-link.logout{color:#cc563d}.sidebar .sidebar-footer .sidebar-footer-link.logout:hover{color:#e07a66}.content-wrapper{margin-left:220px;min-height:100vh;transition:margin-left .3s ease}.content-wrapper.expanded{margin-left:60px}.top-bar{background:#fff;border-bottom:1px solid #e8e8e8;padding:10px 20px;display:flex;align-items:center}.top-bar .top-bar-left{display:flex;align-items:center;gap:15px}.top-bar .top-bar-left i{cursor:pointer;font-size:18px;color:#4e5e6a}.top-bar .top-bar-left i:hover{color:#000}.main{padding:25px;background:#d9dee2;min-height:calc(100vh - 45px)}.tasks_container{display:grid;grid-template-columns:repeat(5, 1fr);gap:20px}.tasks_container .column{width:100%}.tasks_container .column h2{display:flex;padding:10px;background:#fff;margin-bottom:10px;font-size:15px;font-weight:300;border-radius:3px 3px 0 0;justify-content:space-between;align-items:center}.tasks_container .column h2 i{cursor:pointer}.tasks_container .column.tasks_suspended h2{border-bottom:5px solid #cc563d}.tasks_container .column.tasks_fvat h2{border-bottom:5px solid #a900fc}.tasks_container .column.tasks_new h2{border-bottom:5px solid #ccc}.tasks_container .column.tasks_bulk h2{border-bottom:5px solid #ff8c00}.tasks_container .column.tasks_to_do h2{border-bottom:5px solid #2aaf47}.tasks_container .column.tasks_to_review h2{border-bottom:5px solid #2535c9}.tasks_container .column.tasks_closed h2{border-bottom:5px solid #000}.tasks_container .column ul{list-style-type:none;margin:0;padding:0}.tasks_container .column ul .task{margin-bottom:5px;background:#fff;padding:10px;border-radius:0;display:flex;position:relative;border-radius:6px;flex-wrap:wrap}.tasks_container .column ul .task.notopened{border:2px solid #cc563d}.tasks_container .column ul .task .top{display:flex;justify-content:space-between;margin-bottom:5px;width:100%}.tasks_container .column ul .task .top ._users{display:flex;gap:5px;flex-wrap:wrap}.tasks_container .column ul .task .top ._users .user{display:flex;width:25px;height:25px;border-radius:6px;justify-content:center;align-items:center;color:#fff;font-size:12px}.tasks_container .column ul .task .top ._timer{display:flex;gap:5px}.tasks_container .column ul .task .top ._timer .recursively{color:#fff;background:#405189;border-radius:3px;cursor:pointer;margin-bottom:5px;width:25px;height:25px;text-align:center;display:block}.tasks_container .column ul .task .top ._timer .recursively i{font-size:12px}.tasks_container .column ul .task .top ._timer .task_start{display:block;background:#099885;color:#fff;border-radius:6px;cursor:pointer;margin-bottom:5px;width:25px;height:25px;text-align:center}.tasks_container .column ul .task .top ._timer .task_start.hidden{display:none}.tasks_container .column ul .task .top ._timer .task_start i{font-size:12px}.tasks_container .column ul .task .top ._timer .task_end{background:#cc563d;display:block;color:#fff;border-radius:6px;cursor:pointer;margin-bottom:5px;width:25px;height:25px;text-align:center}.tasks_container .column ul .task .top ._timer .task_end.hidden{display:none}.tasks_container .column ul .task .top ._timer .task_end i{font-size:12px}.tasks_container .column ul .task .middle{width:100%}.tasks_container .column ul .task .name{font-size:14px;color:#333;text-decoration:none;display:block;margin-bottom:5px}.tasks_container .column ul .task .bottom{display:flex;justify-content:space-between}.tasks_container .column ul .task .client_info,.tasks_container .column ul .task .current_status{font-size:12px;font-weight:400}.tasks_container .column ul .task .client_info strong,.tasks_container .column ul .task .current_status strong{font-weight:600}.tasks_container .column ul .task .current_status{position:relative;cursor:pointer}.tasks_container .column ul .task .current_status .status_change{position:absolute;left:0;top:20px;background:#fff;padding:15px;border:1px solid #dfdfdf;border-radius:3px;cursor:pointer;box-shadow:0 0 15px rgba(0,0,0,.1);z-index:99;display:none}.tasks_container .column ul .task .current_status .status_change select{width:250px;padding:10px;border:1px solid #cdcdcd;border-radius:3px}.tasks_container .column ul .task .current_status .status_change select option{font-size:15px;padding:3px}.tasks_container .column ul .task .dates{margin-bottom:5px;display:flex;justify-content:space-between;font-size:12px}.tasks_container .column ul .task .dates .danger{color:#cc563d;font-weight:600}.tasks_container .column ul .task .dates .warning{color:#ff8c00}.tasks_container .column ul .task .dates i{font-size:12px;color:#c9ced4;margin-right:5px}.block-header{margin-bottom:20px}.block-header h2{font-size:20px;font-weight:400;color:#4e5e6a;margin:0;padding-bottom:12px;border-bottom:2px solid #e2e6ec}.block-header h2 strong{font-weight:700}.filters-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:24px;padding:12px 16px;background:#f5f7fa;border-radius:8px;border:1px solid #e2e6ec}.filters-bar select,.filters-bar input[type=text],.filters-bar input[type=date],.filters-bar input[type=number]{height:36px;min-width:170px;padding:0 10px;border:1px solid #d0d5dd;border-radius:6px;background:#fff;font-size:13px;color:#4e5e6a;font-family:"Open Sans",sans-serif;transition:border-color .2s}.filters-bar select:focus,.filters-bar input[type=text]:focus,.filters-bar input[type=date]:focus,.filters-bar input[type=number]:focus{border-color:#6690f4;outline:none}.filters-bar .btn{height:36px;display:inline-flex;align-items:center;gap:5px;padding:0 14px;border-radius:6px;font-size:13px;font-weight:500;border:none;cursor:pointer;transition:background .2s,box-shadow .2s;text-decoration:none;color:#fff}.filters-bar .btn.btn-primary{background:#6690f4}.filters-bar .btn.btn-primary:hover{background:#4a74d4}.filters-bar .btn.btn-success{background:#099885}.filters-bar .btn.btn-success:hover{background:#077a6b}.section-title{font-size:14px;font-weight:600;color:#4e5e6a;margin:28px 0 12px;padding-bottom:8px;border-bottom:1px solid #e2e6ec}.action_menu{display:flex;margin-bottom:25px;gap:20px}.action_menu .btn{display:inline-flex;padding:7px 15px;color:#fff;text-decoration:none;align-items:center;justify-content:center;gap:5px}.action_menu .btn.btn_add{background:#099885}.action_menu .btn.btn_add:hover{background:#4a9c3b}.action_menu .btn.btn_cancel{background:#cc563d}.action_menu .btn.btn_cancel:hover{background:#b30000}.action_menu .btn.disabled{opacity:.5}.form_container{background:#fff;padding:25px;max-width:1300px}.form_container.full{max-width:100%}.form_container .form_group{margin-bottom:10px;display:flex}.form_container .form_group>.label{width:300px;display:inline-flex;align-items:flex-start;justify-content:right;padding-right:10px}.form_container .form_group .input{width:calc(100% - 300px)}.fullscreen_description{position:fixed !important;top:25px;left:25px;right:25px;bottom:25px;z-index:9999;background:#fff;padding:20px;overflow:auto;border-radius:.25rem;box-shadow:0 0 20px rgba(0,0,0,.3)}.fullscreen{position:absolute;top:10px;right:10px;cursor:pointer;color:#fff;background:#cc563d;display:inline-flex;height:40px;width:40px;border-radius:6px;align-items:center;justify-content:center;transition:all .3s ease}.fullscreen:hover{transform:scale(1.05);text-decoration:none}.task_popup{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:none;z-index:9999}.task_popup .task_details{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);background:#fff;padding:25px;border-radius:6px;max-width:1140px;width:100%;transition:all .3s ease;height:90vh}.task_popup .task_details .content{height:calc(100% - 50px)}.task_popup .task_details.open_works_time{max-width:1540px}.task_popup .task_details.open_works_time .content{grid-template-columns:1fr 300px 350px}.task_popup .task_details.open_works_time .content .task_work_details{display:block}.task_popup .task_details .title{font-size:20px;margin-bottom:25px;display:flex;align-items:center;gap:10px}.task_popup .task_details .title a{border:1px solid #099885;display:inline-flex;height:30px;width:30px;border-radius:6px;align-items:center;justify-content:center}.task_popup .task_details .title a:hover{text-decoration:none}.task_popup .task_details .title a i{color:#099885}.task_popup .task_details .title a.task-delete{border:1px solid #cc563d}.task_popup .task_details .title a.task-delete i{color:#cc563d}.task_popup .task_details .title a i{font-size:14px}.task_popup .task_details .title .task-title-edit-box{align-items:center;gap:6px}.task_popup .task_details .title .task-title-edit-box .task-title-input{height:30px;font-size:14px;padding:2px 8px;width:300px;border:1px solid #ccc;border-radius:4px}.task_popup .task_details .title .task-title-edit-box a.task-title-save,.task_popup .task_details .title .task-title-edit-box a.task-title-cancel{height:30px;width:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:6px}.task_popup .task_details .title .task-title-edit-box a.task-title-save i,.task_popup .task_details .title .task-title-edit-box a.task-title-cancel i{font-size:13px}.task_popup .task_details .title .task-title-edit-box a.task-title-save{background:#099885;border-color:#099885}.task_popup .task_details .title .task-title-edit-box a.task-title-save i{color:#fff}.task_popup .task_details .title .task-title-edit-box a.task-title-cancel{background:#cc563d;border-color:#cc563d}.task_popup .task_details .title .task-title-edit-box a.task-title-cancel i{color:#fff}.task_popup .task_details .close{position:absolute;top:10px;right:10px;cursor:pointer}.task_popup .task_details .content{display:grid;font-size:14px;grid-template-columns:1fr 300px;gap:30px;transition:all .3s ease}.task_popup .task_details .content h3{width:100%;margin-top:0;margin-bottom:5px;font-weight:500;color:#000;font-size:17px}.task_popup .task_details .content .left{height:100%;overflow:hidden}.task_popup .task_details .content .left .users{display:flex;gap:20px}.task_popup .task_details .content .left .users .user{display:flex;gap:10px;align-items:center;margin-bottom:10px}.task_popup .task_details .content .left .users .user .avatar{height:30px;width:30px;border-radius:6px;background:#ccc;display:flex;justify-content:center;align-items:center;color:#fff;font-size:12px}.task_popup .task_details .content .left .comments{border-radius:3px;max-height:406px;overflow-y:auto}.task_popup .task_details .content .left .comments .new_comment{margin-bottom:10px}.task_popup .task_details .content .left .comments .new_comment textarea{height:75px;margin-bottom:10px;border-radius:6px}.task_popup .task_details .content .left .comments .new_comment .add_comment{background:#099885;color:#fff;padding:10px;border-radius:6px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:200px;text-decoration:none}.task_popup .task_details .content .left .comments .new_comment .add_comment:hover{background:#4a9c3b}.task_popup .task_details .content .left .comments ul{margin:0;padding:0;list-style-type:none}.task_popup .task_details .content .left .comments ul li{background:#ced4da;margin-bottom:5px;padding:15px;border-radius:6px;position:relative}.task_popup .task_details .content .left .comments ul li .delete_comment{position:absolute;top:10px;right:10px;cursor:pointer;color:#cc563d}.task_popup .task_details .content .left .comments ul li .author{font-weight:600;margin-bottom:5px;display:inline-flex;margin-right:10px}.task_popup .task_details .content .left .comments ul li .date{font-size:12px;margin-bottom:5px;display:inline-flex}.task_popup .task_details .content .left .comments ul li .text{margin-bottom:15px;font-size:13px}.task_popup .task_details .content .left .checklist{border-radius:3px;margin-bottom:10px}.task_popup .task_details .content .left .checklist .new_element{display:flex;margin-bottom:10px}.task_popup .task_details .content .left .checklist .new_element input{border-radius:6px 0 0 6px}.task_popup .task_details .content .left .checklist .new_element a{display:flex;align-items:center;justify-content:center;padding:10px;border-radius:0 6px 6px 0;text-decoration:none;width:35px;background:#099885;color:#fff}.task_popup .task_details .content .left .checklist ul{margin:0;padding:0;list-style-type:none;overflow-y:auto;max-height:calc(90vh - 400px)}.task_popup .task_details .content .left .checklist ul li{display:flex;gap:10px;margin-bottom:5px;background:#fff;border-radius:3px;padding:10px;border:1px solid #cdcdcd;font-size:13px;align-items:flex-start}.task_popup .task_details .content .left .checklist ul li a{margin-left:auto;margin-right:0;cursor:pointer;background:#cc563d;display:flex;height:25px;width:25px;min-width:25px;justify-content:center;align-items:center;border:0;border-radius:3px;transition:all .3s ease}.task_popup .task_details .content .left .checklist ul li a:hover{text-decoration:none;background:#b30000}.task_popup .task_details .content .left .checklist ul li a i{color:#fff;font-size:12px}.task_popup .task_details .content .left .attachments{margin-top:10px;border:1px solid #e6e9ed;border-radius:8px;padding:12px;background:#f9fbfd}.task_popup .task_details .content .left .attachments h3{margin-bottom:10px;font-size:16px;font-weight:600}.task_popup .task_details .content .left .attachments .attachments_upload{display:flex;gap:10px;align-items:center;margin-bottom:10px}.task_popup .task_details .content .left .attachments .attachments_upload .attachment_file_input{flex:1;margin-bottom:0;border-radius:6px;background:#fff}.task_popup .task_details .content .left .attachments .attachments_upload .attachment-upload-btn{white-space:nowrap;border-radius:6px;min-width:150px}.task_popup .task_details .content .left .attachments .attachments_upload .attachment-upload-btn.is-loading{pointer-events:none;opacity:.85}.task_popup .task_details .content .left .attachments .attachments_upload .attachment-upload-btn.is-loading i{margin-right:6px}.task_popup .task_details .content .left .attachments .attachments_list{margin:0;padding:0;list-style:none;display:grid;gap:8px;max-height:180px;overflow-y:auto}.task_popup .task_details .content .left .attachments .attachments_list li{display:flex;align-items:center;gap:8px;background:#fff;border:1px solid #e4e8ee;border-radius:6px;padding:8px 10px}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-link{color:#1f3d72;text-decoration:none;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:calc(100% - 140px)}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-link:hover{text-decoration:underline}.task_popup .task_details .content .left .attachments .attachments_list li small{color:#6b7280;margin-right:auto}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-rename,.task_popup .task_details .content .left .attachments .attachments_list li .attachment-delete{display:inline-flex;align-items:center;justify-content:center;height:28px;width:28px;border-radius:4px;text-decoration:none;transition:all .2s ease}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-rename{border:1px solid #d8e2f6;color:#6690f4;background:#f4f8ff}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-rename:hover{background:#e7f0ff}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-delete{border:1px solid #f1d3d1;color:#cc563d;background:#fff6f6}.task_popup .task_details .content .left .attachments .attachments_list li .attachment-delete:hover{background:#ffeaea}.task_popup .task_details .content .left .attachments .attachments_list .attachments-empty{color:#6b7280;border-style:dashed;justify-content:center;font-size:13px}.task_popup .task_details .content .left .description{padding:15px;border-radius:.25rem;border:1px solid #cdcdcd;margin-bottom:15px;max-height:202px;overflow-x:hidden;position:relative}.task_popup .task_details .content .right .box{margin-bottom:15px}.task_popup .task_details .content .right .time a.time_worked_toggle{color:#299cdb;display:inline-flex;border:1px solid #299cdb}.task_popup .task_details .content .right .time a.time_worked_toggle:hover{background:#dff0fa;text-decoration:none}.task_popup .task_details .content .right .time a.time_worked_toggle:active,.task_popup .task_details .content .right .time a.time_worked_toggle:focus{text-decoration:none}.task_popup .task_details .content .right .time a:not(.time_worked_toggle){margin-top:10px;text-decoration:none;gap:10px}.task_popup .task_details .content .right .time a:not(.time_worked_toggle).task_start{background:#0ab39c;color:#fff}.task_popup .task_details .content .right .time a:not(.time_worked_toggle).task_start:hover{background:#099885}.task_popup .task_details .content .right .time a:not(.time_worked_toggle).task_end{background:#cc563d;color:#fff}.task_popup .task_details .content .right .time a:not(.time_worked_toggle).hidden{display:none}.task_popup .task_details .content .right .dates{display:flex;justify-content:space-between;flex-wrap:wrap}.task_popup .task_details .content .right .dates .danger{color:#cc563d;font-weight:600}.task_popup .task_details .content .right .dates .warning{color:#ff8c00}.task_popup .task_details .content .right .dates i{color:#c9ced4;margin-right:5px}.task_popup .task_details .content .task_work_details{display:none;overflow-y:auto;max-height:508px;width:100%;padding-right:10px;padding-top:4px}.task_popup .task_details .content .task_work_details ._line{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;margin-bottom:5px}.task_popup .task_details .content .task_work_details ._line ._user{width:100%;font-size:13px}.task_popup .task_details .content .task_work_details ._line input{width:calc(50% - 25px);text-align:center;margin-left:2px;margin-right:2px}.task_popup .task_details .content .task_work_details ._work_delete{display:inline-flex;height:35px;width:35px;border-radius:6px;align-items:center;justify-content:center;cursor:pointer;border:1px solid #cc563d;margin-left:2px;transition:all .3s ease}.task_popup .task_details .content .task_work_details ._work_delete:hover{background:#cc563d}.task_popup .task_details .content .task_work_details ._work_delete:hover i{color:#fff}.task_popup .task_details .content .task_work_details ._work_delete i{transition:all .3s ease;color:#cc563d}.table{width:100%;border:none;border-radius:8px;overflow:hidden;box-shadow:0 1px 3px rgba(0,0,0,.06);background:#fff}.table th,.table td{padding:10px 14px;border:none;border-bottom:1px solid #eef0f3;text-align:left;vertical-align:middle}.table thead th{background:#f5f7fa;color:#4e5e6a;font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.3px;white-space:nowrap;border-bottom:2px solid #e2e6ec}.table tbody tr{transition:background .15s ease}.table tbody tr:last-child td{border-bottom:none}.table tbody tr:hover{background:#f8fafd}.table td.center,.table th.center{text-align:center}.table td.left,.table th.left{text-align:left}.table td.right,.table th.right{text-align:right}.table td[colspan]{text-align:center;color:#8896a4;padding:24px 14px;font-style:italic}.projects_container{background:#fff;padding:15px;border-radius:6px;display:flex;gap:20px}.projects_container .left{width:calc(100% - 250px)}.projects_container .left ._projects,.projects_container .left ._users{display:flex;gap:20px;flex-wrap:wrap}.projects_container .right{width:250px;display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:center;gap:20px;border-left:1px solid #cdcdcd;padding-left:15px}.projects_container .right select{width:200px}.default_popup{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.5);display:none}.default_popup .popup_content{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);background:#fff;padding:25px;border-radius:0;max-width:1140px;width:100%}.default_popup .popup_content .close{position:absolute;top:10px;right:10px;cursor:pointer}#fg-cron{margin:10px 0}#fg-cron .countdown{background:#099885;color:#fff;padding:10px}#fg-cron #cron-container{max-height:300px;overflow-x:hidden;overflow-y:auto}#fg-cron #cron-container .msg{font-size:13px;padding:5px;border-bottom:1px solid #e8e8e8}.card{background:#fff;padding:25px;border-radius:6px;color:#000;font-size:15px;max-width:1280px}.card.mb25{margin-bottom:25px}.card .card-header{font-weight:600}.card .card-body{padding-top:10px}.card .card-body table{border-collapse:collapse}.card .card-body table th,.card .card-body table td{font-size:14px}.card .card-body table th.bold,.card .card-body table td.bold{font-weight:600}.card .card-body table th.text-right,.card .card-body table td.text-right{text-align:right}.card .card-body table th.text-center,.card .card-body table td.text-center{text-align:center}.card .card-body table th .close-task,.card .card-body table td .close-task{text-decoration:none;color:#6690f4}.card .card-body table th .close-task:hover,.card .card-body table td .close-task:hover{color:#cc563d}.finance-summary{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:10px}.finance-summary .panel{background:#fff;border-radius:6px;padding:15px}.finance-summary .panel h1{font-size:20px;margin:0}.finance-summary .panel span{font-size:.85em}.finance-manager{display:grid;gap:10px;grid-template-columns:250px 1fr 500px;padding-top:25px}.finance-manager .manage-menu{display:inline-block;margin-right:10px}.finance-manager .manage-menu a{color:#333;text-decoration:none;font-weight:300;display:block}.finance-manager .actions{width:100px;text-align:center}.finance-manager .actions a{display:inline-flex;margin:0 2px;height:25px;width:25px;align-items:center;justify-content:center;text-decoration:none;color:#000;border:1px solid #e7e7e7;font-size:11px;border-radius:3px;transition:all .3s ease}.finance-manager .actions a:hover{border:1px solid #6690f4}.bootstrap-tagsinput .tag{background:#6690f4;font-size:13px;padding:5px 10px;border-radius:12px}.bootstrap-tagsinput .tag [data-role=remove]{color:#fff !important}.bootstrap-tagsinput .tag [data-role=remove]:hover{box-shadow:none !important;color:#000 !important}.finance-tags{display:flex;flex-wrap:wrap;gap:5px}.finance-tags a:not(.btn){display:flex;width:100%;text-decoration:none;color:#4e5e6a}.finance-tags a:not(.btn).zoom-100{font-size:1.2em}.finance-tags a:not(.btn).zoom-90{font-size:1.15em}.finance-tags a:not(.btn).zoom-80{font-size:1.1em}.finance-tags a:not(.btn).zoom-70{font-size:1.05em}.finance-tags a:not(.btn).zoom-60{font-size:1em}.finance-tags a:not(.btn).zoom-50{font-size:.95em}.finance-tags a:not(.btn).zoom-40{font-size:.9em}.finance-tags a:not(.btn).zoom-30{font-size:.85em}.finance-tags a:not(.btn).zoom-20{font-size:.8em}.finance-tags a:not(.btn).zoom-10{font-size:.75em}.finance-tags a:not(.btn).zoom-0{font-size:.7em}.manage-menu{position:relative}.manage-menu .context-menu{border-left:4px dotted #000;width:1px;height:100%}.manage-menu .context-menu-container{position:absolute;display:none;background:#fff;box-shadow:5px 5px 15px rgba(0,0,0,.1);top:2px;left:2px}.manage-menu .context-menu-container ul{list-style-type:none;margin:0;padding:0}.manage-menu .context-menu-container ul li a{display:block;padding:7px 15px;white-space:nowrap}.manage-menu .context-menu-container ul li a:hover{background:#f8f8f8}.manage-menu:hover .context-menu-container{display:block}.wiki-categories{display:grid;gap:10px;margin-top:25px;grid-template-columns:1fr 1fr 1fr 1fr}.wiki-categories .category{background:#fff;padding:10px}.wiki-categories .category .users{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;gap:5px}.wiki-categories .category .users .user{display:flex;height:25px;width:25px;border-radius:50%;background:#ccc;justify-content:center;align-items:center;color:#fff;font-size:12px}.wiki-categories .category .actions{display:grid;grid-template-columns:1fr 1fr}.wiki-categories .category .actions a{display:block;color:#4e5e6a;font-size:13px;text-align:center}.wiki-categories .category .title{margin-bottom:5px}.wiki-categories .category .title a{display:block;color:#4e5e6a;font-size:13px;font-weight:600}.bootstrap-datetimepicker-widget .picker-switch a{display:block;color:#000}.gantt_users{display:flex;gap:20px}#g-results{background:#fff;padding:25px}.g-menu-container{margin-bottom:15px}.g-menu-container .right-menu{display:none}.g-center{text-align:center}.alert{background:#099885;border:0;color:#fff}.tasks_main_view{display:flex;gap:20px;align-items:flex-start}.tasks_main_view ._left_column{width:-moz-fit-content;width:fit-content;min-width:350px;max-width:520px;padding:0;background:rgba(0,0,0,0);border-right:0}.tasks_main_view ._left_column .filters_panel{background:linear-gradient(180deg, #fdfefe 0%, #f4f7fb 100%);border:1px solid #dbe2ea;border-radius:12px;padding:16px;box-shadow:none}.tasks_main_view ._left_column .filters_panel_header{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}.tasks_main_view ._left_column .filters_panel_title{display:flex;align-items:center;gap:8px}.tasks_main_view ._left_column .filters_panel_title i{color:#1f3d72}.tasks_main_view ._left_column .filters_panel_title h3{margin:0;font-size:16px;font-weight:700;color:#1f3d72}.tasks_main_view ._left_column .active_filters_badge{display:inline-flex;align-items:center;padding:4px 10px;border-radius:999px;font-size:12px;color:#425466;background:#e9eff8}.tasks_main_view ._left_column .active_filters_badge strong{margin-left:4px;font-size:13px;color:#1f3d72}.tasks_main_view ._left_column .filters_controls{margin-bottom:14px;padding:12px;border-radius:10px;border:1px solid #dbe2ea;background:#fff}.tasks_main_view ._left_column .filters_label{display:block;margin-bottom:6px;font-size:12px;font-weight:600;color:#425466}.tasks_main_view ._left_column select[name=filtr]{margin-bottom:12px;height:40px;border-color:#d1dae4}.tasks_main_view ._left_column select[name=filtr]:focus{border-color:#5f88e9;box-shadow:0 0 0 3px rgba(95,136,233,.15)}.tasks_main_view ._left_column ._buttons{display:flex;gap:8px}.tasks_main_view ._left_column ._buttons .btn{flex:1;min-height:34px;font-size:12px;text-transform:uppercase;letter-spacing:.3px}.tasks_main_view ._left_column ._buttons .btn-dark{background:#3d495e}.tasks_main_view ._left_column ._buttons .btn-dark:hover{background:#2f394c}.tasks_main_view ._left_column .filters_section{border:1px solid #dbe2ea;border-radius:10px;background:#fff;margin-bottom:12px;overflow:hidden}.tasks_main_view ._left_column .filters_section_header{display:flex;gap:8px;align-items:center;justify-content:space-between;padding:10px 12px;background:#f4f7fb;border-bottom:1px solid #e3eaf2}.tasks_main_view ._left_column .filters_section_header h4{margin:0;font-size:14px;font-weight:700;color:#243447}.tasks_main_view ._left_column .filters_section_header .filters_search{max-width:170px;height:32px;font-size:12px;padding:4px 10px;border-color:#d2dbe6}.tasks_main_view ._left_column .filters_section_list{max-height:270px;overflow-y:auto;padding:6px}.tasks_main_view ._left_column .filters_section._projects .filters_section_list{max-height:none;overflow:visible}.tasks_main_view ._left_column .filters_item{border-radius:8px;transition:background .2s ease}.tasks_main_view ._left_column .filters_item:hover{background:#f4f7fb}.tasks_main_view ._left_column .project_row,.tasks_main_view ._left_column ._user{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:5px 7px}.tasks_main_view ._left_column .project_row label,.tasks_main_view ._left_column ._user label{margin:0;flex:1;font-weight:400;font-size:14px;white-space:nowrap}.tasks_main_view ._left_column .project_count{display:inline-block;margin-left:4px;min-width:26px;padding:0 7px;border-radius:999px;background:#1f3d72;color:#fff;font-weight:700;font-size:11px;line-height:19px;text-align:center;vertical-align:middle}.tasks_main_view ._left_column .project_delete_inline{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:5px;border:1px solid #cc563d;background:#cc563d;color:#fff;text-decoration:none;transition:all .2s ease;margin:1px 0}.tasks_main_view ._left_column .project_delete_inline:hover{background:#b74831;border-color:#b74831}.tasks_main_view ._left_column .project_delete_inline i{font-size:10px}.tasks_main_view ._right_column{flex:1;max-width:none;min-width:0}@media(max-width: 1200px){.tasks_main_view{flex-direction:column}.tasks_main_view ._left_column,.tasks_main_view ._right_column{max-width:100%;width:100%}}.gantt-target .gantt-container.gantt-draggable{cursor:grab}.gantt-target .gantt-container.gantt-dragging{cursor:grabbing}#billing-summary .card-header{padding:10px}#billing-summary .billing-kpi{border:1px solid #dee2e6;border-radius:6px;padding:10px 12px;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.04)}#billing-summary .billing-kpi-label{font-size:12px;color:#6c757d;margin-bottom:3px}#billing-summary .billing-kpi-value{font-size:21px;font-weight:700;line-height:1.1}#billing-summary .billing-details-row{display:none}#billing-summary .billing-client-name{font-weight:600}#billing-summary .billing-table>thead>tr>th{background:#f8f9fa}#billing-summary .billing-details-wrap{background:#f8fbff}.vacation-type-badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:500;background:#e3f0ff;color:#2563eb}.vacation-type-badge.type-chorobowe{background:#fff3e0;color:#e65100}.vacation-type-badge.type-inna_nieobecnosc{background:#f3e5f5;color:#7b1fa2}/*# sourceMappingURL=style.css.map */
\ No newline at end of file
diff --git a/layout/style.css.map b/layout/style.css.map
index 48ce7f3..4a6ae0d 100644
--- a/layout/style.css.map
+++ b/layout/style.css.map
@@ -1 +1 @@
-{"version":3,"sources":["style.scss"],"names":[],"mappings":"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","file":"style.css","sourcesContent":["$cBlue: #6690F4;\r\n$cRed: #cc563d;\r\n$cGreen: #099885;\r\n$cBlack: #4e5e6a;\r\n\r\n.default-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 40px;\r\n border-radius: 6px;\r\n padding: 0 15px;\r\n transition: all .3s ease;\r\n\r\n &:hover {\r\n text-decoration: none;\r\n }\r\n}\r\n\r\n.animate {\r\n animation: mymove 3s infinite;\r\n}\r\n\r\n.text-right {\r\n text-align: right;\r\n}\r\n\r\n.nowrap {\r\n white-space: nowrap;\r\n}\r\n\r\ntable {\r\n border-collapse: collapse;\r\n font-size: 13px;\r\n}\r\n\r\nsmall {\r\n font-size: .75em;\r\n}\r\n\r\n@keyframes mymove {\r\n 50% {\r\n opacity: .33;\r\n }\r\n}\r\n\r\n/* motion */\r\n@keyframes gradient-animation {\r\n 0% {\r\n background-position: 15% 0%;\r\n }\r\n\r\n 50% {\r\n background-position: 85% 100%;\r\n }\r\n\r\n 100% {\r\n background-position: 15% 0%;\r\n }\r\n}\r\n\r\n@keyframes frame-enter {\r\n 0% {\r\n clip-path: polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) calc(100% - 3px), 3px calc(100% - 3px), 3px 100%, 100% 100%, 100% 0%, 0% 0%);\r\n }\r\n\r\n 25% {\r\n clip-path: polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) calc(100% - 3px), calc(100% - 3px) calc(100% - 3px), calc(100% - 3px) 100%, 100% 100%, 100% 0%, 0% 0%);\r\n }\r\n\r\n 50% {\r\n clip-path: polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, 100% 0%, 0% 0%);\r\n }\r\n\r\n 75% {\r\n -webkit-clip-path: polygon(0% 100%, 3px 100%, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 0%, 0% 0%);\r\n }\r\n\r\n 100% {\r\n -webkit-clip-path: polygon(0% 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 0% 100%);\r\n }\r\n}\r\n\r\n* {\r\n box-sizing: border-box;\r\n}\r\n\r\nbody {\r\n font-family: \"Open Sans\", sans-serif;\r\n margin: 0;\r\n padding: 0;\r\n font-size: 15px;\r\n color: #4e5e6a;\r\n}\r\n\r\n.btn {\r\n padding: 9px 25px;\r\n transition: all 0.3s ease;\r\n color: #FFF;\r\n border: 0;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n display: inline-flex;\r\n text-decoration: none;\r\n gap: 5px;\r\n justify-content: center;\r\n align-items: center;\r\n\r\n &.btn_small,\r\n &.btn-xs,\r\n &.btn-sm {\r\n padding: 5px 7px;\r\n font-size: 13px;\r\n\r\n i {\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n &.btn-success {\r\n background: $cGreen;\r\n\r\n &:hover {\r\n background: #4a9c3b;\r\n }\r\n }\r\n\r\n &.btn-primary {\r\n background: $cBlue;\r\n\r\n &:hover {\r\n background: #3164db;\r\n }\r\n }\r\n\r\n &.btn-danger {\r\n background: $cRed;\r\n\r\n &:hover {\r\n background: #b30000;\r\n }\r\n }\r\n}\r\n\r\n.hide {\r\n display: none;\r\n}\r\n\r\n.form-error {\r\n color: $cRed;\r\n font-size: 13px;\r\n}\r\n\r\n.input-group {\r\n margin-bottom: 10px;\r\n}\r\n\r\n.form-field {\r\n margin-bottom: 15px;\r\n\r\n label {\r\n display: block;\r\n font-size: 13px;\r\n font-weight: 600;\r\n margin-bottom: 4px;\r\n color: #4e5e6a;\r\n }\r\n}\r\n\r\n.password-wrap {\r\n position: relative;\r\n\r\n .form-control {\r\n padding-right: 40px;\r\n }\r\n\r\n .password-eye {\r\n position: absolute;\r\n right: 10px;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n color: #999;\r\n text-decoration: none;\r\n z-index: 2;\r\n\r\n &:hover {\r\n color: #333;\r\n }\r\n }\r\n}\r\n\r\ninput[type=\"checkbox\"] {\r\n border: 1px solid #cdcdcd;\r\n}\r\n\r\n.form-control {\r\n border: 1px solid #cdcdcd;\r\n border-radius: 6px;\r\n height: 35px;\r\n width: 100%;\r\n padding: 5px;\r\n font-family: \"Open Sans\", sans-serif;\r\n\r\n option {\r\n padding: 5px;\r\n }\r\n\r\n &:focus {\r\n border: 1px solid $cBlue;\r\n outline: none;\r\n }\r\n}\r\n\r\n.unlogged {\r\n background: #EEF1F9;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100vh;\r\n\r\n .box-login {\r\n background: #FFF;\r\n padding: 25px;\r\n border-radius: 6px;\r\n width: 400px;\r\n\r\n .title {\r\n text-align: center;\r\n padding: 10px 10px 25px;\r\n border-bottom: 1px solid #cdcdcd;\r\n font-size: 20px;\r\n margin-bottom: 25px;\r\n }\r\n }\r\n}\r\n\r\n$sidebar-width: 220px;\r\n$sidebar-collapsed-width: 60px;\r\n$sidebar-bg: #1e2a3a;\r\n$sidebar-text: #c2c7d0;\r\n$sidebar-active: #fff;\r\n$sidebar-hover-bg: rgba(255, 255, 255, 0.08);\r\n\r\n.sidebar {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: $sidebar-width;\r\n height: 100vh;\r\n background: $sidebar-bg;\r\n display: flex;\r\n flex-direction: column;\r\n z-index: 1000;\r\n transition: width 0.3s ease;\r\n overflow: hidden;\r\n\r\n &.collapsed {\r\n width: $sidebar-collapsed-width;\r\n\r\n .sidebar-header .sidebar-logo span,\r\n .sidebar-nav ul li a span,\r\n .sidebar-footer span,\r\n .sidebar-footer .sidebar-user span {\r\n display: none;\r\n }\r\n\r\n .sidebar-header .sidebar-logo {\r\n font-size: 0;\r\n\r\n &::first-letter {\r\n font-size: 16px;\r\n }\r\n }\r\n\r\n .sidebar-nav ul li a {\r\n justify-content: center;\r\n padding: 10px;\r\n\r\n i {\r\n margin-right: 0;\r\n }\r\n }\r\n\r\n .sidebar-nav ul li.has-submenu {\r\n .submenu-arrow {\r\n display: none;\r\n }\r\n\r\n .sidebar-submenu {\r\n display: none;\r\n }\r\n }\r\n\r\n .sidebar-footer .sidebar-footer-link,\r\n .sidebar-footer .sidebar-user {\r\n justify-content: center;\r\n padding: 8px 10px;\r\n\r\n i {\r\n margin-right: 0;\r\n }\r\n }\r\n }\r\n\r\n .sidebar-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 15px;\r\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\r\n\r\n .sidebar-logo {\r\n color: $cBlue;\r\n text-decoration: none;\r\n font-size: 16px;\r\n white-space: nowrap;\r\n\r\n span {\r\n font-weight: 700;\r\n }\r\n }\r\n\r\n .sidebar-toggle {\r\n cursor: pointer;\r\n color: $sidebar-text;\r\n font-size: 16px;\r\n transition: color 0.2s ease;\r\n\r\n &:hover {\r\n color: #fff;\r\n }\r\n }\r\n }\r\n\r\n .sidebar-nav {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 10px 0;\r\n\r\n ul {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0;\r\n\r\n li {\r\n a {\r\n display: flex;\r\n align-items: center;\r\n padding: 10px 15px;\r\n color: $sidebar-text;\r\n text-decoration: none;\r\n font-size: 14px;\r\n transition: all 0.2s ease;\r\n white-space: nowrap;\r\n\r\n i {\r\n width: 20px;\r\n text-align: center;\r\n margin-right: 10px;\r\n font-size: 15px;\r\n }\r\n\r\n &:hover {\r\n background: $sidebar-hover-bg;\r\n color: $sidebar-active;\r\n }\r\n }\r\n\r\n &.active a {\r\n background: $sidebar-hover-bg;\r\n color: $sidebar-active;\r\n font-weight: 600;\r\n }\r\n\r\n &.has-submenu {\r\n >a .submenu-arrow {\r\n margin-left: auto;\r\n font-size: 12px;\r\n transition: transform 0.2s ease;\r\n width: auto;\r\n }\r\n\r\n &.open>a .submenu-arrow {\r\n transform: rotate(180deg);\r\n }\r\n\r\n .sidebar-submenu {\r\n max-height: 0;\r\n overflow: hidden;\r\n transition: max-height 0.25s ease;\r\n background: rgba(0, 0, 0, 0.15);\r\n\r\n li a {\r\n padding: 8px 15px 8px 45px;\r\n font-size: 13px;\r\n\r\n i {\r\n font-size: 13px;\r\n width: 16px;\r\n }\r\n }\r\n }\r\n\r\n &.open .sidebar-submenu {\r\n max-height: 200px;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n .sidebar-footer {\r\n border-top: 1px solid rgba(255, 255, 255, 0.1);\r\n padding: 10px 0;\r\n\r\n .sidebar-user {\r\n display: flex;\r\n align-items: center;\r\n padding: 8px 15px;\r\n color: $sidebar-text;\r\n font-size: 13px;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n\r\n i {\r\n margin-right: 10px;\r\n color: $cBlue;\r\n }\r\n }\r\n\r\n .sidebar-footer-link {\r\n display: flex;\r\n align-items: center;\r\n padding: 8px 15px;\r\n color: $sidebar-text;\r\n text-decoration: none;\r\n font-size: 13px;\r\n transition: all 0.2s ease;\r\n white-space: nowrap;\r\n\r\n i {\r\n width: 20px;\r\n text-align: center;\r\n margin-right: 10px;\r\n }\r\n\r\n &:hover {\r\n background: $sidebar-hover-bg;\r\n color: $sidebar-active;\r\n }\r\n\r\n &.logout {\r\n color: $cRed;\r\n\r\n &:hover {\r\n color: #e07a66;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n.content-wrapper {\r\n margin-left: $sidebar-width;\r\n min-height: 100vh;\r\n transition: margin-left 0.3s ease;\r\n\r\n &.expanded {\r\n margin-left: $sidebar-collapsed-width;\r\n }\r\n}\r\n\r\n.top-bar {\r\n background: #fff;\r\n border-bottom: 1px solid #e8e8e8;\r\n padding: 10px 20px;\r\n display: flex;\r\n align-items: center;\r\n\r\n .top-bar-left {\r\n display: flex;\r\n align-items: center;\r\n gap: 15px;\r\n\r\n i {\r\n cursor: pointer;\r\n font-size: 18px;\r\n color: #4e5e6a;\r\n\r\n &:hover {\r\n color: #000;\r\n }\r\n }\r\n }\r\n}\r\n\r\n.main {\r\n padding: 25px;\r\n background: #D9DEE2;\r\n min-height: calc(100vh - 45px);\r\n}\r\n\r\n.tasks_container {\r\n display: grid;\r\n grid-template-columns: repeat(5, 1fr);\r\n gap: 20px;\r\n\r\n .column {\r\n width: 100%;\r\n\r\n h2 {\r\n display: flex;\r\n padding: 10px;\r\n background: #FFF;\r\n margin-bottom: 10px;\r\n font-size: 15px;\r\n font-weight: 300;\r\n border-radius: 3px 3px 0 0;\r\n justify-content: space-between;\r\n align-items: center;\r\n\r\n i {\r\n cursor: pointer;\r\n }\r\n }\r\n\r\n &.tasks_suspended {\r\n h2 {\r\n border-bottom: 5px solid $cRed;\r\n }\r\n }\r\n\r\n &.tasks_fvat {\r\n h2 {\r\n border-bottom: 5px solid #a900fc;\r\n }\r\n }\r\n\r\n &.tasks_new {\r\n h2 {\r\n border-bottom: 5px solid #ccc;\r\n }\r\n }\r\n\r\n &.tasks_bulk {\r\n h2 {\r\n border-bottom: 5px solid #ff8c00;\r\n }\r\n }\r\n\r\n &.tasks_to_do {\r\n h2 {\r\n border-bottom: 5px solid #2aaf47;\r\n }\r\n }\r\n\r\n &.tasks_to_review {\r\n h2 {\r\n border-bottom: 5px solid #2535c9;\r\n }\r\n }\r\n\r\n &.tasks_closed {\r\n h2 {\r\n border-bottom: 5px solid #000;\r\n }\r\n }\r\n\r\n ul {\r\n list-style-type: none;\r\n margin: 0;\r\n padding: 0;\r\n\r\n .task {\r\n margin-bottom: 5px;\r\n background: #FFF;\r\n padding: 10px;\r\n border-radius: 0;\r\n display: flex;\r\n position: relative;\r\n border-radius: 6px;\r\n flex-wrap: wrap;\r\n\r\n &.notopened {\r\n border: 2px solid $cRed;\r\n }\r\n\r\n .top {\r\n display: flex;\r\n justify-content: space-between;\r\n margin-bottom: 5px;\r\n width: 100%;\r\n\r\n ._users {\r\n display: flex;\r\n gap: 5px;\r\n flex-wrap: wrap;\r\n\r\n .user {\r\n display: flex;\r\n width: 25px;\r\n height: 25px;\r\n border-radius: 6px;\r\n justify-content: center;\r\n align-items: center;\r\n color: #FFF;\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n ._timer {\r\n display: flex;\r\n gap: 5px;\r\n\r\n .recursively {\r\n color: #FFF;\r\n background: #405189;\r\n border-radius: 3px;\r\n cursor: pointer;\r\n margin-bottom: 5px;\r\n width: 25px;\r\n height: 25px;\r\n text-align: center;\r\n display: block;\r\n\r\n i {\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n .task_start {\r\n display: block;\r\n background: $cGreen;\r\n color: #FFF;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n margin-bottom: 5px;\r\n width: 25px;\r\n height: 25px;\r\n text-align: center;\r\n\r\n &.hidden {\r\n display: none;\r\n }\r\n\r\n i {\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n .task_end {\r\n background: $cRed;\r\n display: block;\r\n color: #FFF;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n margin-bottom: 5px;\r\n width: 25px;\r\n height: 25px;\r\n text-align: center;\r\n\r\n &.hidden {\r\n display: none;\r\n }\r\n\r\n i {\r\n font-size: 12px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .middle {\r\n width: 100%;\r\n }\r\n\r\n .name {\r\n font-size: 14px;\r\n color: #333;\r\n text-decoration: none;\r\n display: block;\r\n margin-bottom: 5px;\r\n }\r\n\r\n .bottom {\r\n display: flex;\r\n justify-content: space-between;\r\n }\r\n\r\n .client_info,\r\n .current_status {\r\n font-size: 12px;\r\n font-weight: 400;\r\n\r\n strong {\r\n font-weight: 600;\r\n }\r\n }\r\n\r\n .current_status {\r\n position: relative;\r\n cursor: pointer;\r\n\r\n .status_change {\r\n position: absolute;\r\n left: 0;\r\n top: 20px;\r\n background: #fff;\r\n padding: 15px;\r\n border: 1px solid #dfdfdf;\r\n border-radius: 3px;\r\n cursor: pointer;\r\n box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);\r\n z-index: 99;\r\n display: none;\r\n\r\n select {\r\n width: 250px;\r\n padding: 10px;\r\n border: 1px solid #cdcdcd;\r\n border-radius: 3px;\r\n\r\n option {\r\n font-size: 15px;\r\n padding: 3px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .dates {\r\n margin-bottom: 5px;\r\n display: flex;\r\n justify-content: space-between;\r\n font-size: 12px;\r\n\r\n .danger {\r\n color: $cRed;\r\n font-weight: 600;\r\n }\r\n\r\n .warning {\r\n color: #ff8c00;\r\n }\r\n\r\n i {\r\n font-size: 12px;\r\n color: #C9CED4;\r\n margin-right: 5px;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n/* page header */\r\n.block-header {\r\n margin-bottom: 20px;\r\n\r\n h2 {\r\n font-size: 20px;\r\n font-weight: 400;\r\n color: $cBlack;\r\n margin: 0;\r\n padding-bottom: 12px;\r\n border-bottom: 2px solid #e2e6ec;\r\n\r\n strong {\r\n font-weight: 700;\r\n }\r\n }\r\n}\r\n\r\n/* filters bar — reusable across modules */\r\n.filters-bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 10px;\r\n flex-wrap: wrap;\r\n margin-bottom: 24px;\r\n padding: 12px 16px;\r\n background: #f5f7fa;\r\n border-radius: 8px;\r\n border: 1px solid #e2e6ec;\r\n\r\n select,\r\n input[type=\"text\"],\r\n input[type=\"date\"],\r\n input[type=\"number\"] {\r\n height: 36px;\r\n min-width: 170px;\r\n padding: 0 10px;\r\n border: 1px solid #d0d5dd;\r\n border-radius: 6px;\r\n background: #fff;\r\n font-size: 13px;\r\n color: $cBlack;\r\n font-family: \"Open Sans\", sans-serif;\r\n transition: border-color 0.2s;\r\n\r\n &:focus {\r\n border-color: $cBlue;\r\n outline: none;\r\n }\r\n }\r\n\r\n .btn {\r\n height: 36px;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 5px;\r\n padding: 0 14px;\r\n border-radius: 6px;\r\n font-size: 13px;\r\n font-weight: 500;\r\n border: none;\r\n cursor: pointer;\r\n transition: background 0.2s, box-shadow 0.2s;\r\n text-decoration: none;\r\n color: #fff;\r\n\r\n &.btn-primary {\r\n background: $cBlue;\r\n\r\n &:hover {\r\n background: #4a74d4;\r\n }\r\n }\r\n\r\n &.btn-success {\r\n background: $cGreen;\r\n\r\n &:hover {\r\n background: #077a6b;\r\n }\r\n }\r\n }\r\n}\r\n\r\n/* section title — reusable */\r\n.section-title {\r\n font-size: 14px;\r\n font-weight: 600;\r\n color: $cBlack;\r\n margin: 28px 0 12px;\r\n padding-bottom: 8px;\r\n border-bottom: 1px solid #e2e6ec;\r\n}\r\n\r\n.action_menu {\r\n display: flex;\r\n margin-bottom: 25px;\r\n gap: 20px;\r\n\r\n .btn {\r\n display: inline-flex;\r\n padding: 7px 15px;\r\n color: #FFF;\r\n text-decoration: none;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 5px;\r\n\r\n &.btn_add {\r\n background: $cGreen;\r\n\r\n &:hover {\r\n background: #4a9c3b;\r\n }\r\n }\r\n\r\n &.btn_cancel {\r\n background: $cRed;\r\n\r\n &:hover {\r\n background: #b30000;\r\n }\r\n }\r\n\r\n &.disabled {\r\n opacity: .5;\r\n }\r\n }\r\n}\r\n\r\n.form_container {\r\n background: #FFF;\r\n padding: 25px;\r\n max-width: 1300px;\r\n\r\n &.full {\r\n max-width: 100%;\r\n }\r\n\r\n .form_group {\r\n margin-bottom: 10px;\r\n display: flex;\r\n\r\n >.label {\r\n width: 300px;\r\n display: inline-flex;\r\n align-items: flex-start;\r\n justify-content: right;\r\n padding-right: 10px;\r\n }\r\n\r\n .input {\r\n width: calc(100% - 300px);\r\n }\r\n }\r\n}\r\n\r\n.fullscreen_description {\r\n position: fixed !important;\r\n top: 25px;\r\n left: 25px;\r\n right: 25px;\r\n bottom: 25px;\r\n z-index: 9999;\r\n background: white;\r\n padding: 20px;\r\n overflow: auto;\r\n border-radius: 0.25rem;\r\n box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n.fullscreen {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n cursor: pointer;\r\n color: #FFF;\r\n background: $cRed;\r\n display: inline-flex;\r\n height: 40px;\r\n width: 40px;\r\n border-radius: 6px;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.3s ease;\r\n\r\n &:hover {\r\n transform: scale(1.05);\r\n text-decoration: none;\r\n }\r\n}\r\n\r\n.task_popup {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background: rgba(0, 0, 0, 0.5);\r\n display: none;\r\n z-index: 9999;\r\n\r\n .task_details {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n background: #FFF;\r\n padding: 25px;\r\n border-radius: 6px;\r\n max-width: 1140px;\r\n width: 100%;\r\n transition: all 0.3s ease;\r\n height: 90vh;\r\n\r\n .content {\r\n height: calc(100% - 50px);\r\n }\r\n\r\n &.open_works_time {\r\n max-width: 1540px;\r\n\r\n .content {\r\n grid-template-columns: 1fr 300px 350px;\r\n\r\n .task_work_details {\r\n display: block;\r\n }\r\n }\r\n }\r\n\r\n .title {\r\n font-size: 20px;\r\n margin-bottom: 25px;\r\n display: flex;\r\n align-items: center;\r\n gap: 10px;\r\n\r\n a {\r\n border: 1px solid $cGreen;\r\n display: inline-flex;\r\n height: 30px;\r\n width: 30px;\r\n border-radius: 6px;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n &:hover {\r\n text-decoration: none;\r\n }\r\n\r\n i {\r\n color: $cGreen;\r\n }\r\n\r\n &.task-delete {\r\n border: 1px solid $cRed;\r\n\r\n i {\r\n color: $cRed;\r\n }\r\n }\r\n\r\n i {\r\n font-size: 14px;\r\n }\r\n }\r\n\r\n .task-title-edit-box {\r\n align-items: center;\r\n gap: 6px;\r\n\r\n .task-title-input {\r\n height: 30px;\r\n font-size: 14px;\r\n padding: 2px 8px;\r\n width: 300px;\r\n border: 1px solid #ccc;\r\n border-radius: 4px;\r\n }\r\n\r\n a.task-title-save,\r\n a.task-title-cancel {\r\n height: 30px;\r\n width: 30px;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: 6px;\r\n\r\n i {\r\n font-size: 13px;\r\n }\r\n }\r\n\r\n a.task-title-save {\r\n background: $cGreen;\r\n border-color: $cGreen;\r\n\r\n i {\r\n color: #fff;\r\n }\r\n }\r\n\r\n a.task-title-cancel {\r\n background: $cRed;\r\n border-color: $cRed;\r\n\r\n i {\r\n color: #fff;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .close {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n cursor: pointer;\r\n }\r\n\r\n .content {\r\n display: grid;\r\n font-size: 14px;\r\n grid-template-columns: 1fr 300px;\r\n gap: 30px;\r\n transition: all 0.3s ease;\r\n\r\n h3 {\r\n width: 100%;\r\n margin-top: 0;\r\n margin-bottom: 5px;\r\n font-weight: 500;\r\n color: #000;\r\n font-size: 17px;\r\n }\r\n\r\n .left {\r\n height: 100%;\r\n overflow: hidden;\r\n\r\n .users {\r\n display: flex;\r\n gap: 20px;\r\n\r\n .user {\r\n display: flex;\r\n gap: 10px;\r\n align-items: center;\r\n margin-bottom: 10px;\r\n\r\n .avatar {\r\n height: 30px;\r\n width: 30px;\r\n border-radius: 6px;\r\n background: #ccc;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n color: #FFF;\r\n font-size: 12px;\r\n }\r\n }\r\n }\r\n\r\n .comments {\r\n border-radius: 3px;\r\n max-height: 406px;\r\n overflow-y: auto;\r\n\r\n .new_comment {\r\n margin-bottom: 10px;\r\n\r\n textarea {\r\n height: 75px;\r\n margin-bottom: 10px;\r\n border-radius: 6px;\r\n }\r\n\r\n .add_comment {\r\n background: $cGreen;\r\n color: #FFF;\r\n padding: 10px;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 200px;\r\n text-decoration: none;\r\n\r\n &:hover {\r\n background: #4a9c3b;\r\n }\r\n }\r\n }\r\n\r\n ul {\r\n margin: 0;\r\n padding: 0;\r\n list-style-type: none;\r\n\r\n li {\r\n background: #ced4da;\r\n margin-bottom: 5px;\r\n padding: 15px;\r\n border-radius: 6px;\r\n position: relative;\r\n\r\n .delete_comment {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n cursor: pointer;\r\n color: $cRed;\r\n }\r\n\r\n .author {\r\n font-weight: 600;\r\n margin-bottom: 5px;\r\n display: inline-flex;\r\n margin-right: 10px;\r\n }\r\n\r\n .date {\r\n font-size: 12px;\r\n margin-bottom: 5px;\r\n display: inline-flex;\r\n }\r\n\r\n .text {\r\n margin-bottom: 15px;\r\n font-size: 13px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .checklist {\r\n border-radius: 3px;\r\n margin-bottom: 10px;\r\n\r\n .new_element {\r\n display: flex;\r\n margin-bottom: 10px;\r\n\r\n input {\r\n border-radius: 6px 0 0 6px;\r\n }\r\n\r\n a {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 10px;\r\n border-radius: 0 6px 6px 0;\r\n text-decoration: none;\r\n width: 35px;\r\n background: $cGreen;\r\n color: #FFF;\r\n }\r\n }\r\n\r\n ul {\r\n margin: 0;\r\n padding: 0;\r\n list-style-type: none;\r\n overflow-y: auto;\r\n max-height: calc(90vh - 400px);\r\n\r\n li {\r\n display: flex;\r\n gap: 10px;\r\n margin-bottom: 5px;\r\n background: #FFF;\r\n border-radius: 3px;\r\n padding: 10px;\r\n border: 1px solid #cdcdcd;\r\n font-size: 13px;\r\n align-items: flex-start;\r\n\r\n a {\r\n margin-left: auto;\r\n margin-right: 0;\r\n cursor: pointer;\r\n background: $cRed;\r\n display: flex;\r\n height: 25px;\r\n width: 25px;\r\n min-width: 25px;\r\n justify-content: center;\r\n align-items: center;\r\n border: 0;\r\n border-radius: 3px;\r\n transition: all 0.3s ease;\r\n\r\n &:hover {\r\n text-decoration: none;\r\n background: #b30000;\r\n }\r\n\r\n i {\r\n color: #FFF;\r\n font-size: 12px;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n .attachments {\r\n margin-top: 10px;\r\n border: 1px solid #e6e9ed;\r\n border-radius: 8px;\r\n padding: 12px;\r\n background: #f9fbfd;\r\n\r\n h3 {\r\n margin-bottom: 10px;\r\n font-size: 16px;\r\n font-weight: 600;\r\n }\r\n\r\n .attachments_upload {\r\n display: flex;\r\n gap: 10px;\r\n align-items: center;\r\n margin-bottom: 10px;\r\n\r\n .attachment_file_input {\r\n flex: 1;\r\n margin-bottom: 0;\r\n border-radius: 6px;\r\n background: #fff;\r\n }\r\n\r\n .attachment-upload-btn {\r\n white-space: nowrap;\r\n border-radius: 6px;\r\n min-width: 150px;\r\n\r\n &.is-loading {\r\n pointer-events: none;\r\n opacity: 0.85;\r\n\r\n i {\r\n margin-right: 6px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .attachments_list {\r\n margin: 0;\r\n padding: 0;\r\n list-style: none;\r\n display: grid;\r\n gap: 8px;\r\n max-height: 180px;\r\n overflow-y: auto;\r\n\r\n li {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n background: #fff;\r\n border: 1px solid #e4e8ee;\r\n border-radius: 6px;\r\n padding: 8px 10px;\r\n\r\n .attachment-link {\r\n color: #1f3d72;\r\n text-decoration: none;\r\n font-weight: 600;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n max-width: calc(100% - 140px);\r\n\r\n &:hover {\r\n text-decoration: underline;\r\n }\r\n }\r\n\r\n small {\r\n color: #6b7280;\r\n margin-right: auto;\r\n }\r\n\r\n .attachment-rename,\r\n .attachment-delete {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 28px;\r\n width: 28px;\r\n border-radius: 4px;\r\n text-decoration: none;\r\n transition: all 0.2s ease;\r\n }\r\n\r\n .attachment-rename {\r\n border: 1px solid #d8e2f6;\r\n color: $cBlue;\r\n background: #f4f8ff;\r\n\r\n &:hover {\r\n background: #e7f0ff;\r\n }\r\n }\r\n\r\n .attachment-delete {\r\n border: 1px solid #f1d3d1;\r\n color: $cRed;\r\n background: #fff6f6;\r\n\r\n &:hover {\r\n background: #ffeaea;\r\n }\r\n }\r\n }\r\n\r\n .attachments-empty {\r\n color: #6b7280;\r\n border-style: dashed;\r\n justify-content: center;\r\n font-size: 13px;\r\n }\r\n }\r\n }\r\n\r\n .description {\r\n padding: 15px;\r\n border-radius: 0.25rem;\r\n border: 1px solid #cdcdcd;\r\n margin-bottom: 15px;\r\n max-height: 202px;\r\n overflow-x: hidden;\r\n position: relative;\r\n }\r\n }\r\n\r\n .right {\r\n\r\n .box {\r\n margin-bottom: 15px;\r\n }\r\n\r\n .time {\r\n a.time_worked_toggle {\r\n @extend .default-btn;\r\n color: #299cdb;\r\n display: inline-flex;\r\n border: 1px solid #299cdb;\r\n\r\n &:hover {\r\n background: #dff0fa;\r\n text-decoration: none;\r\n }\r\n\r\n &:active,\r\n &:focus {\r\n text-decoration: none;\r\n }\r\n }\r\n\r\n a:not(.time_worked_toggle) {\r\n @extend .default-btn;\r\n margin-top: 10px;\r\n text-decoration: none;\r\n gap: 10px;\r\n\r\n &.task_start {\r\n background: #0ab39c;\r\n color: #FFF;\r\n\r\n &:hover {\r\n background: #099885;\r\n }\r\n }\r\n\r\n &.task_end {\r\n background: $cRed;\r\n color: #FFF;\r\n }\r\n\r\n &.hidden {\r\n display: none;\r\n }\r\n }\r\n }\r\n\r\n .dates {\r\n display: flex;\r\n justify-content: space-between;\r\n flex-wrap: wrap;\r\n\r\n .danger {\r\n color: $cRed;\r\n font-weight: 600;\r\n }\r\n\r\n .warning {\r\n color: #ff8c00;\r\n }\r\n\r\n i {\r\n color: #C9CED4;\r\n margin-right: 5px;\r\n }\r\n }\r\n }\r\n\r\n .task_work_details {\r\n display: none;\r\n overflow-y: auto;\r\n max-height: 508px;\r\n width: 100%;\r\n padding-right: 10px;\r\n padding-top: 4px;\r\n\r\n ._line {\r\n display: flex;\r\n flex-wrap: wrap;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 5px;\r\n\r\n ._user {\r\n width: 100%;\r\n font-size: 13px;\r\n }\r\n\r\n input {\r\n width: calc(50% - 25px);\r\n text-align: center;\r\n margin-left: 2px;\r\n margin-right: 2px;\r\n }\r\n }\r\n\r\n ._work_delete {\r\n display: inline-flex;\r\n height: 35px;\r\n width: 35px;\r\n border-radius: 6px;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n border: 1px solid $cRed;\r\n margin-left: 2px;\r\n transition: all 0.3s ease;\r\n\r\n &:hover {\r\n background: $cRed;\r\n\r\n i {\r\n color: #FFF;\r\n }\r\n }\r\n\r\n i {\r\n transition: all 0.3s ease;\r\n color: $cRed;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n.table {\r\n width: 100%;\r\n border: none;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\r\n background: #fff;\r\n\r\n th,\r\n td {\r\n padding: 10px 14px;\r\n border: none;\r\n border-bottom: 1px solid #eef0f3;\r\n text-align: left;\r\n vertical-align: middle;\r\n }\r\n\r\n thead th {\r\n background: #f5f7fa;\r\n color: #4e5e6a;\r\n font-weight: 600;\r\n font-size: 12px;\r\n text-transform: uppercase;\r\n letter-spacing: 0.3px;\r\n white-space: nowrap;\r\n border-bottom: 2px solid #e2e6ec;\r\n }\r\n\r\n tbody tr {\r\n transition: background 0.15s ease;\r\n\r\n &:last-child td {\r\n border-bottom: none;\r\n }\r\n\r\n &:hover {\r\n background: #f8fafd;\r\n }\r\n }\r\n\r\n td.center,\r\n th.center {\r\n text-align: center;\r\n }\r\n\r\n td.left,\r\n th.left {\r\n text-align: left;\r\n }\r\n\r\n td.right,\r\n th.right {\r\n text-align: right;\r\n }\r\n\r\n // empty state\r\n td[colspan] {\r\n text-align: center;\r\n color: #8896a4;\r\n padding: 24px 14px;\r\n font-style: italic;\r\n }\r\n}\r\n\r\n.projects_container {\r\n background: #FFF;\r\n padding: 15px;\r\n border-radius: 6px;\r\n display: flex;\r\n gap: 20px;\r\n\r\n .left {\r\n width: calc(100% - 250px);\r\n\r\n ._projects,\r\n ._users {\r\n display: flex;\r\n gap: 20px;\r\n flex-wrap: wrap;\r\n }\r\n }\r\n\r\n .right {\r\n width: 250px;\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: flex-start;\r\n justify-content: center;\r\n gap: 20px;\r\n border-left: 1px solid #cdcdcd;\r\n padding-left: 15px;\r\n\r\n select {\r\n width: 200px;\r\n }\r\n }\r\n}\r\n\r\n.default_popup {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background: rgba(0, 0, 0, 0.5);\r\n display: none;\r\n\r\n .popup_content {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n background: #FFF;\r\n padding: 25px;\r\n border-radius: 0;\r\n max-width: 1140px;\r\n width: 100%;\r\n\r\n .close {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n cursor: pointer;\r\n }\r\n }\r\n}\r\n\r\n#fg-cron {\r\n margin: 10px 0;\r\n\r\n .countdown {\r\n background: $cGreen;\r\n color: #FFF;\r\n padding: 10px;\r\n }\r\n\r\n #cron-container {\r\n max-height: 300px;\r\n overflow-x: hidden;\r\n overflow-y: auto;\r\n\r\n .msg {\r\n font-size: 13px;\r\n padding: 5px;\r\n border-bottom: 1px solid #e8e8e8;\r\n }\r\n }\r\n}\r\n\r\n.card {\r\n background: #FFF;\r\n padding: 25px;\r\n border-radius: 6px;\r\n color: #000;\r\n font-size: 15px;\r\n max-width: 1280px;\r\n\r\n &.mb25 {\r\n margin-bottom: 25px;\r\n }\r\n\r\n .card-header {\r\n font-weight: 600;\r\n }\r\n\r\n .card-body {\r\n padding-top: 10px;\r\n\r\n table {\r\n border-collapse: collapse;\r\n\r\n th,\r\n td {\r\n font-size: 14px;\r\n\r\n &.bold {\r\n font-weight: 600;\r\n }\r\n\r\n &.text-right {\r\n text-align: right;\r\n }\r\n\r\n &.text-center {\r\n text-align: center;\r\n }\r\n\r\n .close-task {\r\n text-decoration: none;\r\n color: $cBlue;\r\n\r\n &:hover {\r\n color: $cRed;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n.finance-summary {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr 1fr 1fr;\r\n gap: 10px;\r\n\r\n .panel {\r\n background: #FFF;\r\n border-radius: 6px;\r\n padding: 15px;\r\n\r\n h1 {\r\n font-size: 20px;\r\n margin: 0;\r\n }\r\n\r\n span {\r\n font-size: 0.85em;\r\n }\r\n }\r\n}\r\n\r\n.finance-manager {\r\n display: grid;\r\n gap: 10px;\r\n grid-template-columns: 200px 1fr 500px;\r\n padding-top: 25px;\r\n\r\n .manage-menu {\r\n display: inline-block;\r\n margin-right: 10px;\r\n\r\n a {\r\n color: #333333;\r\n text-decoration: none;\r\n font-weight: 300;\r\n display: block;\r\n }\r\n }\r\n\r\n .actions {\r\n width: 100px;\r\n text-align: center;\r\n\r\n a {\r\n display: inline-flex;\r\n margin: 0 2px;\r\n height: 25px;\r\n width: 25px;\r\n align-items: center;\r\n justify-content: center;\r\n text-decoration: none;\r\n color: #000;\r\n border: 1px solid #e7e7e7;\r\n font-size: 11px;\r\n border-radius: 3px;\r\n transition: all 0.3s ease;\r\n\r\n &:hover {\r\n border: 1px solid $cBlue;\r\n }\r\n }\r\n }\r\n}\r\n\r\n.bootstrap-tagsinput {\r\n .tag {\r\n background: $cBlue;\r\n font-size: 13px;\r\n padding: 5px 10px;\r\n border-radius: 12px;\r\n\r\n [data-role=\"remove\"] {\r\n color: #FFF !important;\r\n\r\n &:hover {\r\n box-shadow: none !important;\r\n color: #000 !important\r\n }\r\n }\r\n }\r\n}\r\n\r\n.finance-tags {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 5px;\r\n\r\n a:not(.btn) {\r\n display: flex;\r\n width: 100%;\r\n text-decoration: none;\r\n color: $cBlack;\r\n\r\n &.zoom-100 {\r\n font-size: 1.2em;\r\n }\r\n\r\n &.zoom-90 {\r\n font-size: 1.15em;\r\n }\r\n\r\n &.zoom-80 {\r\n font-size: 1.1em;\r\n }\r\n\r\n &.zoom-70 {\r\n font-size: 1.05em;\r\n }\r\n\r\n &.zoom-60 {\r\n font-size: 1em;\r\n }\r\n\r\n &.zoom-50 {\r\n font-size: 0.95em;\r\n }\r\n\r\n &.zoom-40 {\r\n font-size: 0.9em;\r\n }\r\n\r\n &.zoom-30 {\r\n font-size: 0.85em;\r\n }\r\n\r\n &.zoom-20 {\r\n font-size: 0.8em;\r\n }\r\n\r\n &.zoom-10 {\r\n font-size: 0.75em;\r\n }\r\n\r\n &.zoom-0 {\r\n font-size: 0.7em;\r\n }\r\n }\r\n}\r\n\r\n.manage-menu {\r\n position: relative;\r\n\r\n .context-menu {\r\n border-left: 4px dotted #000;\r\n width: 1px;\r\n height: 100%;\r\n }\r\n\r\n .context-menu-container {\r\n position: absolute;\r\n display: none;\r\n background: #FFF;\r\n box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.1);\r\n top: 2px;\r\n left: 2px;\r\n\r\n ul {\r\n list-style-type: none;\r\n margin: 0;\r\n padding: 0;\r\n\r\n li {\r\n a {\r\n display: block;\r\n padding: 7px 15px;\r\n white-space: nowrap;\r\n\r\n &:hover {\r\n background: #f8f8f8;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n &:hover {\r\n .context-menu-container {\r\n display: block;\r\n }\r\n }\r\n}\r\n\r\n.wiki-categories {\r\n display: grid;\r\n gap: 10px;\r\n margin-top: 25px;\r\n grid-template-columns: 1fr 1fr 1fr 1fr;\r\n\r\n .category {\r\n background: #FFF;\r\n padding: 10px;\r\n\r\n .users {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr 1fr 1fr;\r\n gap: 5px;\r\n\r\n .user {\r\n display: flex;\r\n height: 25px;\r\n width: 25px;\r\n border-radius: 50%;\r\n background: #ccc;\r\n justify-content: center;\r\n align-items: center;\r\n color: #FFF;\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n .actions {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n\r\n a {\r\n display: block;\r\n color: $cBlack;\r\n font-size: 13px;\r\n text-align: center;\r\n }\r\n }\r\n\r\n .title {\r\n margin-bottom: 5px;\r\n\r\n a {\r\n display: block;\r\n color: $cBlack;\r\n font-size: 13px;\r\n font-weight: 600;\r\n }\r\n }\r\n }\r\n}\r\n\r\n.bootstrap-datetimepicker-widget .picker-switch {\r\n a {\r\n display: block;\r\n color: #000;\r\n }\r\n}\r\n\r\n.gantt_users {\r\n display: flex;\r\n gap: 20px;\r\n}\r\n\r\n#g-results {\r\n background: #FFF;\r\n padding: 25px;\r\n}\r\n\r\n.g-menu-container {\r\n margin-bottom: 15px;\r\n\r\n .right-menu {\r\n display: none;\r\n }\r\n}\r\n\r\n.g-center {\r\n text-align: center;\r\n}\r\n\r\n.alert {\r\n background: $cGreen;\r\n border: 0;\r\n color: #FFF;\r\n}\r\n\r\n.tasks_main_view {\r\n display: flex;\r\n gap: 20px;\r\n\r\n ._left_column {\r\n padding: 25px;\r\n background: #fcfcfc;\r\n border-right: 1px solid #e8e8e8;\r\n width: 350px;\r\n\r\n label {\r\n font-weight: 400;\r\n font-size: 14px;\r\n }\r\n\r\n select[name=\"filtr\"] {\r\n margin-bottom: 10px;\r\n }\r\n\r\n ._buttons {\r\n display: flex;\r\n gap: 10px;\r\n justify-content: space-between;\r\n\r\n .btn {\r\n flex: 1;\r\n }\r\n }\r\n }\r\n\r\n ._right_column {\r\n flex: 1;\r\n max-width: calc(100% - 350px);\r\n }\r\n}\r\n\r\n#billing-summary {\r\n .card-header {\r\n padding: 10px;\r\n }\r\n\r\n .billing-kpi {\r\n border: 1px solid #dee2e6;\r\n border-radius: 6px;\r\n padding: 10px 12px;\r\n background: #ffffff;\r\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\r\n }\r\n\r\n .billing-kpi-label {\r\n font-size: 12px;\r\n color: #6c757d;\r\n margin-bottom: 3px;\r\n }\r\n\r\n .billing-kpi-value {\r\n font-size: 21px;\r\n font-weight: 700;\r\n line-height: 1.1;\r\n }\r\n\r\n .billing-details-row {\r\n display: none;\r\n }\r\n\r\n .billing-client-name {\r\n font-weight: 600;\r\n }\r\n\r\n .billing-table>thead>tr>th {\r\n background: #f8f9fa;\r\n }\r\n\r\n .billing-details-wrap {\r\n background: #f8fbff;\r\n }\r\n}\r\n\r\n/* sidebar submenu */\r\n\r\n/* vacations module */\r\n\r\n.vacation-type-badge {\r\n display: inline-block;\r\n padding: 2px 8px;\r\n border-radius: 4px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n background: #e3f0ff;\r\n color: #2563eb;\r\n\r\n &.type-chorobowe {\r\n background: #fff3e0;\r\n color: #e65100;\r\n }\r\n\r\n &.type-inna_nieobecnosc {\r\n background: #f3e5f5;\r\n color: #7b1fa2;\r\n }\r\n}"]}
\ No newline at end of file
+{"version":3,"sources":["style.scss"],"names":[],"mappings":"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","file":"style.css","sourcesContent":["$cBlue: #6690F4;\r\n$cRed: #cc563d;\r\n$cGreen: #099885;\r\n$cBlack: #4e5e6a;\r\n\r\n.default-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 40px;\r\n border-radius: 6px;\r\n padding: 0 15px;\r\n transition: all .3s ease;\r\n\r\n &:hover {\r\n text-decoration: none;\r\n }\r\n}\r\n\r\n.animate {\r\n animation: mymove 3s infinite;\r\n}\r\n\r\n.text-right {\r\n text-align: right;\r\n}\r\n\r\n.nowrap {\r\n white-space: nowrap;\r\n}\r\n\r\ntable {\r\n border-collapse: collapse;\r\n font-size: 13px;\r\n}\r\n\r\nsmall {\r\n font-size: .75em;\r\n}\r\n\r\n@keyframes mymove {\r\n 50% {\r\n opacity: .33;\r\n }\r\n}\r\n\r\n/* motion */\r\n@keyframes gradient-animation {\r\n 0% {\r\n background-position: 15% 0%;\r\n }\r\n\r\n 50% {\r\n background-position: 85% 100%;\r\n }\r\n\r\n 100% {\r\n background-position: 15% 0%;\r\n }\r\n}\r\n\r\n@keyframes frame-enter {\r\n 0% {\r\n clip-path: polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) calc(100% - 3px), 3px calc(100% - 3px), 3px 100%, 100% 100%, 100% 0%, 0% 0%);\r\n }\r\n\r\n 25% {\r\n clip-path: polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) calc(100% - 3px), calc(100% - 3px) calc(100% - 3px), calc(100% - 3px) 100%, 100% 100%, 100% 0%, 0% 0%);\r\n }\r\n\r\n 50% {\r\n clip-path: polygon(0% 100%, 3px 100%, 3px 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, calc(100% - 3px) 3px, 100% 0%, 0% 0%);\r\n }\r\n\r\n 75% {\r\n -webkit-clip-path: polygon(0% 100%, 3px 100%, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 3px, 3px 0%, 0% 0%);\r\n }\r\n\r\n 100% {\r\n -webkit-clip-path: polygon(0% 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 3px 100%, 0% 100%);\r\n }\r\n}\r\n\r\n* {\r\n box-sizing: border-box;\r\n}\r\n\r\nbody {\r\n font-family: \"Open Sans\", sans-serif;\r\n margin: 0;\r\n padding: 0;\r\n font-size: 15px;\r\n color: #4e5e6a;\r\n}\r\n\r\n.btn {\r\n padding: 9px 25px;\r\n transition: all 0.3s ease;\r\n color: #FFF;\r\n border: 0;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n display: inline-flex;\r\n text-decoration: none;\r\n gap: 5px;\r\n justify-content: center;\r\n align-items: center;\r\n\r\n &.btn_small,\r\n &.btn-xs,\r\n &.btn-sm {\r\n padding: 5px 7px;\r\n font-size: 13px;\r\n\r\n i {\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n &.btn-success {\r\n background: $cGreen;\r\n\r\n &:hover {\r\n background: #4a9c3b;\r\n }\r\n }\r\n\r\n &.btn-primary {\r\n background: $cBlue;\r\n\r\n &:hover {\r\n background: #3164db;\r\n }\r\n }\r\n\r\n &.btn-danger {\r\n background: $cRed;\r\n\r\n &:hover {\r\n background: #b30000;\r\n }\r\n }\r\n}\r\n\r\n.hide {\r\n display: none;\r\n}\r\n\r\n.form-error {\r\n color: $cRed;\r\n font-size: 13px;\r\n}\r\n\r\n.input-group {\r\n margin-bottom: 10px;\r\n}\r\n\r\n.form-field {\r\n margin-bottom: 15px;\r\n\r\n label {\r\n display: block;\r\n font-size: 13px;\r\n font-weight: 600;\r\n margin-bottom: 4px;\r\n color: #4e5e6a;\r\n }\r\n}\r\n\r\n.password-wrap {\r\n position: relative;\r\n\r\n .form-control {\r\n padding-right: 40px;\r\n }\r\n\r\n .password-eye {\r\n position: absolute;\r\n right: 10px;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n color: #999;\r\n text-decoration: none;\r\n z-index: 2;\r\n\r\n &:hover {\r\n color: #333;\r\n }\r\n }\r\n}\r\n\r\ninput[type=\"checkbox\"] {\r\n border: 1px solid #cdcdcd;\r\n}\r\n\r\n.form-control {\r\n border: 1px solid #cdcdcd;\r\n border-radius: 6px;\r\n height: 35px;\r\n width: 100%;\r\n padding: 5px;\r\n font-family: \"Open Sans\", sans-serif;\r\n\r\n option {\r\n padding: 5px;\r\n }\r\n\r\n &:focus {\r\n border: 1px solid $cBlue;\r\n outline: none;\r\n }\r\n}\r\n\r\n.unlogged {\r\n background: #EEF1F9;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 100vh;\r\n\r\n .box-login {\r\n background: #FFF;\r\n padding: 25px;\r\n border-radius: 6px;\r\n width: 400px;\r\n\r\n .title {\r\n text-align: center;\r\n padding: 10px 10px 25px;\r\n border-bottom: 1px solid #cdcdcd;\r\n font-size: 20px;\r\n margin-bottom: 25px;\r\n }\r\n }\r\n}\r\n\r\n$sidebar-width: 220px;\r\n$sidebar-collapsed-width: 60px;\r\n$sidebar-bg: #1e2a3a;\r\n$sidebar-text: #c2c7d0;\r\n$sidebar-active: #fff;\r\n$sidebar-hover-bg: rgba(255, 255, 255, 0.08);\r\n\r\n.sidebar {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: $sidebar-width;\r\n height: 100vh;\r\n background: $sidebar-bg;\r\n display: flex;\r\n flex-direction: column;\r\n z-index: 1000;\r\n transition: width 0.3s ease;\r\n overflow: hidden;\r\n\r\n &.collapsed {\r\n width: $sidebar-collapsed-width;\r\n\r\n .sidebar-header .sidebar-logo span,\r\n .sidebar-nav ul li a span,\r\n .sidebar-footer span,\r\n .sidebar-footer .sidebar-user span {\r\n display: none;\r\n }\r\n\r\n .sidebar-header .sidebar-logo {\r\n font-size: 0;\r\n\r\n &::first-letter {\r\n font-size: 16px;\r\n }\r\n }\r\n\r\n .sidebar-nav ul li a {\r\n justify-content: center;\r\n padding: 10px;\r\n\r\n i {\r\n margin-right: 0;\r\n }\r\n }\r\n\r\n .sidebar-nav ul li.has-submenu {\r\n .submenu-arrow {\r\n display: none;\r\n }\r\n\r\n .sidebar-submenu {\r\n display: none;\r\n }\r\n }\r\n\r\n .sidebar-footer .sidebar-footer-link,\r\n .sidebar-footer .sidebar-user {\r\n justify-content: center;\r\n padding: 8px 10px;\r\n\r\n i {\r\n margin-right: 0;\r\n }\r\n }\r\n }\r\n\r\n .sidebar-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 15px;\r\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\r\n\r\n .sidebar-logo {\r\n color: $cBlue;\r\n text-decoration: none;\r\n font-size: 16px;\r\n white-space: nowrap;\r\n\r\n span {\r\n font-weight: 700;\r\n }\r\n }\r\n\r\n .sidebar-toggle {\r\n cursor: pointer;\r\n color: $sidebar-text;\r\n font-size: 16px;\r\n transition: color 0.2s ease;\r\n\r\n &:hover {\r\n color: #fff;\r\n }\r\n }\r\n }\r\n\r\n .sidebar-nav {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 10px 0;\r\n\r\n ul {\r\n list-style: none;\r\n margin: 0;\r\n padding: 0;\r\n\r\n li {\r\n a {\r\n display: flex;\r\n align-items: center;\r\n padding: 10px 15px;\r\n color: $sidebar-text;\r\n text-decoration: none;\r\n font-size: 14px;\r\n transition: all 0.2s ease;\r\n white-space: nowrap;\r\n\r\n i {\r\n width: 20px;\r\n text-align: center;\r\n margin-right: 10px;\r\n font-size: 15px;\r\n }\r\n\r\n &:hover {\r\n background: $sidebar-hover-bg;\r\n color: $sidebar-active;\r\n }\r\n }\r\n\r\n &.active a {\r\n background: $sidebar-hover-bg;\r\n color: $sidebar-active;\r\n font-weight: 600;\r\n }\r\n\r\n &.has-submenu {\r\n >a .submenu-arrow {\r\n margin-left: auto;\r\n font-size: 12px;\r\n transition: transform 0.2s ease;\r\n width: auto;\r\n }\r\n\r\n &.open>a .submenu-arrow {\r\n transform: rotate(180deg);\r\n }\r\n\r\n .sidebar-submenu {\r\n max-height: 0;\r\n overflow: hidden;\r\n transition: max-height 0.25s ease;\r\n background: rgba(0, 0, 0, 0.15);\r\n\r\n li a {\r\n padding: 8px 15px 8px 45px;\r\n font-size: 13px;\r\n\r\n i {\r\n font-size: 13px;\r\n width: 16px;\r\n }\r\n }\r\n }\r\n\r\n &.open .sidebar-submenu {\r\n max-height: 200px;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n .sidebar-footer {\r\n border-top: 1px solid rgba(255, 255, 255, 0.1);\r\n padding: 10px 0;\r\n\r\n .sidebar-user {\r\n display: flex;\r\n align-items: center;\r\n padding: 8px 15px;\r\n color: $sidebar-text;\r\n font-size: 13px;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n\r\n i {\r\n margin-right: 10px;\r\n color: $cBlue;\r\n }\r\n }\r\n\r\n .sidebar-footer-link {\r\n display: flex;\r\n align-items: center;\r\n padding: 8px 15px;\r\n color: $sidebar-text;\r\n text-decoration: none;\r\n font-size: 13px;\r\n transition: all 0.2s ease;\r\n white-space: nowrap;\r\n\r\n i {\r\n width: 20px;\r\n text-align: center;\r\n margin-right: 10px;\r\n }\r\n\r\n &:hover {\r\n background: $sidebar-hover-bg;\r\n color: $sidebar-active;\r\n }\r\n\r\n &.logout {\r\n color: $cRed;\r\n\r\n &:hover {\r\n color: #e07a66;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n.content-wrapper {\r\n margin-left: $sidebar-width;\r\n min-height: 100vh;\r\n transition: margin-left 0.3s ease;\r\n\r\n &.expanded {\r\n margin-left: $sidebar-collapsed-width;\r\n }\r\n}\r\n\r\n.top-bar {\r\n background: #fff;\r\n border-bottom: 1px solid #e8e8e8;\r\n padding: 10px 20px;\r\n display: flex;\r\n align-items: center;\r\n\r\n .top-bar-left {\r\n display: flex;\r\n align-items: center;\r\n gap: 15px;\r\n\r\n i {\r\n cursor: pointer;\r\n font-size: 18px;\r\n color: #4e5e6a;\r\n\r\n &:hover {\r\n color: #000;\r\n }\r\n }\r\n }\r\n}\r\n\r\n.main {\r\n padding: 25px;\r\n background: #D9DEE2;\r\n min-height: calc(100vh - 45px);\r\n}\r\n\r\n.tasks_container {\r\n display: grid;\r\n grid-template-columns: repeat(5, 1fr);\r\n gap: 20px;\r\n\r\n .column {\r\n width: 100%;\r\n\r\n h2 {\r\n display: flex;\r\n padding: 10px;\r\n background: #FFF;\r\n margin-bottom: 10px;\r\n font-size: 15px;\r\n font-weight: 300;\r\n border-radius: 3px 3px 0 0;\r\n justify-content: space-between;\r\n align-items: center;\r\n\r\n i {\r\n cursor: pointer;\r\n }\r\n }\r\n\r\n &.tasks_suspended {\r\n h2 {\r\n border-bottom: 5px solid $cRed;\r\n }\r\n }\r\n\r\n &.tasks_fvat {\r\n h2 {\r\n border-bottom: 5px solid #a900fc;\r\n }\r\n }\r\n\r\n &.tasks_new {\r\n h2 {\r\n border-bottom: 5px solid #ccc;\r\n }\r\n }\r\n\r\n &.tasks_bulk {\r\n h2 {\r\n border-bottom: 5px solid #ff8c00;\r\n }\r\n }\r\n\r\n &.tasks_to_do {\r\n h2 {\r\n border-bottom: 5px solid #2aaf47;\r\n }\r\n }\r\n\r\n &.tasks_to_review {\r\n h2 {\r\n border-bottom: 5px solid #2535c9;\r\n }\r\n }\r\n\r\n &.tasks_closed {\r\n h2 {\r\n border-bottom: 5px solid #000;\r\n }\r\n }\r\n\r\n ul {\r\n list-style-type: none;\r\n margin: 0;\r\n padding: 0;\r\n\r\n .task {\r\n margin-bottom: 5px;\r\n background: #FFF;\r\n padding: 10px;\r\n border-radius: 0;\r\n display: flex;\r\n position: relative;\r\n border-radius: 6px;\r\n flex-wrap: wrap;\r\n\r\n &.notopened {\r\n border: 2px solid $cRed;\r\n }\r\n\r\n .top {\r\n display: flex;\r\n justify-content: space-between;\r\n margin-bottom: 5px;\r\n width: 100%;\r\n\r\n ._users {\r\n display: flex;\r\n gap: 5px;\r\n flex-wrap: wrap;\r\n\r\n .user {\r\n display: flex;\r\n width: 25px;\r\n height: 25px;\r\n border-radius: 6px;\r\n justify-content: center;\r\n align-items: center;\r\n color: #FFF;\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n ._timer {\r\n display: flex;\r\n gap: 5px;\r\n\r\n .recursively {\r\n color: #FFF;\r\n background: #405189;\r\n border-radius: 3px;\r\n cursor: pointer;\r\n margin-bottom: 5px;\r\n width: 25px;\r\n height: 25px;\r\n text-align: center;\r\n display: block;\r\n\r\n i {\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n .task_start {\r\n display: block;\r\n background: $cGreen;\r\n color: #FFF;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n margin-bottom: 5px;\r\n width: 25px;\r\n height: 25px;\r\n text-align: center;\r\n\r\n &.hidden {\r\n display: none;\r\n }\r\n\r\n i {\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n .task_end {\r\n background: $cRed;\r\n display: block;\r\n color: #FFF;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n margin-bottom: 5px;\r\n width: 25px;\r\n height: 25px;\r\n text-align: center;\r\n\r\n &.hidden {\r\n display: none;\r\n }\r\n\r\n i {\r\n font-size: 12px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .middle {\r\n width: 100%;\r\n }\r\n\r\n .name {\r\n font-size: 14px;\r\n color: #333;\r\n text-decoration: none;\r\n display: block;\r\n margin-bottom: 5px;\r\n }\r\n\r\n .bottom {\r\n display: flex;\r\n justify-content: space-between;\r\n }\r\n\r\n .client_info,\r\n .current_status {\r\n font-size: 12px;\r\n font-weight: 400;\r\n\r\n strong {\r\n font-weight: 600;\r\n }\r\n }\r\n\r\n .current_status {\r\n position: relative;\r\n cursor: pointer;\r\n\r\n .status_change {\r\n position: absolute;\r\n left: 0;\r\n top: 20px;\r\n background: #fff;\r\n padding: 15px;\r\n border: 1px solid #dfdfdf;\r\n border-radius: 3px;\r\n cursor: pointer;\r\n box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);\r\n z-index: 99;\r\n display: none;\r\n\r\n select {\r\n width: 250px;\r\n padding: 10px;\r\n border: 1px solid #cdcdcd;\r\n border-radius: 3px;\r\n\r\n option {\r\n font-size: 15px;\r\n padding: 3px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .dates {\r\n margin-bottom: 5px;\r\n display: flex;\r\n justify-content: space-between;\r\n font-size: 12px;\r\n\r\n .danger {\r\n color: $cRed;\r\n font-weight: 600;\r\n }\r\n\r\n .warning {\r\n color: #ff8c00;\r\n }\r\n\r\n i {\r\n font-size: 12px;\r\n color: #C9CED4;\r\n margin-right: 5px;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n/* page header */\r\n.block-header {\r\n margin-bottom: 20px;\r\n\r\n h2 {\r\n font-size: 20px;\r\n font-weight: 400;\r\n color: $cBlack;\r\n margin: 0;\r\n padding-bottom: 12px;\r\n border-bottom: 2px solid #e2e6ec;\r\n\r\n strong {\r\n font-weight: 700;\r\n }\r\n }\r\n}\r\n\r\n/* filters bar — reusable across modules */\r\n.filters-bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 10px;\r\n flex-wrap: wrap;\r\n margin-bottom: 24px;\r\n padding: 12px 16px;\r\n background: #f5f7fa;\r\n border-radius: 8px;\r\n border: 1px solid #e2e6ec;\r\n\r\n select,\r\n input[type=\"text\"],\r\n input[type=\"date\"],\r\n input[type=\"number\"] {\r\n height: 36px;\r\n min-width: 170px;\r\n padding: 0 10px;\r\n border: 1px solid #d0d5dd;\r\n border-radius: 6px;\r\n background: #fff;\r\n font-size: 13px;\r\n color: $cBlack;\r\n font-family: \"Open Sans\", sans-serif;\r\n transition: border-color 0.2s;\r\n\r\n &:focus {\r\n border-color: $cBlue;\r\n outline: none;\r\n }\r\n }\r\n\r\n .btn {\r\n height: 36px;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 5px;\r\n padding: 0 14px;\r\n border-radius: 6px;\r\n font-size: 13px;\r\n font-weight: 500;\r\n border: none;\r\n cursor: pointer;\r\n transition: background 0.2s, box-shadow 0.2s;\r\n text-decoration: none;\r\n color: #fff;\r\n\r\n &.btn-primary {\r\n background: $cBlue;\r\n\r\n &:hover {\r\n background: #4a74d4;\r\n }\r\n }\r\n\r\n &.btn-success {\r\n background: $cGreen;\r\n\r\n &:hover {\r\n background: #077a6b;\r\n }\r\n }\r\n }\r\n}\r\n\r\n/* section title — reusable */\r\n.section-title {\r\n font-size: 14px;\r\n font-weight: 600;\r\n color: $cBlack;\r\n margin: 28px 0 12px;\r\n padding-bottom: 8px;\r\n border-bottom: 1px solid #e2e6ec;\r\n}\r\n\r\n.action_menu {\r\n display: flex;\r\n margin-bottom: 25px;\r\n gap: 20px;\r\n\r\n .btn {\r\n display: inline-flex;\r\n padding: 7px 15px;\r\n color: #FFF;\r\n text-decoration: none;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 5px;\r\n\r\n &.btn_add {\r\n background: $cGreen;\r\n\r\n &:hover {\r\n background: #4a9c3b;\r\n }\r\n }\r\n\r\n &.btn_cancel {\r\n background: $cRed;\r\n\r\n &:hover {\r\n background: #b30000;\r\n }\r\n }\r\n\r\n &.disabled {\r\n opacity: .5;\r\n }\r\n }\r\n}\r\n\r\n.form_container {\r\n background: #FFF;\r\n padding: 25px;\r\n max-width: 1300px;\r\n\r\n &.full {\r\n max-width: 100%;\r\n }\r\n\r\n .form_group {\r\n margin-bottom: 10px;\r\n display: flex;\r\n\r\n >.label {\r\n width: 300px;\r\n display: inline-flex;\r\n align-items: flex-start;\r\n justify-content: right;\r\n padding-right: 10px;\r\n }\r\n\r\n .input {\r\n width: calc(100% - 300px);\r\n }\r\n }\r\n}\r\n\r\n.fullscreen_description {\r\n position: fixed !important;\r\n top: 25px;\r\n left: 25px;\r\n right: 25px;\r\n bottom: 25px;\r\n z-index: 9999;\r\n background: white;\r\n padding: 20px;\r\n overflow: auto;\r\n border-radius: 0.25rem;\r\n box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);\r\n}\r\n\r\n.fullscreen {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n cursor: pointer;\r\n color: #FFF;\r\n background: $cRed;\r\n display: inline-flex;\r\n height: 40px;\r\n width: 40px;\r\n border-radius: 6px;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.3s ease;\r\n\r\n &:hover {\r\n transform: scale(1.05);\r\n text-decoration: none;\r\n }\r\n}\r\n\r\n.task_popup {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background: rgba(0, 0, 0, 0.5);\r\n display: none;\r\n z-index: 9999;\r\n\r\n .task_details {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n background: #FFF;\r\n padding: 25px;\r\n border-radius: 6px;\r\n max-width: 1140px;\r\n width: 100%;\r\n transition: all 0.3s ease;\r\n height: 90vh;\r\n\r\n .content {\r\n height: calc(100% - 50px);\r\n }\r\n\r\n &.open_works_time {\r\n max-width: 1540px;\r\n\r\n .content {\r\n grid-template-columns: 1fr 300px 350px;\r\n\r\n .task_work_details {\r\n display: block;\r\n }\r\n }\r\n }\r\n\r\n .title {\r\n font-size: 20px;\r\n margin-bottom: 25px;\r\n display: flex;\r\n align-items: center;\r\n gap: 10px;\r\n\r\n a {\r\n border: 1px solid $cGreen;\r\n display: inline-flex;\r\n height: 30px;\r\n width: 30px;\r\n border-radius: 6px;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n &:hover {\r\n text-decoration: none;\r\n }\r\n\r\n i {\r\n color: $cGreen;\r\n }\r\n\r\n &.task-delete {\r\n border: 1px solid $cRed;\r\n\r\n i {\r\n color: $cRed;\r\n }\r\n }\r\n\r\n i {\r\n font-size: 14px;\r\n }\r\n }\r\n\r\n .task-title-edit-box {\r\n align-items: center;\r\n gap: 6px;\r\n\r\n .task-title-input {\r\n height: 30px;\r\n font-size: 14px;\r\n padding: 2px 8px;\r\n width: 300px;\r\n border: 1px solid #ccc;\r\n border-radius: 4px;\r\n }\r\n\r\n a.task-title-save,\r\n a.task-title-cancel {\r\n height: 30px;\r\n width: 30px;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: 6px;\r\n\r\n i {\r\n font-size: 13px;\r\n }\r\n }\r\n\r\n a.task-title-save {\r\n background: $cGreen;\r\n border-color: $cGreen;\r\n\r\n i {\r\n color: #fff;\r\n }\r\n }\r\n\r\n a.task-title-cancel {\r\n background: $cRed;\r\n border-color: $cRed;\r\n\r\n i {\r\n color: #fff;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .close {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n cursor: pointer;\r\n }\r\n\r\n .content {\r\n display: grid;\r\n font-size: 14px;\r\n grid-template-columns: 1fr 300px;\r\n gap: 30px;\r\n transition: all 0.3s ease;\r\n\r\n h3 {\r\n width: 100%;\r\n margin-top: 0;\r\n margin-bottom: 5px;\r\n font-weight: 500;\r\n color: #000;\r\n font-size: 17px;\r\n }\r\n\r\n .left {\r\n height: 100%;\r\n overflow: hidden;\r\n\r\n .users {\r\n display: flex;\r\n gap: 20px;\r\n\r\n .user {\r\n display: flex;\r\n gap: 10px;\r\n align-items: center;\r\n margin-bottom: 10px;\r\n\r\n .avatar {\r\n height: 30px;\r\n width: 30px;\r\n border-radius: 6px;\r\n background: #ccc;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n color: #FFF;\r\n font-size: 12px;\r\n }\r\n }\r\n }\r\n\r\n .comments {\r\n border-radius: 3px;\r\n max-height: 406px;\r\n overflow-y: auto;\r\n\r\n .new_comment {\r\n margin-bottom: 10px;\r\n\r\n textarea {\r\n height: 75px;\r\n margin-bottom: 10px;\r\n border-radius: 6px;\r\n }\r\n\r\n .add_comment {\r\n background: $cGreen;\r\n color: #FFF;\r\n padding: 10px;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 200px;\r\n text-decoration: none;\r\n\r\n &:hover {\r\n background: #4a9c3b;\r\n }\r\n }\r\n }\r\n\r\n ul {\r\n margin: 0;\r\n padding: 0;\r\n list-style-type: none;\r\n\r\n li {\r\n background: #ced4da;\r\n margin-bottom: 5px;\r\n padding: 15px;\r\n border-radius: 6px;\r\n position: relative;\r\n\r\n .delete_comment {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n cursor: pointer;\r\n color: $cRed;\r\n }\r\n\r\n .author {\r\n font-weight: 600;\r\n margin-bottom: 5px;\r\n display: inline-flex;\r\n margin-right: 10px;\r\n }\r\n\r\n .date {\r\n font-size: 12px;\r\n margin-bottom: 5px;\r\n display: inline-flex;\r\n }\r\n\r\n .text {\r\n margin-bottom: 15px;\r\n font-size: 13px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .checklist {\r\n border-radius: 3px;\r\n margin-bottom: 10px;\r\n\r\n .new_element {\r\n display: flex;\r\n margin-bottom: 10px;\r\n\r\n input {\r\n border-radius: 6px 0 0 6px;\r\n }\r\n\r\n a {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 10px;\r\n border-radius: 0 6px 6px 0;\r\n text-decoration: none;\r\n width: 35px;\r\n background: $cGreen;\r\n color: #FFF;\r\n }\r\n }\r\n\r\n ul {\r\n margin: 0;\r\n padding: 0;\r\n list-style-type: none;\r\n overflow-y: auto;\r\n max-height: calc(90vh - 400px);\r\n\r\n li {\r\n display: flex;\r\n gap: 10px;\r\n margin-bottom: 5px;\r\n background: #FFF;\r\n border-radius: 3px;\r\n padding: 10px;\r\n border: 1px solid #cdcdcd;\r\n font-size: 13px;\r\n align-items: flex-start;\r\n\r\n a {\r\n margin-left: auto;\r\n margin-right: 0;\r\n cursor: pointer;\r\n background: $cRed;\r\n display: flex;\r\n height: 25px;\r\n width: 25px;\r\n min-width: 25px;\r\n justify-content: center;\r\n align-items: center;\r\n border: 0;\r\n border-radius: 3px;\r\n transition: all 0.3s ease;\r\n\r\n &:hover {\r\n text-decoration: none;\r\n background: #b30000;\r\n }\r\n\r\n i {\r\n color: #FFF;\r\n font-size: 12px;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n .attachments {\r\n margin-top: 10px;\r\n border: 1px solid #e6e9ed;\r\n border-radius: 8px;\r\n padding: 12px;\r\n background: #f9fbfd;\r\n\r\n h3 {\r\n margin-bottom: 10px;\r\n font-size: 16px;\r\n font-weight: 600;\r\n }\r\n\r\n .attachments_upload {\r\n display: flex;\r\n gap: 10px;\r\n align-items: center;\r\n margin-bottom: 10px;\r\n\r\n .attachment_file_input {\r\n flex: 1;\r\n margin-bottom: 0;\r\n border-radius: 6px;\r\n background: #fff;\r\n }\r\n\r\n .attachment-upload-btn {\r\n white-space: nowrap;\r\n border-radius: 6px;\r\n min-width: 150px;\r\n\r\n &.is-loading {\r\n pointer-events: none;\r\n opacity: 0.85;\r\n\r\n i {\r\n margin-right: 6px;\r\n }\r\n }\r\n }\r\n }\r\n\r\n .attachments_list {\r\n margin: 0;\r\n padding: 0;\r\n list-style: none;\r\n display: grid;\r\n gap: 8px;\r\n max-height: 180px;\r\n overflow-y: auto;\r\n\r\n li {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n background: #fff;\r\n border: 1px solid #e4e8ee;\r\n border-radius: 6px;\r\n padding: 8px 10px;\r\n\r\n .attachment-link {\r\n color: #1f3d72;\r\n text-decoration: none;\r\n font-weight: 600;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n max-width: calc(100% - 140px);\r\n\r\n &:hover {\r\n text-decoration: underline;\r\n }\r\n }\r\n\r\n small {\r\n color: #6b7280;\r\n margin-right: auto;\r\n }\r\n\r\n .attachment-rename,\r\n .attachment-delete {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n height: 28px;\r\n width: 28px;\r\n border-radius: 4px;\r\n text-decoration: none;\r\n transition: all 0.2s ease;\r\n }\r\n\r\n .attachment-rename {\r\n border: 1px solid #d8e2f6;\r\n color: $cBlue;\r\n background: #f4f8ff;\r\n\r\n &:hover {\r\n background: #e7f0ff;\r\n }\r\n }\r\n\r\n .attachment-delete {\r\n border: 1px solid #f1d3d1;\r\n color: $cRed;\r\n background: #fff6f6;\r\n\r\n &:hover {\r\n background: #ffeaea;\r\n }\r\n }\r\n }\r\n\r\n .attachments-empty {\r\n color: #6b7280;\r\n border-style: dashed;\r\n justify-content: center;\r\n font-size: 13px;\r\n }\r\n }\r\n }\r\n\r\n .description {\r\n padding: 15px;\r\n border-radius: 0.25rem;\r\n border: 1px solid #cdcdcd;\r\n margin-bottom: 15px;\r\n max-height: 202px;\r\n overflow-x: hidden;\r\n position: relative;\r\n }\r\n }\r\n\r\n .right {\r\n\r\n .box {\r\n margin-bottom: 15px;\r\n }\r\n\r\n .time {\r\n a.time_worked_toggle {\r\n @extend .default-btn;\r\n color: #299cdb;\r\n display: inline-flex;\r\n border: 1px solid #299cdb;\r\n\r\n &:hover {\r\n background: #dff0fa;\r\n text-decoration: none;\r\n }\r\n\r\n &:active,\r\n &:focus {\r\n text-decoration: none;\r\n }\r\n }\r\n\r\n a:not(.time_worked_toggle) {\r\n @extend .default-btn;\r\n margin-top: 10px;\r\n text-decoration: none;\r\n gap: 10px;\r\n\r\n &.task_start {\r\n background: #0ab39c;\r\n color: #FFF;\r\n\r\n &:hover {\r\n background: #099885;\r\n }\r\n }\r\n\r\n &.task_end {\r\n background: $cRed;\r\n color: #FFF;\r\n }\r\n\r\n &.hidden {\r\n display: none;\r\n }\r\n }\r\n }\r\n\r\n .dates {\r\n display: flex;\r\n justify-content: space-between;\r\n flex-wrap: wrap;\r\n\r\n .danger {\r\n color: $cRed;\r\n font-weight: 600;\r\n }\r\n\r\n .warning {\r\n color: #ff8c00;\r\n }\r\n\r\n i {\r\n color: #C9CED4;\r\n margin-right: 5px;\r\n }\r\n }\r\n }\r\n\r\n .task_work_details {\r\n display: none;\r\n overflow-y: auto;\r\n max-height: 508px;\r\n width: 100%;\r\n padding-right: 10px;\r\n padding-top: 4px;\r\n\r\n ._line {\r\n display: flex;\r\n flex-wrap: wrap;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 5px;\r\n\r\n ._user {\r\n width: 100%;\r\n font-size: 13px;\r\n }\r\n\r\n input {\r\n width: calc(50% - 25px);\r\n text-align: center;\r\n margin-left: 2px;\r\n margin-right: 2px;\r\n }\r\n }\r\n\r\n ._work_delete {\r\n display: inline-flex;\r\n height: 35px;\r\n width: 35px;\r\n border-radius: 6px;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n border: 1px solid $cRed;\r\n margin-left: 2px;\r\n transition: all 0.3s ease;\r\n\r\n &:hover {\r\n background: $cRed;\r\n\r\n i {\r\n color: #FFF;\r\n }\r\n }\r\n\r\n i {\r\n transition: all 0.3s ease;\r\n color: $cRed;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n.table {\r\n width: 100%;\r\n border: none;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);\r\n background: #fff;\r\n\r\n th,\r\n td {\r\n padding: 10px 14px;\r\n border: none;\r\n border-bottom: 1px solid #eef0f3;\r\n text-align: left;\r\n vertical-align: middle;\r\n }\r\n\r\n thead th {\r\n background: #f5f7fa;\r\n color: #4e5e6a;\r\n font-weight: 600;\r\n font-size: 12px;\r\n text-transform: uppercase;\r\n letter-spacing: 0.3px;\r\n white-space: nowrap;\r\n border-bottom: 2px solid #e2e6ec;\r\n }\r\n\r\n tbody tr {\r\n transition: background 0.15s ease;\r\n\r\n &:last-child td {\r\n border-bottom: none;\r\n }\r\n\r\n &:hover {\r\n background: #f8fafd;\r\n }\r\n }\r\n\r\n td.center,\r\n th.center {\r\n text-align: center;\r\n }\r\n\r\n td.left,\r\n th.left {\r\n text-align: left;\r\n }\r\n\r\n td.right,\r\n th.right {\r\n text-align: right;\r\n }\r\n\r\n // empty state\r\n td[colspan] {\r\n text-align: center;\r\n color: #8896a4;\r\n padding: 24px 14px;\r\n font-style: italic;\r\n }\r\n}\r\n\r\n.projects_container {\r\n background: #FFF;\r\n padding: 15px;\r\n border-radius: 6px;\r\n display: flex;\r\n gap: 20px;\r\n\r\n .left {\r\n width: calc(100% - 250px);\r\n\r\n ._projects,\r\n ._users {\r\n display: flex;\r\n gap: 20px;\r\n flex-wrap: wrap;\r\n }\r\n }\r\n\r\n .right {\r\n width: 250px;\r\n display: flex;\r\n flex-wrap: wrap;\r\n align-items: flex-start;\r\n justify-content: center;\r\n gap: 20px;\r\n border-left: 1px solid #cdcdcd;\r\n padding-left: 15px;\r\n\r\n select {\r\n width: 200px;\r\n }\r\n }\r\n}\r\n\r\n.default_popup {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background: rgba(0, 0, 0, 0.5);\r\n display: none;\r\n\r\n .popup_content {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n background: #FFF;\r\n padding: 25px;\r\n border-radius: 0;\r\n max-width: 1140px;\r\n width: 100%;\r\n\r\n .close {\r\n position: absolute;\r\n top: 10px;\r\n right: 10px;\r\n cursor: pointer;\r\n }\r\n }\r\n}\r\n\r\n#fg-cron {\r\n margin: 10px 0;\r\n\r\n .countdown {\r\n background: $cGreen;\r\n color: #FFF;\r\n padding: 10px;\r\n }\r\n\r\n #cron-container {\r\n max-height: 300px;\r\n overflow-x: hidden;\r\n overflow-y: auto;\r\n\r\n .msg {\r\n font-size: 13px;\r\n padding: 5px;\r\n border-bottom: 1px solid #e8e8e8;\r\n }\r\n }\r\n}\r\n\r\n.card {\r\n background: #FFF;\r\n padding: 25px;\r\n border-radius: 6px;\r\n color: #000;\r\n font-size: 15px;\r\n max-width: 1280px;\r\n\r\n &.mb25 {\r\n margin-bottom: 25px;\r\n }\r\n\r\n .card-header {\r\n font-weight: 600;\r\n }\r\n\r\n .card-body {\r\n padding-top: 10px;\r\n\r\n table {\r\n border-collapse: collapse;\r\n\r\n th,\r\n td {\r\n font-size: 14px;\r\n\r\n &.bold {\r\n font-weight: 600;\r\n }\r\n\r\n &.text-right {\r\n text-align: right;\r\n }\r\n\r\n &.text-center {\r\n text-align: center;\r\n }\r\n\r\n .close-task {\r\n text-decoration: none;\r\n color: $cBlue;\r\n\r\n &:hover {\r\n color: $cRed;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\n.finance-summary {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr 1fr 1fr;\r\n gap: 10px;\r\n\r\n .panel {\r\n background: #FFF;\r\n border-radius: 6px;\r\n padding: 15px;\r\n\r\n h1 {\r\n font-size: 20px;\r\n margin: 0;\r\n }\r\n\r\n span {\r\n font-size: 0.85em;\r\n }\r\n }\r\n}\r\n\r\n.finance-manager {\r\n display: grid;\r\n gap: 10px;\r\n grid-template-columns: 250px 1fr 500px;\r\n padding-top: 25px;\r\n\r\n .manage-menu {\r\n display: inline-block;\r\n margin-right: 10px;\r\n\r\n a {\r\n color: #333333;\r\n text-decoration: none;\r\n font-weight: 300;\r\n display: block;\r\n }\r\n }\r\n\r\n .actions {\r\n width: 100px;\r\n text-align: center;\r\n\r\n a {\r\n display: inline-flex;\r\n margin: 0 2px;\r\n height: 25px;\r\n width: 25px;\r\n align-items: center;\r\n justify-content: center;\r\n text-decoration: none;\r\n color: #000;\r\n border: 1px solid #e7e7e7;\r\n font-size: 11px;\r\n border-radius: 3px;\r\n transition: all 0.3s ease;\r\n\r\n &:hover {\r\n border: 1px solid $cBlue;\r\n }\r\n }\r\n }\r\n}\r\n\r\n.bootstrap-tagsinput {\r\n .tag {\r\n background: $cBlue;\r\n font-size: 13px;\r\n padding: 5px 10px;\r\n border-radius: 12px;\r\n\r\n [data-role=\"remove\"] {\r\n color: #FFF !important;\r\n\r\n &:hover {\r\n box-shadow: none !important;\r\n color: #000 !important\r\n }\r\n }\r\n }\r\n}\r\n\r\n.finance-tags {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 5px;\r\n\r\n a:not(.btn) {\r\n display: flex;\r\n width: 100%;\r\n text-decoration: none;\r\n color: $cBlack;\r\n\r\n &.zoom-100 {\r\n font-size: 1.2em;\r\n }\r\n\r\n &.zoom-90 {\r\n font-size: 1.15em;\r\n }\r\n\r\n &.zoom-80 {\r\n font-size: 1.1em;\r\n }\r\n\r\n &.zoom-70 {\r\n font-size: 1.05em;\r\n }\r\n\r\n &.zoom-60 {\r\n font-size: 1em;\r\n }\r\n\r\n &.zoom-50 {\r\n font-size: 0.95em;\r\n }\r\n\r\n &.zoom-40 {\r\n font-size: 0.9em;\r\n }\r\n\r\n &.zoom-30 {\r\n font-size: 0.85em;\r\n }\r\n\r\n &.zoom-20 {\r\n font-size: 0.8em;\r\n }\r\n\r\n &.zoom-10 {\r\n font-size: 0.75em;\r\n }\r\n\r\n &.zoom-0 {\r\n font-size: 0.7em;\r\n }\r\n }\r\n}\r\n\r\n.manage-menu {\r\n position: relative;\r\n\r\n .context-menu {\r\n border-left: 4px dotted #000;\r\n width: 1px;\r\n height: 100%;\r\n }\r\n\r\n .context-menu-container {\r\n position: absolute;\r\n display: none;\r\n background: #FFF;\r\n box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.1);\r\n top: 2px;\r\n left: 2px;\r\n\r\n ul {\r\n list-style-type: none;\r\n margin: 0;\r\n padding: 0;\r\n\r\n li {\r\n a {\r\n display: block;\r\n padding: 7px 15px;\r\n white-space: nowrap;\r\n\r\n &:hover {\r\n background: #f8f8f8;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n &:hover {\r\n .context-menu-container {\r\n display: block;\r\n }\r\n }\r\n}\r\n\r\n.wiki-categories {\r\n display: grid;\r\n gap: 10px;\r\n margin-top: 25px;\r\n grid-template-columns: 1fr 1fr 1fr 1fr;\r\n\r\n .category {\r\n background: #FFF;\r\n padding: 10px;\r\n\r\n .users {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr 1fr 1fr;\r\n gap: 5px;\r\n\r\n .user {\r\n display: flex;\r\n height: 25px;\r\n width: 25px;\r\n border-radius: 50%;\r\n background: #ccc;\r\n justify-content: center;\r\n align-items: center;\r\n color: #FFF;\r\n font-size: 12px;\r\n }\r\n }\r\n\r\n .actions {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n\r\n a {\r\n display: block;\r\n color: $cBlack;\r\n font-size: 13px;\r\n text-align: center;\r\n }\r\n }\r\n\r\n .title {\r\n margin-bottom: 5px;\r\n\r\n a {\r\n display: block;\r\n color: $cBlack;\r\n font-size: 13px;\r\n font-weight: 600;\r\n }\r\n }\r\n }\r\n}\r\n\r\n.bootstrap-datetimepicker-widget .picker-switch {\r\n a {\r\n display: block;\r\n color: #000;\r\n }\r\n}\r\n\r\n.gantt_users {\r\n display: flex;\r\n gap: 20px;\r\n}\r\n\r\n#g-results {\r\n background: #FFF;\r\n padding: 25px;\r\n}\r\n\r\n.g-menu-container {\r\n margin-bottom: 15px;\r\n\r\n .right-menu {\r\n display: none;\r\n }\r\n}\r\n\r\n.g-center {\r\n text-align: center;\r\n}\r\n\r\n.alert {\r\n background: $cGreen;\r\n border: 0;\r\n color: #FFF;\r\n}\r\n\r\n.tasks_main_view {\r\n display: flex;\r\n gap: 20px;\r\n align-items: flex-start;\r\n\r\n ._left_column {\r\n width: fit-content;\r\n min-width: 350px;\r\n max-width: 520px;\r\n padding: 0;\r\n background: transparent;\r\n border-right: 0;\r\n\r\n .filters_panel {\r\n background: linear-gradient(180deg, #fdfefe 0%, #f4f7fb 100%);\r\n border: 1px solid #dbe2ea;\r\n border-radius: 12px;\r\n padding: 16px;\r\n box-shadow: none;\r\n }\r\n\r\n .filters_panel_header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n margin-bottom: 14px;\r\n }\r\n\r\n .filters_panel_title {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n\r\n i {\r\n color: #1f3d72;\r\n }\r\n\r\n h3 {\r\n margin: 0;\r\n font-size: 16px;\r\n font-weight: 700;\r\n color: #1f3d72;\r\n }\r\n }\r\n\r\n .active_filters_badge {\r\n display: inline-flex;\r\n align-items: center;\r\n padding: 4px 10px;\r\n border-radius: 999px;\r\n font-size: 12px;\r\n color: #425466;\r\n background: #e9eff8;\r\n\r\n strong {\r\n margin-left: 4px;\r\n font-size: 13px;\r\n color: #1f3d72;\r\n }\r\n }\r\n\r\n .filters_controls {\r\n margin-bottom: 14px;\r\n padding: 12px;\r\n border-radius: 10px;\r\n border: 1px solid #dbe2ea;\r\n background: #fff;\r\n }\r\n\r\n .filters_label {\r\n display: block;\r\n margin-bottom: 6px;\r\n font-size: 12px;\r\n font-weight: 600;\r\n color: #425466;\r\n }\r\n\r\n select[name=\"filtr\"] {\r\n margin-bottom: 12px;\r\n height: 40px;\r\n border-color: #d1dae4;\r\n\r\n &:focus {\r\n border-color: #5f88e9;\r\n box-shadow: 0 0 0 3px rgba(95, 136, 233, 0.15);\r\n }\r\n }\r\n\r\n ._buttons {\r\n display: flex;\r\n gap: 8px;\r\n\r\n .btn {\r\n flex: 1;\r\n min-height: 34px;\r\n font-size: 12px;\r\n text-transform: uppercase;\r\n letter-spacing: 0.3px;\r\n }\r\n\r\n .btn-dark {\r\n background: #3d495e;\r\n\r\n &:hover {\r\n background: #2f394c;\r\n }\r\n }\r\n }\r\n\r\n .filters_section {\r\n border: 1px solid #dbe2ea;\r\n border-radius: 10px;\r\n background: #fff;\r\n margin-bottom: 12px;\r\n overflow: hidden;\r\n }\r\n\r\n .filters_section_header {\r\n display: flex;\r\n gap: 8px;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 10px 12px;\r\n background: #f4f7fb;\r\n border-bottom: 1px solid #e3eaf2;\r\n\r\n h4 {\r\n margin: 0;\r\n font-size: 14px;\r\n font-weight: 700;\r\n color: #243447;\r\n }\r\n\r\n .filters_search {\r\n max-width: 170px;\r\n height: 32px;\r\n font-size: 12px;\r\n padding: 4px 10px;\r\n border-color: #d2dbe6;\r\n }\r\n }\r\n\r\n .filters_section_list {\r\n max-height: 270px;\r\n overflow-y: auto;\r\n padding: 6px;\r\n }\r\n\r\n .filters_section._projects .filters_section_list {\r\n max-height: none;\r\n overflow: visible;\r\n }\r\n\r\n .filters_item {\r\n border-radius: 8px;\r\n transition: background 0.2s ease;\r\n\r\n &:hover {\r\n background: #f4f7fb;\r\n }\r\n }\r\n\r\n .project_row,\r\n ._user {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 8px;\r\n padding: 5px 7px;\r\n\r\n label {\r\n margin: 0;\r\n flex: 1;\r\n font-weight: 400;\r\n font-size: 14px;\r\n white-space: nowrap;\r\n }\r\n }\r\n\r\n .project_count {\r\n display: inline-block;\r\n margin-left: 4px;\r\n min-width: 26px;\r\n padding: 0 7px;\r\n border-radius: 999px;\r\n background: #1f3d72;\r\n color: #fff;\r\n font-weight: 700;\r\n font-size: 11px;\r\n line-height: 19px;\r\n text-align: center;\r\n vertical-align: middle;\r\n }\r\n\r\n .project_delete_inline {\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 20px;\r\n height: 20px;\r\n border-radius: 5px;\r\n border: 1px solid #cc563d;\r\n background: #cc563d;\r\n color: #fff;\r\n text-decoration: none;\r\n transition: all 0.2s ease;\r\n margin: 1px 0;\r\n\r\n &:hover {\r\n background: #b74831;\r\n border-color: #b74831;\r\n }\r\n\r\n i {\r\n font-size: 10px;\r\n }\r\n }\r\n }\r\n\r\n ._right_column {\r\n flex: 1;\r\n max-width: none;\r\n min-width: 0;\r\n }\r\n}\r\n\r\n@media (max-width: 1200px) {\r\n .tasks_main_view {\r\n flex-direction: column;\r\n\r\n ._left_column,\r\n ._right_column {\r\n max-width: 100%;\r\n width: 100%;\r\n }\r\n }\r\n}\r\n\r\n.gantt-target {\r\n .gantt-container.gantt-draggable {\r\n cursor: grab;\r\n }\r\n\r\n .gantt-container.gantt-dragging {\r\n cursor: grabbing;\r\n }\r\n}\r\n\r\n#billing-summary {\r\n .card-header {\r\n padding: 10px;\r\n }\r\n\r\n .billing-kpi {\r\n border: 1px solid #dee2e6;\r\n border-radius: 6px;\r\n padding: 10px 12px;\r\n background: #ffffff;\r\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\r\n }\r\n\r\n .billing-kpi-label {\r\n font-size: 12px;\r\n color: #6c757d;\r\n margin-bottom: 3px;\r\n }\r\n\r\n .billing-kpi-value {\r\n font-size: 21px;\r\n font-weight: 700;\r\n line-height: 1.1;\r\n }\r\n\r\n .billing-details-row {\r\n display: none;\r\n }\r\n\r\n .billing-client-name {\r\n font-weight: 600;\r\n }\r\n\r\n .billing-table>thead>tr>th {\r\n background: #f8f9fa;\r\n }\r\n\r\n .billing-details-wrap {\r\n background: #f8fbff;\r\n }\r\n}\r\n\r\n/* sidebar submenu */\r\n\r\n/* vacations module */\r\n\r\n.vacation-type-badge {\r\n display: inline-block;\r\n padding: 2px 8px;\r\n border-radius: 4px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n background: #e3f0ff;\r\n color: #2563eb;\r\n\r\n &.type-chorobowe {\r\n background: #fff3e0;\r\n color: #e65100;\r\n }\r\n\r\n &.type-inna_nieobecnosc {\r\n background: #f3e5f5;\r\n color: #7b1fa2;\r\n }\r\n}"]}
\ No newline at end of file
diff --git a/layout/style.scss b/layout/style.scss
index 81d8108..4ab12e7 100644
--- a/layout/style.scss
+++ b/layout/style.scss
@@ -1750,7 +1750,7 @@ $sidebar-hover-bg: rgba(255, 255, 255, 0.08);
.finance-manager {
display: grid;
gap: 10px;
- grid-template-columns: 200px 1fr 500px;
+ grid-template-columns: 250px 1fr 500px;
padding-top: 25px;
.manage-menu {
@@ -1999,36 +1999,248 @@ $sidebar-hover-bg: rgba(255, 255, 255, 0.08);
.tasks_main_view {
display: flex;
gap: 20px;
+ align-items: flex-start;
._left_column {
- padding: 25px;
- background: #fcfcfc;
- border-right: 1px solid #e8e8e8;
- width: 350px;
+ width: fit-content;
+ min-width: 350px;
+ max-width: 520px;
+ padding: 0;
+ background: transparent;
+ border-right: 0;
- label {
- font-weight: 400;
- font-size: 14px;
+ .filters_panel {
+ background: linear-gradient(180deg, #fdfefe 0%, #f4f7fb 100%);
+ border: 1px solid #dbe2ea;
+ border-radius: 12px;
+ padding: 16px;
+ box-shadow: none;
+ }
+
+ .filters_panel_header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 14px;
+ }
+
+ .filters_panel_title {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ i {
+ color: #1f3d72;
+ }
+
+ h3 {
+ margin: 0;
+ font-size: 16px;
+ font-weight: 700;
+ color: #1f3d72;
+ }
+ }
+
+ .active_filters_badge {
+ display: inline-flex;
+ align-items: center;
+ padding: 4px 10px;
+ border-radius: 999px;
+ font-size: 12px;
+ color: #425466;
+ background: #e9eff8;
+
+ strong {
+ margin-left: 4px;
+ font-size: 13px;
+ color: #1f3d72;
+ }
+ }
+
+ .filters_controls {
+ margin-bottom: 14px;
+ padding: 12px;
+ border-radius: 10px;
+ border: 1px solid #dbe2ea;
+ background: #fff;
+ }
+
+ .filters_label {
+ display: block;
+ margin-bottom: 6px;
+ font-size: 12px;
+ font-weight: 600;
+ color: #425466;
}
select[name="filtr"] {
- margin-bottom: 10px;
+ margin-bottom: 12px;
+ height: 40px;
+ border-color: #d1dae4;
+
+ &:focus {
+ border-color: #5f88e9;
+ box-shadow: 0 0 0 3px rgba(95, 136, 233, 0.15);
+ }
}
._buttons {
display: flex;
- gap: 10px;
- justify-content: space-between;
+ gap: 8px;
.btn {
flex: 1;
+ min-height: 34px;
+ font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: 0.3px;
+ }
+
+ .btn-dark {
+ background: #3d495e;
+
+ &:hover {
+ background: #2f394c;
+ }
+ }
+ }
+
+ .filters_section {
+ border: 1px solid #dbe2ea;
+ border-radius: 10px;
+ background: #fff;
+ margin-bottom: 12px;
+ overflow: hidden;
+ }
+
+ .filters_section_header {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px 12px;
+ background: #f4f7fb;
+ border-bottom: 1px solid #e3eaf2;
+
+ h4 {
+ margin: 0;
+ font-size: 14px;
+ font-weight: 700;
+ color: #243447;
+ }
+
+ .filters_search {
+ max-width: 170px;
+ height: 32px;
+ font-size: 12px;
+ padding: 4px 10px;
+ border-color: #d2dbe6;
+ }
+ }
+
+ .filters_section_list {
+ max-height: 270px;
+ overflow-y: auto;
+ padding: 6px;
+ }
+
+ .filters_section._projects .filters_section_list {
+ max-height: none;
+ overflow: visible;
+ }
+
+ .filters_item {
+ border-radius: 8px;
+ transition: background 0.2s ease;
+
+ &:hover {
+ background: #f4f7fb;
+ }
+ }
+
+ .project_row,
+ ._user {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ padding: 5px 7px;
+
+ label {
+ margin: 0;
+ flex: 1;
+ font-weight: 400;
+ font-size: 14px;
+ white-space: nowrap;
+ }
+ }
+
+ .project_count {
+ display: inline-block;
+ margin-left: 4px;
+ min-width: 26px;
+ padding: 0 7px;
+ border-radius: 999px;
+ background: #1f3d72;
+ color: #fff;
+ font-weight: 700;
+ font-size: 11px;
+ line-height: 19px;
+ text-align: center;
+ vertical-align: middle;
+ }
+
+ .project_delete_inline {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 20px;
+ height: 20px;
+ border-radius: 5px;
+ border: 1px solid #cc563d;
+ background: #cc563d;
+ color: #fff;
+ text-decoration: none;
+ transition: all 0.2s ease;
+ margin: 1px 0;
+
+ &:hover {
+ background: #b74831;
+ border-color: #b74831;
+ }
+
+ i {
+ font-size: 10px;
}
}
}
._right_column {
flex: 1;
- max-width: calc(100% - 350px);
+ max-width: none;
+ min-width: 0;
+ }
+}
+
+@media (max-width: 1200px) {
+ .tasks_main_view {
+ flex-direction: column;
+
+ ._left_column,
+ ._right_column {
+ max-width: 100%;
+ width: 100%;
+ }
+ }
+}
+
+.gantt-target {
+ .gantt-container.gantt-draggable {
+ cursor: grab;
+ }
+
+ .gantt-container.gantt-dragging {
+ cursor: grabbing;
}
}
diff --git a/templates/finances/fakturownia-import-panel.php b/templates/finances/fakturownia-import-panel.php
new file mode 100644
index 0000000..824663a
--- /dev/null
+++ b/templates/finances/fakturownia-import-panel.php
@@ -0,0 +1,148 @@
+
+
+
+
+
Import faktur z Fakturowni
+
+
+ if ( is_array( $this -> fakturownia_last_summary ) && isset( $this -> fakturownia_last_summary['summary'] ) ): ?>
+
+ Ostatni import: = $esc( $this -> fakturownia_last_summary['at'] ?? '-' ); ?>
+ Zaimportowano: = (int)( $this -> fakturownia_last_summary['summary']['imported'] ?? 0 ); ?>,
+ pominieto: = (int)( $this -> fakturownia_last_summary['summary']['skipped'] ?? 0 ); ?>,
+ brak mapowan: = (int)( $this -> fakturownia_last_summary['summary']['unmapped'] ?? 0 ); ?>,
+ bledy: = (int)( $this -> fakturownia_last_summary['summary']['errors'] ?? 0 ); ?>
+
+ endif; ?>
+
+ if ( is_array( $this -> fakturownia_pending_clients ) && count( $this -> fakturownia_pending_clients ) ): ?>
+
Brakujace mapowania klientow
+
+
+
+ | Klient z Fakturowni |
+ CRM klient |
+ Akcja |
+
+
+
+ foreach ( $this -> fakturownia_pending_clients as $row ): ?>
+
+
+ = $esc( $row['external_name'] ); ?>
+ Klucz: = $esc( $row['external_key'] ); ?> | wystapienia: = (int)$row['hits']; ?>
+ |
+
+ |
+
+
+
+ |
+
+ endforeach; ?>
+
+
+ endif; ?>
+
+ if ( is_array( $this -> fakturownia_pending_items ) && count( $this -> fakturownia_pending_items ) ): ?>
+
Brakujace mapowania produktow/uslug
+
+
+
+ | Pozycja z faktury |
+ Kategoria finansowa |
+ Akcja |
+
+
+
+ foreach ( $this -> fakturownia_pending_items as $row ): ?>
+
+
+ = $esc( $row['external_name'] ); ?>
+ Klucz: = $esc( $row['external_key'] ); ?> | wystapienia: = (int)$row['hits']; ?>
+ |
+
+ |
+
+
+
+ |
+
+ endforeach; ?>
+
+
+ endif; ?>
+
+
+
diff --git a/templates/finances/main-view.php b/templates/finances/main-view.php
index 12fe66f..2c15a46 100644
--- a/templates/finances/main-view.php
+++ b/templates/finances/main-view.php
@@ -46,6 +46,9 @@
+
+ include 'fakturownia-import-panel.php'; ?>
+
@@ -307,4 +310,4 @@ $(function() {
$(this).parents('.input-group').children('input').trigger('click');
});
});
-
\ No newline at end of file
+
diff --git a/templates/tasks/main_view.php b/templates/tasks/main_view.php
index 162887e..c6e3027 100644
--- a/templates/tasks/main_view.php
+++ b/templates/tasks/main_view.php
@@ -1,48 +1,70 @@
-
-
-
-
Projekty
- foreach ( $this -> projects as $project ):?>
-
-
-
- if ( \controls\Users::permissions( $this -> user['id'], 'projects', 'project_delete' ) ):?>
-
-
-
- endif;?>
+
+
+
+
+
+
+
+
+
+
+ foreach ( $this -> projects as $project ):?>
+
+
+
+ if ( \controls\Users::permissions( $this -> user['id'], 'projects', 'project_delete' ) ):?>
+
+
+
+ endif;?>
+
+
+ endforeach;?>
+
+
+ if ( $this -> user['id'] == 1 ):?>
+
+
+
+ foreach ( $this -> users as $user ):?>
+
+
+
+ endforeach;?>
- endforeach;?>
+ endif;?>
- if ( $this -> user['id'] == 1 ):?>
-
-
Użytkownicy
- foreach ( $this -> users as $user ):?>
-
-
-
- endforeach;?>
-
- endif;?>