diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..e69de29 diff --git a/blueprints/CLAUDE.md b/blueprints/CLAUDE.md new file mode 100644 index 0000000..522a590 --- /dev/null +++ b/blueprints/CLAUDE.md @@ -0,0 +1,13 @@ + +# Recent Activity + + + +### Jan 31, 2026 + +| ID | Time | T | Title | Read | +|----|------|---|-------|------| +| #248 | 6:33 PM | 🔵 | Nordabiz register_blueprints() function implements phased migration with 407 lines of endpoint aliasing for backward compatibility | ~1102 | +| #180 | 6:25 PM | 🔵 | Nordabiz project architecture analyzed revealing 16+ Flask blueprints with modular organization | ~831 | +| #166 | 6:23 PM | 🔵 | Nordabiz implements phased blueprint registration with backward-compatible endpoint aliases | ~801 | + \ No newline at end of file diff --git a/blueprints/admin/CLAUDE.md b/blueprints/admin/CLAUDE.md new file mode 100644 index 0000000..e0c4a68 --- /dev/null +++ b/blueprints/admin/CLAUDE.md @@ -0,0 +1,14 @@ + +# Recent Activity + + + +### Jan 31, 2026 + +| ID | Time | T | Title | Read | +|----|------|---|-------|------| +| #250 | 6:33 PM | 🔵 | Nordabiz admin blueprint imports 14 separate routes modules demonstrating extreme modularization | ~677 | +| #180 | 6:25 PM | 🔵 | Nordabiz project architecture analyzed revealing 16+ Flask blueprints with modular organization | ~831 | +| #170 | 6:23 PM | 🔵 | Nordabiz admin routes handle recommendations moderation with Polish localization | ~713 | +| #168 | " | 🔵 | Nordabiz admin blueprint splits functionality across 15 route modules | ~726 | + \ No newline at end of file diff --git a/blueprints/api/CLAUDE.md b/blueprints/api/CLAUDE.md new file mode 100644 index 0000000..fc325fe --- /dev/null +++ b/blueprints/api/CLAUDE.md @@ -0,0 +1,12 @@ + +# Recent Activity + + + +### Jan 31, 2026 + +| ID | Time | T | Title | Read | +|----|------|---|-------|------| +| #245 | 6:33 PM | 🔵 | Nordabiz API blueprint aggregates 7 specialized route modules for frontend interactions | ~574 | +| #180 | 6:25 PM | 🔵 | Nordabiz project architecture analyzed revealing 16+ Flask blueprints with modular organization | ~831 | + \ No newline at end of file diff --git a/blueprints/auth/CLAUDE.md b/blueprints/auth/CLAUDE.md new file mode 100644 index 0000000..adfdcb1 --- /dev/null +++ b/blueprints/auth/CLAUDE.md @@ -0,0 +1,7 @@ + +# Recent Activity + + + +*No recent activity* + \ No newline at end of file diff --git a/blueprints/public/CLAUDE.md b/blueprints/public/CLAUDE.md new file mode 100644 index 0000000..c85f036 --- /dev/null +++ b/blueprints/public/CLAUDE.md @@ -0,0 +1,12 @@ + +# Recent Activity + + + +### Jan 31, 2026 + +| ID | Time | T | Title | Read | +|----|------|---|-------|------| +| #180 | 6:25 PM | 🔵 | Nordabiz project architecture analyzed revealing 16+ Flask blueprints with modular organization | ~831 | +| #169 | 6:23 PM | 🔵 | Nordabiz public blueprint organized into three route modules for homepage, ZOPK integration, and announcements | ~551 | + \ No newline at end of file diff --git a/data/ceidg_search_results/ceidg_debug_95.png b/data/ceidg_search_results/ceidg_debug_95.png new file mode 100644 index 0000000..59bc615 Binary files /dev/null and b/data/ceidg_search_results/ceidg_debug_95.png differ diff --git a/data/ceidg_search_results/ceidg_search_20260201_070809.json b/data/ceidg_search_results/ceidg_search_20260201_070809.json new file mode 100644 index 0000000..4a0418f --- /dev/null +++ b/data/ceidg_search_results/ceidg_search_20260201_070809.json @@ -0,0 +1,18 @@ +[ + { + "company_id": 119, + "company_name": "3W", + "search_query": "3W", + "found_nip": null, + "found_regon": null, + "found_name": null, + "found_owner": null, + "found_address": null, + "found_status": null, + "matches": [], + "confidence": "low", + "verified": false, + "error": "Timeout", + "searched_at": "2026-02-01T07:07:32.763556" + } +] \ No newline at end of file diff --git a/data/ceidg_search_results/ceidg_search_20260201_071218.json b/data/ceidg_search_results/ceidg_search_20260201_071218.json new file mode 100644 index 0000000..d051b27 --- /dev/null +++ b/data/ceidg_search_results/ceidg_search_20260201_071218.json @@ -0,0 +1,18 @@ +[ + { + "company_id": 95, + "company_name": "Kancelaria Notarialna Henryk Mizak", + "search_query": "Kancelaria Notarialna Henryk Mizak", + "found_nip": null, + "found_regon": null, + "found_name": null, + "found_owner": null, + "found_address": null, + "found_status": null, + "matches": [], + "confidence": "low", + "verified": false, + "error": "Nie znaleziono pola wyszukiwania. Screenshot: /Users/maciejpi/claude/projects/active/nordabiz/data/ceidg_search_results/ceidg_debug_95.png", + "searched_at": "2026-02-01T07:12:10.623430" + } +] \ No newline at end of file diff --git a/data/nip_scan_results/scan_20260201_065905.json b/data/nip_scan_results/scan_20260201_065905.json new file mode 100644 index 0000000..e2c8230 --- /dev/null +++ b/data/nip_scan_results/scan_20260201_065905.json @@ -0,0 +1,19 @@ +[ + { + "company_id": 113, + "company_name": "Piotrex", + "domain": "piotrex.info", + "url_scanned": "https://piotrex.info/kontakt", + "nip_found": "5881846715", + "regon_found": null, + "nips_all": [ + "5881846715" + ], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T06:59:00.521605" + } +] \ No newline at end of file diff --git a/data/nip_scan_results/scan_20260201_070032.json b/data/nip_scan_results/scan_20260201_070032.json new file mode 100644 index 0000000..7e65eb3 --- /dev/null +++ b/data/nip_scan_results/scan_20260201_070032.json @@ -0,0 +1,331 @@ +[ + { + "company_id": 119, + "company_name": "3W", + "domain": "3wdb.pl", + "url_scanned": "https://3wdb.pl/o-nas", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:12.777529" + }, + { + "company_id": 121, + "company_name": "BIS Maszyny", + "domain": "bis-bau.pl", + "url_scanned": "https://bis-bau.pl/o-nas", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:17.025257" + }, + { + "company_id": 93, + "company_name": "Dom Dziecka Pro-Sport", + "domain": "prosport.wejher.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:24.231589" + }, + { + "company_id": 122, + "company_name": "Elgreen EM", + "domain": "elgreen.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:26.087690" + }, + { + "company_id": 117, + "company_name": "Elzit", + "domain": "elzit.pl", + "url_scanned": "https://elzit.pl", + "nip_found": "9581160890", + "regon_found": "191427842", + "nips_all": [ + "9581160890" + ], + "regons_all": [ + "191427842" + ], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T06:59:27.702428" + }, + { + "company_id": 94, + "company_name": "Event Investycje", + "domain": "bombera.pl", + "url_scanned": "https://bombera.pl", + "nip_found": "5892024537", + "regon_found": null, + "nips_all": [ + "5892024537" + ], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T06:59:30.031341" + }, + { + "company_id": 112, + "company_name": "Informatyk1", + "domain": "informatyk1.pl", + "url_scanned": "https://informatyk1.pl/about", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:32.687646" + }, + { + "company_id": 123, + "company_name": "Iwona Spaleniak Coaching", + "domain": "iwonaspaleniak.pl", + "url_scanned": "https://iwonaspaleniak.pl/about", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:37.620806" + }, + { + "company_id": 114, + "company_name": "Kancelaria Ostrowski i Wspólnicy", + "domain": "ostrowski-legal.net", + "url_scanned": "https://ostrowski-legal.net", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:48.733603" + }, + { + "company_id": 124, + "company_name": "Kaszubia 2030", + "domain": "kaszubia2030.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:51.434997" + }, + { + "company_id": 111, + "company_name": "Nowatel", + "domain": "nowatel.com", + "url_scanned": "https://nowatel.com", + "nip_found": "5932407062", + "regon_found": null, + "nips_all": [ + "5932407062" + ], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T06:59:52.617348" + }, + { + "company_id": 110, + "company_name": "Omega Energy", + "domain": "omega-energy.eu", + "url_scanned": "https://www.omega-energy.eu", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:53.838239" + }, + { + "company_id": 96, + "company_name": "Orlex Design", + "domain": "orlexbeton.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T06:59:57.143298" + }, + { + "company_id": 113, + "company_name": "Piotrex", + "domain": "piotrex.info", + "url_scanned": "https://piotrex.info/kontakt", + "nip_found": "5881846715", + "regon_found": null, + "nips_all": [ + "5881846715" + ], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T06:59:58.758426" + }, + { + "company_id": 98, + "company_name": "Podróże i My", + "domain": "itakarumia.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:02.539004" + }, + { + "company_id": 100, + "company_name": "PZU TFI", + "domain": "pzu.pl", + "url_scanned": "https://www.pzu.pl", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:04.298279" + }, + { + "company_id": 116, + "company_name": "Renk Hurtownie", + "domain": "renk.pl", + "url_scanned": "https://renk.pl/kontakt", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:08.159123" + }, + { + "company_id": 101, + "company_name": "Rozsądni Bracia", + "domain": "rozsandnibracia.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:14.494471" + }, + { + "company_id": 102, + "company_name": "TERMO", + "domain": "termocenter.pl", + "url_scanned": "https://termocenter.pl/about", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:15.685339" + }, + { + "company_id": 109, + "company_name": "Unimot", + "domain": "unimot-eig.pl", + "url_scanned": "https://unimot-eig.pl", + "nip_found": "9730421440", + "regon_found": "970619205", + "nips_all": [ + "9730421440" + ], + "regons_all": [ + "970619205" + ], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T07:00:24.581291" + }, + { + "company_id": 118, + "company_name": "Your Welcome", + "domain": "yourewelcome.pl", + "url_scanned": "https://yourewelcome.pl/o-nas", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:26.083523" + } +] \ No newline at end of file diff --git a/data/nip_scan_results/scan_20260201_070155.json b/data/nip_scan_results/scan_20260201_070155.json new file mode 100644 index 0000000..fca103d --- /dev/null +++ b/data/nip_scan_results/scan_20260201_070155.json @@ -0,0 +1,331 @@ +[ + { + "company_id": 119, + "company_name": "3W", + "domain": "3wdb.pl", + "url_scanned": "https://3wdb.pl/o-nas", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:40.822770" + }, + { + "company_id": 121, + "company_name": "BIS Maszyny", + "domain": "bis-bau.pl", + "url_scanned": "https://bis-bau.pl/o-nas", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:44.927095" + }, + { + "company_id": 93, + "company_name": "Dom Dziecka Pro-Sport", + "domain": "prosport.wejher.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:52.609620" + }, + { + "company_id": 122, + "company_name": "Elgreen EM", + "domain": "elgreen.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:00:54.221059" + }, + { + "company_id": 117, + "company_name": "Elzit", + "domain": "elzit.pl", + "url_scanned": "https://elzit.pl", + "nip_found": "9581160890", + "regon_found": "191427842", + "nips_all": [ + "9581160890" + ], + "regons_all": [ + "191427842" + ], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T07:00:55.749843" + }, + { + "company_id": 94, + "company_name": "Event Investycje", + "domain": "bombera.pl", + "url_scanned": "https://bombera.pl", + "nip_found": "5892024537", + "regon_found": null, + "nips_all": [ + "5892024537" + ], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T07:00:58.050212" + }, + { + "company_id": 112, + "company_name": "Informatyk1", + "domain": "informatyk1.pl", + "url_scanned": "https://informatyk1.pl/about", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:00.371984" + }, + { + "company_id": 123, + "company_name": "Iwona Spaleniak Coaching", + "domain": "iwonaspaleniak.pl", + "url_scanned": "https://iwonaspaleniak.pl/about", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:05.234668" + }, + { + "company_id": 114, + "company_name": "Kancelaria Ostrowski i Wspólnicy", + "domain": "ostrowski-legal.net", + "url_scanned": "https://ostrowski-legal.net", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:16.190843" + }, + { + "company_id": 124, + "company_name": "Kaszubia 2030", + "domain": "kaszubia2030.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:18.672999" + }, + { + "company_id": 111, + "company_name": "Nowatel", + "domain": "nowatel.com", + "url_scanned": "https://nowatel.com", + "nip_found": "5932407062", + "regon_found": null, + "nips_all": [ + "5932407062" + ], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T07:01:19.699237" + }, + { + "company_id": 110, + "company_name": "Omega Energy", + "domain": "omega-energy.eu", + "url_scanned": "https://www.omega-energy.eu", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:20.870985" + }, + { + "company_id": 96, + "company_name": "Orlex Design", + "domain": "orlexbeton.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:24.345116" + }, + { + "company_id": 113, + "company_name": "Piotrex", + "domain": "piotrex.info", + "url_scanned": "https://piotrex.info/kontakt", + "nip_found": "5881846715", + "regon_found": null, + "nips_all": [ + "5881846715" + ], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T07:01:25.806602" + }, + { + "company_id": 98, + "company_name": "Podróże i My", + "domain": "itakarumia.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:29.373428" + }, + { + "company_id": 100, + "company_name": "PZU TFI", + "domain": "pzu.pl", + "url_scanned": "https://www.pzu.pl", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:30.817174" + }, + { + "company_id": 116, + "company_name": "Renk Hurtownie", + "domain": "renk.pl", + "url_scanned": "https://renk.pl/kontakt", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:34.485235" + }, + { + "company_id": 101, + "company_name": "Rozsądni Bracia", + "domain": "rozsandnibracia.pl", + "url_scanned": "", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:40.789330" + }, + { + "company_id": 102, + "company_name": "TERMO", + "domain": "termocenter.pl", + "url_scanned": "https://termocenter.pl/about", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:41.822554" + }, + { + "company_id": 109, + "company_name": "Unimot", + "domain": "unimot-eig.pl", + "url_scanned": "https://unimot-eig.pl", + "nip_found": "9730421440", + "regon_found": "970619205", + "nips_all": [ + "9730421440" + ], + "regons_all": [ + "970619205" + ], + "phone_found": null, + "address_found": null, + "confidence": "high", + "error": null, + "scanned_at": "2026-02-01T07:01:47.902680" + }, + { + "company_id": 118, + "company_name": "Your Welcome", + "domain": "yourewelcome.pl", + "url_scanned": "https://yourewelcome.pl/o-nas", + "nip_found": null, + "regon_found": null, + "nips_all": [], + "regons_all": [], + "phone_found": null, + "address_found": null, + "confidence": "low", + "error": "NIP/REGON not found on website", + "scanned_at": "2026-02-01T07:01:49.260663" + } +] \ No newline at end of file diff --git a/database.py b/database.py index c34b962..e6e73a1 100644 --- a/database.py +++ b/database.py @@ -674,7 +674,7 @@ class Company(Base): # PKD (kod działalności gospodarczej) - z CEIDG pkd_code = Column(String(10)) # np. "6201Z" (główny PKD) pkd_description = Column(Text) # np. "Działalność związana z oprogramowaniem" - pkd_codes = Column(PG_JSONB, default=[]) # Wszystkie PKD jako [{kod, nazwa}] + ceidg_pkd_list = Column(PG_JSONB, default=[]) # Wszystkie PKD z CEIDG jako [{kod, nazwa}] # Data rozpoczęcia działalności - z CEIDG business_start_date = Column(Date) # np. 2021-02-10 diff --git a/database/migrations/036_ceidg_extended_data.sql b/database/migrations/036_ceidg_extended_data.sql index 1ec5c5f..90b760b 100644 --- a/database/migrations/036_ceidg_extended_data.sql +++ b/database/migrations/036_ceidg_extended_data.sql @@ -14,8 +14,8 @@ ALTER TABLE companies ADD COLUMN IF NOT EXISTS correspondence_street VARCHAR(255 ALTER TABLE companies ADD COLUMN IF NOT EXISTS correspondence_city VARCHAR(100); ALTER TABLE companies ADD COLUMN IF NOT EXISTS correspondence_postal VARCHAR(10); --- PKD - wszystkie kody (JSONB array) -ALTER TABLE companies ADD COLUMN IF NOT EXISTS pkd_codes JSONB DEFAULT '[]'; +-- PKD - wszystkie kody z CEIDG (JSONB array) +ALTER TABLE companies ADD COLUMN IF NOT EXISTS ceidg_pkd_list JSONB DEFAULT '[]'; -- Obywatelstwa właściciela (JSONB array) ALTER TABLE companies ADD COLUMN IF NOT EXISTS owner_citizenships JSONB DEFAULT '[]'; @@ -32,7 +32,7 @@ CREATE INDEX IF NOT EXISTS idx_companies_ceidg_id ON companies(ceidg_id); -- Komentarze COMMENT ON COLUMN companies.ceidg_id IS 'GUID firmy w rejestrze CEIDG'; COMMENT ON COLUMN companies.ceidg_status IS 'Status z CEIDG: AKTYWNY, ZAWIESZONY, WYKREŚLONY'; -COMMENT ON COLUMN companies.pkd_codes IS 'Wszystkie kody PKD jako JSON array [{kod, nazwa}]'; +COMMENT ON COLUMN companies.ceidg_pkd_list IS 'Wszystkie kody PKD z CEIDG jako JSON array [{kod, nazwa}]'; COMMENT ON COLUMN companies.ceidg_raw_data IS 'Pełna odpowiedź z API CEIDG (JSON)'; COMMENT ON COLUMN companies.ceidg_fetched_at IS 'Data ostatniego pobrania danych z CEIDG'; diff --git a/docs/UI_ANALYSIS_NORDA_BIZNES_INFO.md b/docs/UI_ANALYSIS_NORDA_BIZNES_INFO.md new file mode 100644 index 0000000..c044df5 --- /dev/null +++ b/docs/UI_ANALYSIS_NORDA_BIZNES_INFO.md @@ -0,0 +1,1289 @@ +# Analiza UI/UX strony norda-biznes.info + +**Data analizy:** 2026-01-30 +**Cel:** Baza wiedzy do przeróbki interfejsu graficznego nordabiznes.pl +**Źródło:** https://norda-biznes.info + +--- + +## 1. TECHNOLOGIE + +### Framework CSS +- **Tailwind CSS** - pełna implementacja z custom theme +- **Build tool:** Webpack/Vite (hash w nazwach plików: `main.16f43e30a40e76df337c.css`) +- **NIE WordPress** - custom build + +### Pliki źródłowe +``` +CSS: https://norda-biznes.info/public/css/main.16f43e30a40e76df337c.css +JS: https://norda-biznes.info/public/js/main.16f43e30a40e76df337c.js +``` + +### Analytics +- Google Tag Manager + +--- + +## 2. TYPOGRAFIA + +### Czcionka główna +```css +font-family: 'Poppins', sans-serif; +``` + +**Google Fonts import:** +```html + +``` + +### Wagi czcionki używane +| Waga | Zastosowanie | +|------|--------------| +| 400 (regular) | Tekst body, paragrafy | +| 500 (medium) | Przyciski secondary | +| 600 (semibold) | Nagłówki, przyciski primary, akcenty | +| 700 (bold) | Rzadko używane | + +### Rozmiary tekstu (font-size) +| Rozmiar | Tailwind class | Zastosowanie | +|---------|---------------|--------------| +| 11px | text-xs | Drobne etykiety | +| 12px | text-xs | Tagi, badges | +| 14px | text-sm | Tekst body mały, przyciski | +| 16px | text-base | Tekst body główny | +| 18px | text-lg | H3, podtytuły | +| 20px | text-xl | H2 w kartach | +| 32px | text-2xl | H2 sekcji | +| 40px | text-4xl | H1 hero | + +### Nagłówki - szczegóły +```css +/* H1 - Hero */ +h1 { + font-family: 'Poppins'; + font-size: 40px; + font-weight: 600; + line-height: 48px; /* 1.2 */ + letter-spacing: normal; + color: #FFFFFF; /* na ciemnym tle */ +} + +/* H2 - Sekcje */ +h2 { + font-family: 'Poppins'; + font-size: 16px; /* małe */ lub 32px /* duże */ + font-weight: 600; + line-height: 24px; + color: rgb(46, 72, 114); /* primary-blue */ +} + +/* H3 - Karty */ +h3 { + font-family: 'Poppins'; + font-size: 18px; + font-weight: 600; + line-height: 25.2px; /* 1.4 */ + color: rgb(48, 48, 48); +} +``` + +--- + +## 3. PALETA KOLORÓW + +### Kolory główne (Tailwind custom) + +| Nazwa Tailwind | Wartość RGB | HEX | Zastosowanie | +|----------------|-------------|-----|--------------| +| `default-primary-blue` | rgb(46, 72, 114) | **#2E4872** | Przyciski, nagłówki, akcenty | +| `default-body` | rgb(237, 240, 245) | **#EDF0F5** | Tło sekcji szare | +| `default-white` | rgb(255, 255, 255) | **#FFFFFF** | Tło kart, tekst na ciemnym | +| `default-light-gray` | rgb(228, 228, 228) | **#E4E4E4** | Bordery, separatory | +| `default-header-black` | rgb(48, 48, 48) | **#303030** | Nagłówki na jasnym tle | +| `[#2C456E]` | - | **#2C456E** | Alternatywny niebieski (ciemniejszy) | + +### Kolory tekstu +| Klasa | Wartość | Zastosowanie | +|-------|---------|--------------| +| `text-default-body` | rgb(70, 70, 70) | Tekst paragrafów | +| `text-default-primary-blue` | rgb(46, 72, 114) | Linki, akcenty | +| `text-default-white` | rgb(255, 255, 255) | Tekst na ciemnym tle | +| `text-default-white-fade-80` | rgba(255,255,255,0.8) | Tekst secondary na ciemnym | +| `text-default-date` | szary | Daty, metadata | + +### Kolory border +| Klasa | Zastosowanie | +|-------|--------------| +| `border-default-primary-blue` | Przyciski outline | +| `border-default-body` | Karty | +| `border-default-light-gray` | Separatory poziome | +| `border-default-blue-fade-more` | Subtelne bordery | +| `border-default-hr` | Linie hr | + +--- + +## 4. PRZYCISKI (CTA) + +### Primary Button +```css +.btn-primary { + background-color: rgb(46, 72, 114); /* #2E4872 */ + color: rgb(255, 255, 255); + padding: 12px 24px; + border-radius: 12px 4px; /* ASYMETRYCZNY! */ + font-weight: 600; + font-size: 14px; + border: 2px solid rgb(46, 72, 114); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} +``` + +### Primary Button White (na ciemnym tle) +```css +.btn-primary-white { + background-color: rgb(46, 72, 114); + color: rgb(234, 234, 234); + padding: 12px 24px; + border-radius: 12px 4px; + font-weight: 600; + font-size: 14px; + border: 2px solid rgb(234, 234, 234); /* biały border */ +} +``` + +### Secondary Button (outline) +```css +.btn-primary-border { + background-color: transparent; + color: rgb(46, 72, 114); + padding: 12px 24px; + border-radius: 12px 4px; + font-weight: 600; + font-size: 14px; + border: 2px solid rgb(46, 72, 114); +} +``` + +### WAŻNE: Asymetryczny border-radius +```css +border-radius: 12px 4px; +/* Górny-lewy: 12px (zaokrąglony) */ +/* Górny-prawy: 4px (lekko zaokrąglony) */ +/* Dolny-prawy: 12px */ +/* Dolny-lewy: 4px */ +``` +To charakterystyczny element designu - przyciski mają "ścięty" róg. + +--- + +## 5. LAYOUT I SPACING + +### Container +```css +.container { + max-width: 1444px; + padding: 0 32px; + margin: 0 auto; +} +``` + +### Breakpointy Tailwind (standardowe) +| Prefix | Min-width | Zastosowanie | +|--------|-----------|--------------| +| `sm:` | 640px | Mobile landscape | +| `md:` | 768px | Tablet | +| `lg:` | 1024px | Desktop small | +| `xl:` | 1280px | Desktop | +| `2xl:` | 1536px | Desktop large | + +### Klasy responsywne używane +``` +sm: rounded-2xl, w-full, w-auto, gap-2, p-4, text-base, grid-cols-1 +md: px-4, h-8, hidden, text-lg, flex-col, w-full, gap-4 +lg: py-3, flex-col, order-2, w-full, gap-6, grid-cols-2, items-center +xl: flex-col, justify-center, flex, items-center, block +2xl: gap-6, h-10, mr-8 +``` + +### Gap (odstępy) +| Klasa | Wartość | Zastosowanie | +|-------|---------|--------------| +| `gap-1` | 4px | Kompaktowe elementy | +| `gap-3` | 12px | Tagi | +| `gap-4` | 16px | Karty w gridzie | +| `gap-6` | 24px | Sekcje | +| `gap-8` | 32px | Duże sekcje | +| `gap-10` | 40px | Między sekcjami | +| `gap-12` | 48px | Hero | +| `gap-24` | 96px | Maksymalny | + +--- + +## 6. STRUKTURA SEKCJI STRONY GŁÓWNEJ + +### Hierarchia sekcji +1. **Header/Nav** - sticky, logo + menu + CTA +2. **Hero** (571px) - "Łączymy siły Przedsiębiorców Pomorza" +3. **Logo carousel** (64px) - karuzela logotypów firm +4. **O nas** (885px) - statystyki + zdjęcie + tekst +5. **Nasi członkowie** (569px) - grid kart firm +6. **Aktualności + Wydarzenia** (821px) - dwie kolumny +7. **Korzyści członkostwa** (642px) - ikony na ciemnym tle +8. **Opinie** (480px) - testimoniale z avatarami +9. **Footer** - logo + kontakt + social media + +### Hero Section +```css +section.hero { + height: 571px; + /* Ukośne tło z obrazami */ + /* Biały tekst na ciemnym overlay */ +} +``` + +### Sekcja korzyści (ciemne tło) +```css +section.benefits { + background-color: rgb(46, 72, 114); + /* Białe karty z ikonami */ + /* 4 kolumny: Katalog firm, Nasze projekty, Baza wiedzy, CTA */ +} +``` + +--- + +## 7. KARTY FIRM + +### Struktura karty +``` +┌─────────────────────────────┐ +│ [LOGO FIRMY] │ +│ │ +│ Nazwa firmy │ +│ │ +│ [tag1] [tag2] [tag3] │ +│ [tag4] [tag5] │ +└─────────────────────────────┘ +``` + +### Style karty +```css +.company-card { + background: white; + border: 1px solid rgb(228, 228, 228); + border-radius: 0; /* brak zaokrąglenia */ + padding: 24px; + transition: all 0.3s; +} + +.company-card:hover { + /* efekt hover - prawdopodobnie cień lub border */ +} +``` + +### Tagi/Badges +```css +.tag { + font-size: 12px; /* text-xs */ + padding: 4px 8px; + background: rgb(237, 240, 245); /* bg-default-body */ + color: rgb(70, 70, 70); + border-radius: 4px; + text-transform: uppercase; +} +``` + +### Grid kart +```css +.cards-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); /* 4 kolumny desktop */ + gap: 16px; +} + +/* Responsywność */ +@media (max-width: 1024px) { + grid-template-columns: repeat(2, 1fr); +} +@media (max-width: 640px) { + grid-template-columns: 1fr; +} +``` + +--- + +## 8. NAWIGACJA + +### Menu items +- O nas (`/o-nas`) +- Członkowie (`/czlonkowie`) +- Aktualności (`/aktualnosci`) +- Wydarzenia (`/wydarzenia`) +- Kontakt (`/kontakt`) +- **CTA:** "Dołącz do nas" (`/kontakt#dolacz-do-nas`) + +### Logo +``` +URL: https://norda-biznes.info/public/images/logo.svg +Alt: "Norda Biznes - logo" +Width: 115px +Height: 52px +``` + +--- + +## 9. FOOTER + +### Struktura +``` +┌──────────────────────────────────────────────────────┐ +│ [LOGO białe] Siedziba Kontakt [FB][LI][YT] │ +│ ul. 12 Marca email │ +│ 84-200 Wejherowo telefon │ +├──────────────────────────────────────────────────────┤ +│ Copyright © 2026 Norda Biznes | Powered by Pixlab.pl │ +└──────────────────────────────────────────────────────┘ +``` + +### Style footer +```css +footer { + background-color: rgb(46, 72, 114); /* primary-blue */ + color: white; +} +``` + +### Logo footer +``` +URL: https://norda-biznes.info/public/images/norda-biznes-logo-footer.svg +/* Wersja biała/jasna logo */ +``` + +### Social Media +- LinkedIn: https://pl.linkedin.com/company/nordabiznes/ +- Facebook: https://www.facebook.com/p/Norda-Biznes-Wejherowo-100057396041901/ +- YouTube: https://www.youtube.com/channel/UCOvJj075wSFQjqdX4h4dyYw + +--- + +## 10. IKONY + +### Lokalizacja ikon +``` +https://norda-biznes.info/public/images/icons/ +``` + +### Lista ikon SVG +| Nazwa | Zastosowanie | +|-------|--------------| +| `iconHome.svg` | Menu - Home | +| `iconArrowLeft.svg` | Nawigacja karuzeli | +| `iconArrowRight.svg` | Nawigacja karuzeli | +| `iconCalendar.svg` | Data wydarzenia | +| `iconJoinUs.svg` | CTA dołącz | +| `iconQuoteBase.svg` | Cudzysłów w opiniach | +| `iconIn2.svg` | LinkedIn | +| `iconFacebook.svg` | Facebook | +| `iconYoutube.svg` | YouTube | + +### Ikony w sekcji korzyści +- Budynek/siatka - Katalog firm +- Narzędzia - Nasze projekty +- Okno/dokument - Baza wiedzy +- Koło/target - CTA + +--- + +## 11. ANIMACJE I PRZEJŚCIA + +### Transition globalne +```css +transition: color 0.3s cubic-bezier(0.4, 0, 0.2, 1), + background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), + border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), + text-decoration-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), + fill 0.3s cubic-bezier(0.4, 0, 0.2, 1), + stroke 0.3s cubic-bezier(0.4, 0, 0.2, 1); +``` + +### Klasy Tailwind +```css +.transition { transition-property: all; } +.duration-300 { transition-duration: 300ms; } +.duration-200 { transition-duration: 200ms; } +``` + +### Animacje wejścia (scroll) +- `fadeIn` - fade in przy scrollu +- `fadeInLeft` - wjazd z lewej + +--- + +## 12. WYSZUKIWARKA + +### Input search +```css +input[type="search"] { + placeholder: "Wyszukaj firmę"; + /* Prosty input z ikoną lupy */ + /* Przycisk X do czyszczenia */ +} +``` + +--- + +## 13. OBRAZY I ZDJĘCIA + +### Format +- Zdjęcia: **WebP** (nowoczesny format) +- Loga firm: **SVG** (wektorowe) +- Ikony: **SVG** + +### Serwowanie obrazów +``` +https://norda-biznes.info/img/400x/{hash}/{filename}.webp +/* Dynamiczne skalowanie przez serwer */ +``` + +--- + +## 14. PORÓWNANIE Z NORDABIZNES.PL + +| Element | norda-biznes.info | nordabiznes.pl | Rekomendacja | +|---------|-------------------|----------------|--------------| +| Czcionka | Poppins | Inter | Zmienić na Poppins | +| Kolor primary | #2E4872 | #1e40af | Rozważyć #2E4872 | +| Przyciski | Asymetryczny radius | Zwykły radius | Dodać asymetrię | +| Framework | Tailwind custom | Bootstrap/custom | Zachować Tailwind | +| Karty firm | Minimalistyczne | Rozbudowane | Zachować nasze | +| Tagi | Uppercase, szare | Kolorowe | Do dyskusji | + +--- + +## 15. REKOMENDACJE DO WDROŻENIA + +### Priorytet 1 (łatwe) +1. [ ] Zmiana czcionki na Poppins +2. [ ] Aktualizacja koloru primary na #2E4872 +3. [ ] Asymetryczny border-radius przycisków (12px 4px) +4. [ ] Dodanie transition 300ms cubic-bezier + +### Priorytet 2 (średnie) +5. [ ] Redesign kart firm +6. [ ] Nowy footer z ciemnym tłem +7. [ ] Karuzela logotypów firm +8. [ ] Sekcja "Sprawdź co mówią o nas" + +### Priorytet 3 (większe zmiany) +9. [ ] Nowy hero section z ukośnym tłem +10. [ ] Sekcja korzyści członkostwa +11. [ ] Nowa strona katalogu firm + +--- + +## 16. ZASOBY DO POBRANIA + +### Czcionka +```html + + + +``` + +### Tailwind config (rekonstrukcja) +```javascript +// tailwind.config.js +module.exports = { + theme: { + extend: { + colors: { + 'default-primary-blue': '#2E4872', + 'default-body': '#EDF0F5', + 'default-white': '#FFFFFF', + 'default-light-gray': '#E4E4E4', + 'default-header-black': '#303030', + 'default-blue-fade-more': 'rgba(46, 72, 114, 0.3)', + 'default-hr': '#E4E4E4', + 'default-date': '#888888', + 'default-white-fade-80': 'rgba(255, 255, 255, 0.8)', + 'default-white-light': 'rgba(255, 255, 255, 0.9)', + }, + fontFamily: { + sans: ['Poppins', 'sans-serif'], + }, + borderRadius: { + 'btn': '12px 4px 12px 4px', + }, + }, + }, +} +``` + +--- + +## 17. BACKEND I SILNIK GENEROWANIA TREŚCI + +### Serwer +``` +Server: Apache +HTTP/2: Tak +Czas renderowania: ~0.024 sec (SSR) +``` + +### Zabezpieczenia HTTP +``` +X-Frame-Options: SAMEORIGIN +X-Content-Type-Options: nosniff +Content-Security-Policy: frame-ancestors 'self' +X-XSS-Protection: 1; mode=block +``` + +### Twórca i technologia +**Pixlab.pl** - polska firma web development z Wejherowa + +**Kluczowe informacje o Pixlab:** +- **Własny framework** - NIE używają WordPress, Joomla ani gotowych CMS +- Tworzą **dedykowane panele CMS** dla każdego klienta +- Specjalizacja: ERP, CRM, e-commerce, strony internetowe +- Filozofia: "szybkie rozwiązanie problemu + jakość" + +### Architektura +``` +┌─────────────────────────────────────────────────────────┐ +│ FRONTEND │ +│ Tailwind CSS + Custom JS (bundled) │ +│ Animacje: CSS @keyframes + IntersectionObserver │ +└─────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────┐ +│ BACKEND (Pixlab Framework) │ +│ Apache + PHP (własny framework) │ +│ Server-Side Rendering (SSR) │ +│ Dedykowany panel CMS │ +└─────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────┐ +│ IMAGE PROCESSING SERVICE │ +│ Pattern: /img/{size}/{hash}/{filename}.{format} │ +│ Sizes: 24x, 64x, 128x, 400x, 600x, org │ +│ Formats: WebP, SVG, JPG │ +└─────────────────────────────────────────────────────────┘ +``` + +--- + +## 18. SYSTEM OBRAZÓW (WAŻNE!) + +### Pattern URL +``` +https://norda-biznes.info/img/{size}/{hash}/{filename}.{format} +``` + +### Dostępne rozmiary +| Rozmiar | Zastosowanie | +|---------|--------------| +| `24x` | Micro ikony | +| `64x` | Małe ikony | +| `128x` | Avatary, thumbnails | +| `400x` | Karty firm, loga | +| `600x` | Zdjęcia w newsach | +| `org` | Oryginalne (pełny rozmiar) | + +### Formaty +- **WebP** - zdjęcia (nowoczesna kompresja) +- **SVG** - loga firm, ikony +- **JPG** - fallback dla starszych przeglądarek + +### Przykłady +``` +/img/400x/2c55c5/F447f9l70050E1G7B126T2w7S2j8K9B9.webp +/img/128x/e30ee4/T5J7a8n8M0g0J1R7Q2C5u6t0p2B2j2n5.webp +/img/org/ca6339/S5K900z840X0T1q7T619j0T7W4l8H9B8.jpg +``` + +### Implementacja +Prawdopodobnie własny image processing service (podobny do Imgproxy/Thumbor) lub skrypt PHP do dynamicznego skalowania. + +--- + +## 19. CSS ANIMACJE (SZCZEGÓŁY) + +### Zdefiniowane @keyframes +```css +/* Podstawowe animacje fade */ +@keyframes fadeIn { ... } +@keyframes fadeInDown { ... } +@keyframes fadeInLeft { ... } +@keyframes fadeInRight { ... } +@keyframes fadeInUp { ... } +@keyframes fadeOut { ... } + +/* Lightbox animacje (SimpleLightbox?) */ +@keyframes slbOverlay { ... } +@keyframes slbEnter { ... } +@keyframes slbEnterNext { ... } +@keyframes slbEnterPrev { ... } +``` + +### Animacje scroll (IntersectionObserver) +Elementy z klasami `fadeIn`, `fadeInLeft` są animowane przy scrollu używając natywnego IntersectionObserver API - bez zewnętrznych bibliotek (AOS, GSAP). + +### Brak zewnętrznych bibliotek animacji +- ❌ GSAP +- ❌ AOS (Animate On Scroll) +- ❌ Framer Motion +- ❌ Anime.js +- ✅ Własna implementacja CSS + IntersectionObserver + +--- + +## 20. PWA (Progressive Web App) + +### Manifest +``` +URL: /public/images/favicon/site.webmanifest +Display: standalone +Theme color: #ffffff +Background color: #ffffff +``` + +### Ikony PWA +``` +/android-chrome-192x192.png +/android-chrome-384x384.png +``` + +### Favicon set +``` +/public/images/favicon/favicon-32x32.png +/public/images/favicon/apple-touch-icon.png +``` + +### Status PWA +Podstawowa konfiguracja - brak Service Worker offline, brak push notifications. + +--- + +## 21. SEO I META TAGI + +### Open Graph +```html + + + + + +``` + +### Twitter Cards +```html + + + + +``` + +### Resource Hints +```html + + +``` + +### Google Analytics +``` +Tracking ID: G-TCT7QR17L5 +``` + +--- + +## 22. MOŻLIWOŚCI ADAPTACJI + +### Co można skopiować bezpośrednio: +1. ✅ Paleta kolorów (CSS variables) +2. ✅ Typografia (Poppins + rozmiary) +3. ✅ Style przycisków (asymetryczny radius) +4. ✅ Animacje CSS (@keyframes) +5. ✅ Breakpointy responsywności +6. ✅ Struktura sekcji + +### Co wymaga własnej implementacji: +1. ⚠️ System obrazów (własny image processing) +2. ⚠️ Panel CMS (Pixlab framework) +3. ⚠️ Karuzela logotypów (custom lub Swiper/Splide) +4. ⚠️ Animacje scroll (IntersectionObserver) + +### Inspiracje do rozważenia: +1. 🤔 Hero z ukośnym tłem +2. 🤔 Sekcja "Korzyści członkostwa" +3. 🤔 Testimoniale z avatarami +4. 🤔 Footer z ciemnym tłem + +--- + +## 23. PODSUMOWANIE TECHNOLOGII + +| Warstwa | Technologia | +|---------|-------------| +| **Serwer** | Apache | +| **Backend** | PHP (Pixlab Framework) | +| **Rendering** | SSR (~24ms) | +| **CMS** | Dedykowany panel Pixlab | +| **Frontend** | Tailwind CSS (custom) | +| **JavaScript** | Vanilla JS (bundled) | +| **Animacje** | CSS @keyframes + IntersectionObserver | +| **Obrazy** | Custom image service (WebP, SVG, JPG) | +| **Czcionka** | Poppins (Google Fonts) | +| **Analytics** | Google Analytics 4 | +| **PWA** | Podstawowy manifest | + +--- + +--- + +## 24. SITEMAP I STRUKTURA URL + +### Sitemap +``` +URL: https://norda-biznes.info/sitemap.xml +Liczba URL: 102 +Lastmod: 2026-01-30 +Changefreq: daily +``` + +### Struktura URL +| Typ | Pattern | Przykład | +|-----|---------|----------| +| Strony statyczne | `/{slug}` | `/o-nas`, `/kontakt` | +| Aktualności | `/{slug}-n{ID}` | `/konferencja-w-greenpack-n69` | +| Firmy | `/{slug}-m{ID}` | `/agat-m39`, `/pixlab-softwarehouse-m1` | + +### Lista stron statycznych +``` +/ +/o-nas +/czlonkowie +/aktualnosci +/wydarzenia +/kontakt +/statut +/oplaty-czlonkowskie +/wladze-izby +``` + +### Liczba firm w katalogu +**61 firm** (na dzień 2026-01-30) + +### Przykładowe firmy +- pixlab-softwarehouse-m1 +- sigma-budownictwo-m2 +- kantor-promes-m3 +- wdx-m4 +- bormax-m5 +- inpi-sp-z-o-o-m88 +- agat-m39 +- eura-tech-m27 + +--- + +## 25. PERFORMANCE (MIERZONE) + +### Czas odpowiedzi serwera (TTFB) +``` +Time Total: 84ms +Time Connect: 23ms +Time TTFB: 84ms +``` + +### Performance API (browser) +```javascript +{ + pageLoadTime: 165ms, // Całkowity czas ładowania + domContentLoaded: 164ms, // DOM ready + domInteractive: 160ms, // DOM interaktywny + responseTime: 59ms // Czas odpowiedzi serwera +} +``` + +### Rozmiar DOM +``` +Liczba elementów: 462 (mały DOM) +``` + +### Zasoby +| Typ | Liczba | +|-----|--------| +| Obrazy | 83 | +| Skrypty zewnętrzne | 2 | +| Skrypty inline | 1 | +| CSS zewnętrzne | 2 | +| **Łącznie zasobów** | 48 | + +### Lazy Loading +``` +Obrazy z loading="lazy": 0 (BRAK!) +Obrazy z data-src: 0 +``` +⚠️ **Uwaga:** Strona nie używa lazy loading dla obrazów - potencjalna optymalizacja. + +### Skrypty +``` +Async: 1 (gtag.js) +Defer: 0 +``` + +--- + +## 26. DOSTĘPNOŚĆ (A11Y) + +### Landmarks +| Element | Liczba | Status | +|---------|--------|--------| +| header/banner | 1 | ✅ | +| nav/navigation | 1 | ✅ | +| main | 0 | ⚠️ BRAK | +| footer/contentinfo | 1 | ✅ | + +### Obrazy +| Metryka | Wartość | +|---------|---------| +| Łącznie obrazów | 83 | +| Z atrybutem alt | 83 (100%) ✅ | +| Z pustym alt="" | 28 (dekoracyjne) | +| Bez alt | 0 ✅ | + +### Linki +| Metryka | Wartość | +|---------|---------| +| Łącznie linków | 63 | +| Z tekstem/aria-label | 58 | +| Puste linki | 0 ✅ | + +### Struktura nagłówków +``` +H1: 1 ✅ (jeden na stronę) +H2: 6 +H3: 10 +H4: 0 +``` + +### Brakujące elementy a11y +- ❌ Skip links (brak) +- ❌ Landmark `
` (brak) +- ❌ Focus-visible styles (nie wykryto) + +### Język +```html + +``` +✅ Poprawnie ustawiony + +### ARIA +``` +Elementy z aria-label/aria-labelledby: 36 +``` + +--- + +## 27. KONTRAST KOLORÓW + +### Analiza (WCAG 2.1) +| Element | Kolor | Tło | Ratio | WCAG AA | +|---------|-------|-----|-------|---------| +| H1 | #FFFFFF | ciemne | 21:1 | ✅ PASS | +| H2 | #2E4872 | transparent | 2.29:1 | ⚠️ (tło jest jasne) | +| H3 | #303030 | transparent | 1.59:1 | ⚠️ (tło jest jasne) | +| Links | #464646 | transparent | 2.22:1 | ⚠️ (tło jest jasne) | + +**Uwaga:** Ratio jest liczone względem transparent, więc rzeczywisty kontrast na jasnym tle (#EDF0F5) jest wyższy. + +### Rzeczywiste kontrasty (szacowane) +- H2 (#2E4872) na #EDF0F5: ~7:1 ✅ +- H3 (#303030) na #FFFFFF: ~12:1 ✅ +- Text (#464646) na #FFFFFF: ~8:1 ✅ + +--- + +## 28. SEO STRUCTURED DATA + +### JSON-LD +``` +❌ BRAK - strona nie używa JSON-LD structured data +``` + +### Microdata +``` +❌ BRAK - strona nie używa microdata +``` + +### RDFa +``` +❌ BRAK +``` + +### Open Graph (kompletność) +| Tag | Wartość | Status | +|-----|---------|--------| +| og:title | ✅ | Norda Biznes Regionalna Izba Przedsiębiorców | +| og:description | ✅ | Naszą misją jest ochrona i reprezentacja... | +| og:url | ✅ | https://norda-biznes.info/ | +| og:type | ✅ | website | +| og:image | ✅ | /img/800x/e68450/.jpg | + +### Twitter Cards +| Tag | Wartość | +|-----|---------| +| twitter:card | summary_large_image | +| twitter:title | ✅ | +| twitter:description | ✅ | +| twitter:image | ✅ | + +### Rekomendacja SEO +Dodać JSON-LD dla: +- Organization +- LocalBusiness +- BreadcrumbList + +--- + +## 29. PLIKI BEZPIECZEŃSTWA I KONFIGURACJI + +### robots.txt +``` +❌ BRAK (zwraca 404) +``` + +### security.txt +``` +❌ BRAK (/.well-known/security.txt zwraca 404) +``` + +### sitemap.xml +``` +✅ DOSTĘPNY +URL: https://norda-biznes.info/sitemap.xml +``` + +### PWA Manifest +``` +✅ DOSTĘPNY +URL: /public/images/favicon/site.webmanifest +``` + +--- + +## 30. STRONA 404 (CUSTOM) + +### Design strony błędu +```css +/* Pełnoekranowe tło */ +background: url(/public/images/backgrounds/404_bg.jpg) center no-repeat; +background-size: cover; + +/* Nagłówek 404 */ +h1 { + font-size: 130px; + font-weight: 800; + color: #2E4872; +} + +/* Przycisk powrotu */ +.btn-primary { + border-radius: 0.75rem 0.25rem; /* asymetryczny */ + background-color: rgb(46, 72, 114); +} +``` + +### Elementy strony 404 +- Logo w headerze +- Duży napis "404" +- Tekst: "Strona której szukasz nie została odnaleziona" +- Podtekst: "Możliwe, że strona została przeniesiona lub wpisałeś niepoprawny adres" +- Przycisk: "Wróć do strony głównej" + +--- + +## 31. PEŁNA LISTA IKON SVG + +### Lokalizacja +``` +https://norda-biznes.info/public/images/icons/ +``` + +### Wykryte ikony +| Plik | Zastosowanie | +|------|--------------| +| iconHome.svg | Ikona domu w menu | +| iconArrowLeft.svg | Strzałka w lewo (karuzela) | +| iconArrowRight.svg | Strzałka w prawo (karuzela) | +| iconCalendar.svg | Data wydarzenia | +| iconJoinUs.svg | CTA "Dołącz do nas" | +| iconQuoteBase.svg | Cudzysłów w opiniach | +| iconIn2.svg | LinkedIn | +| iconFacebook.svg | Facebook | +| iconYoutube.svg | YouTube | + +### Inne obrazy SVG +``` +/public/images/logo.svg - Logo główne +/public/images/norda-biznes-logo-footer.svg - Logo footer (białe) +/public/images/star.svg - Gwiazdka (rating?) +``` + +--- + +## 32. PEŁNA LISTA FIRM (61) + +``` +1. pixlab-softwarehouse-m1 +2. sigma-budownictwo-m2 +3. kantor-promes-m3 +4. wdx-m4 +5. bormax-m5 +6. riela-polska-m6 +7. delkom-m7 +8. waterm-m8 +9. cristap-m9 +10. hebel-masiak-i-wspolnicy-adwokaci-i-radcowie-prawni-m10 +11. sibuk-m12 +12. kaszubski-bank-spoldzielczy-m13 +13. seo-partner-m14 +14. biuro-rachunkowosci-perfekta-m15 +15. green-house-systems-m16 +16. graal-m18 +17. rubo-m19 +18. porta-kmi-m20 +19. rotor-m21 +20. p-p-m22 +21. ekofabryka-m23 +22. almares-m24 +23. ttm-m25 +24. el-professional-m26 +25. eura-tech-m27 +26. lean-idea-m28 +27. hotel-spa-wieniawa-m29 +28. phu-ted-m30 +29. orlex-mg-m31 +30. lenap-hale-m34 +31. mkonsult-m35 +32. agis-management-group-m37 +33. chlodnictwo-klimatyzacja-tomasz-nowak-m38 +34. agat-m39 +35. ama-m40 +36. ampery-m41 +37. armet-bis-m42 +38. bibrokers-m43 +39. ekod-m44 +40. eko-laser-m45 +41. el-forte-m46 +42. hillob-m47 +43. joker-m48 +44. kammet-m49 +45. kupsa-coathing-m50 +46. kbms-m51 +47. kancelaria-radcy-prawnego-radoslaw-skwarlo-m52 +48. litwic-litwic-m54 +49. mesan-m56 +50. pucka-gospodarka-komunalna-m57 +51. pg-construction-m58 +52. pro-invest-m60 +53. portal-m61 +54. scrol-m63 +55. semerling-security-m64 +56. phu-witka-m65 +57. wejherplast-m67 +58. rumia-invest-park-m68 +59. sim-rumia-m69 +60. stalpunkt-m70 +61. alumech-m71 +... (i więcej do m95) +``` + +--- + +## 33. RESPONSYWNOŚĆ (MOBILE) + +### Testowane rozdzielczości +- Mobile: 375x812 (iPhone X) +- Desktop: 1920x1080 + +### Mobile Header +``` +┌─────────────────────────────────────┐ +│ [LOGO] [Dołącz do nas] [☰] │ +└─────────────────────────────────────┘ +``` +- Logo po lewej +- CTA button widoczny +- Hamburger menu (☰) zamiast pełnego menu + +### Mobile Hero +- Tytuł: skalowany do mniejszego rozmiaru +- Podtytuł: pełna szerokość +- CTA button: zachowany + +### Mobile karuzela logotypów +- Działa poprawnie +- Strzałki nawigacji widoczne +- 2 loga na raz + +### Mobile sekcja "O nas" +- Tekst: pełna szerokość, czytelny +- Zdjęcie: skalowane do 100% szerokości +- Przyciski: obok siebie (flex-row) + +### Mobile karty firm +``` +Grid: 2 kolumny (sm:grid-cols-2) + 1 kolumna na bardzo małych ekranach +``` + +### Mobile statystyki +- Lista pionowa z ikonami +- Dobrze czytelne + +### Breakpoint behavior +| Element | Mobile (<640px) | Tablet (640-1024px) | Desktop (>1024px) | +|---------|-----------------|---------------------|-------------------| +| Menu | Hamburger | Hamburger | Pełne | +| Karty firm | 1-2 kolumny | 2 kolumny | 4 kolumny | +| Hero images | Ukryte | 2 zdjęcia | 4 zdjęcia | +| Footer | Stack pionowy | 2 kolumny | 3 kolumny | + +### Ocena responsywności +**9/10** - Bardzo dobra implementacja mobile-first z Tailwind CSS + +--- + +## 34. REKOMENDACJE OPTYMALIZACJI + +### Do wdrożenia na norda-biznes.info (gdyby pytali) +1. ❌ Dodać robots.txt +2. ❌ Dodać security.txt +3. ❌ Dodać JSON-LD structured data +4. ❌ Dodać lazy loading obrazów +5. ❌ Dodać skip link +6. ❌ Dodać `
` landmark + +### Do zaadaptowania w nordabiznes.pl +1. ✅ Czcionka Poppins +2. ✅ Paleta kolorów +3. ✅ Asymetryczne przyciski +4. ✅ Struktura sekcji +5. ✅ Custom strona 404 +6. ✅ Animacje fadeIn na scroll + +--- + +--- + +## 35. COOKIES I STORAGE + +### Cookies +``` +❌ BRAK cookies +``` +Strona nie ustawia żadnych cookies (nawet sesyjnych). + +### LocalStorage +``` +❌ PUSTE +``` + +### SessionStorage +``` +❌ PUSTE +``` + +### Service Worker +``` +Obsługa: ✅ (przeglądarka wspiera) +Zarejestrowany: ❌ NIE +``` + +### IndexedDB +``` +Obsługa: ✅ +Używane: ❌ NIE +``` + +### Wniosek +Strona jest **stateless** po stronie klienta - wszystkie dane są renderowane server-side bez persistencji w przeglądarce. + +--- + +## 36. CACHE HEADERS + +### HTML (strona główna) +``` +Cache-Control: BRAK +ETag: BRAK +Expires: BRAK +``` + +### CSS +``` +Content-Type: text/css +Vary: Accept-Encoding +Cache-Control: BRAK +``` + +### Obrazy (SVG) +``` +Content-Type: image/svg+xml +Cache-Control: BRAK +``` + +### Wniosek +⚠️ **Brak explicite cache headers** - cache jest kontrolowany tylko przez domyślne zachowanie przeglądarki. Rekomendacja: dodać `Cache-Control: max-age=31536000` dla statycznych assetów z hashem w nazwie. + +--- + +## 37. PODSUMOWANIE KOMPLETNEJ ANALIZY + +### Co zostało zbadane +| Obszar | Status | +|--------|--------| +| Technologie (framework, serwer) | ✅ | +| Typografia (czcionki, rozmiary) | ✅ | +| Paleta kolorów | ✅ | +| Style przycisków | ✅ | +| Layout i spacing | ✅ | +| Struktura sekcji | ✅ | +| Karty firm | ✅ | +| Nawigacja | ✅ | +| Footer | ✅ | +| Ikony SVG | ✅ | +| Animacje CSS | ✅ | +| Wyszukiwarka | ✅ | +| System obrazów | ✅ | +| Backend/CMS | ✅ | +| PWA | ✅ | +| SEO (meta, OG, Twitter) | ✅ | +| Sitemap | ✅ | +| Performance (timing) | ✅ | +| Dostępność (a11y) | ✅ | +| Kontrast kolorów | ✅ | +| Structured data | ✅ | +| Responsywność (mobile) | ✅ | +| Cookies/Storage | ✅ | +| Cache headers | ✅ | +| Strona 404 | ✅ | +| Lista firm | ✅ | + +### Statystyki raportu +- Liczba sekcji: 37 +- Liczba tabel: 40+ +- Liczba bloków kodu: 50+ +- Liczba zidentyfikowanych firm: 61 +- Liczba URL w sitemap: 102 + +--- + +**Powered by:** Pixlab.pl (twórcy strony źródłowej) +**Kontakt Pixlab:** https://pixlab.pl + +**Analiza wykonana przez:** Claude Code (Claude Opus 4.5) +**Data ostatniej aktualizacji:** 2026-01-30 +**Wersja raportu:** 3.0 (kompletna analiza - 37 sekcji) diff --git a/docs/UI_REDESIGN_CHANGELOG.md b/docs/UI_REDESIGN_CHANGELOG.md new file mode 100644 index 0000000..eb2878c --- /dev/null +++ b/docs/UI_REDESIGN_CHANGELOG.md @@ -0,0 +1,173 @@ +# NordaBiz UI Redesign Changelog + +## Cel projektu +Zmiana wyglądu nordabiznes.pl na zgodny z norda-biznes.info, zachowując wszystkie funkcjonalności. + +--- + +## PRZED ZMIANAMI (Produkcja - 30.01.2026) + +**Screenshot ID:** ss_7892h2ggn + +### Obecny stan: +- **Czcionka:** Inter +- **Primary color:** #2563eb (jasny niebieski) +- **Tło:** #f8fafc +- **Event banner:** pomarańczowy (#f59e0b) +- **NordaGPT banner:** fioletowy (#7c3aed) +- **Karty firm:** cień (box-shadow), hover z translateY +- **Przyciski:** border-radius 8px (symetryczny) + +--- + +## SPRINT 1: Fundamenty (Commit: de46e12) + +**Screenshot ID:** ss_3438lwagj + +### Zmiany: +1. **Czcionka:** Inter → **Poppins** +2. **Primary color:** #2563eb → **#2E4872** +3. **Primary dark:** #1e40af → **#1e3050** +4. **Primary light:** #3b82f6 → **#4a6999** +5. **Tło (background):** #f8fafc → **#EDF0F5** +6. **Border color:** #e2e8f0 → **#e0e4eb** +7. **Border-radius przycisków:** 0.5rem → **12px 4px 12px 4px** (asymetryczny) +8. **Header:** usunięcie border-bottom, cień `0 2px 10px rgba(46, 72, 114, 0.08)` +9. **Footer:** background #1e293b → **#2E4872**, padding 60px/30px + +### Pliki zmienione: +- `templates/base.html` + +--- + +## SPRINT 2: Bannery i karty firm (Commit: 1da42f2) + +**Screenshot ID:** ss_29596hr83 + +### Zmiany: +1. **Event banner:** #f59e0b (pomarańczowy) → **#2E4872** (niebieski) +2. **NordaGPT banner:** #7c3aed (fioletowy) → **#2E4872** (niebieski) +3. **Karty firm:** usunięcie box-shadow, dodanie `border: 1px solid #e0e4eb` +4. **Karty firm hover:** `border-color: var(--primary)` zamiast translateY +5. **Tagi kategorii:** + - background: primary (#2E4872) + - color: white + - font-size: 11px + - text-transform: uppercase + - letter-spacing: 0.5px +6. **Przyciski w bannerach:** asymetryczny border-radius + +### Pliki zmienione: +- `templates/index.html` + +--- + +## SPRINT 3: Strona chatu NordaGPT (Commit: b680e3f) + +**Screenshot ID:** ss_6281tcv2v + +### Zmiany: +1. **Chat header:** #7c3aed/#5b21b6 → **#2E4872/#1e3050** +2. **Sidebar "Nowa rozmowa" button:** fioletowy → niebieski +3. **Message avatars (AI):** fioletowy gradient → niebieski gradient +4. **Input focus:** border-color i box-shadow na niebieski +5. **Send button:** fioletowy gradient → niebieski gradient +6. **Typing indicator dots:** #7c3aed → #2E4872 +7. **Suggestion chips hover:** fioletowy → niebieski +8. **Thinking toggle:** fioletowe akcenty → niebieskie +9. **Fluent CSS:** wszystkie zmienne primary na NordaBiz blue + +### Pliki zmienione: +- `templates/chat.html` +- `static/css/fluent-nordabiz.css` + +--- + +## SPRINT 6: Karty firm i tagi (Commit: 64583b6) + +**Screenshot ID:** ss_sprint6 + +### Zmiany: +1. **Karty firm border-radius:** `8px` → `0` (ostre rogi jak na źródle) +2. **Karty firm border:** `#e0e4eb` → `#E4E4E4` +3. **Tagi kategorii background:** niebieski primary → `#EDF0F5` (szary) +4. **Tagi kategorii color:** biały → `#464646` (ciemny) +5. **Text primary:** `#1e293b` → `#303030` +6. **Text secondary:** `#64748b` → `#464646` + +### Pliki zmienione: +- `templates/base.html` +- `templates/index.html` + +--- + +## SPRINT 5: Landing page (Commit: ede9d09) + +**Screenshot ID:** ss_sprint5 + +### Zmiany: +1. **Hero gradient:** `#1e40af/#2563eb/#3b82f6` → `#1e3050/#2E4872/#4a6999` +2. **Accent color:** `#2563eb` → `#2E4872` +3. **Hero section:** `data-animate="fadeIn"` +4. **Stats section:** `data-animate="fadeInUp"` +5. **CTA section:** `data-animate="fadeInUp"` + +### Pliki zmienione: +- `templates/landing.html` + +--- + +## SPRINT 4: Animacje scroll (Commit: 6e1c46e) + +**Screenshot ID:** ss_sprint4 + +### Zmiany: +1. **Nowy plik:** `static/js/scroll-animations.js` z IntersectionObserver +2. **CSS keyframes:** fadeIn, fadeInUp, fadeInLeft, fadeInRight, scaleIn +3. **Event banner:** `data-animate="fadeIn"` +4. **Chat banner:** `data-animate="fadeIn"` +5. **Search section:** `data-animate="fadeIn"` +6. **Karty firm:** `data-animate="fadeInUp"` z delay stagger (1-6) +7. **Accessibility:** `prefers-reduced-motion` wsparcie + +### Pliki zmienione: +- `templates/base.html` +- `templates/index.html` +- `static/js/scroll-animations.js` (NOWY) + +--- + +## PODSUMOWANIE ZMIAN + +| Element | PRZED | PO | +|---------|-------|-----| +| Czcionka | Inter | **Poppins** | +| Primary | #2563eb | **#2E4872** | +| Tło | #f8fafc | **#EDF0F5** | +| Border-radius btn | 8px | **12px 4px** | +| Event banner | #f59e0b | **#2E4872** | +| NordaGPT | #7c3aed | **#2E4872** | +| Karty firm | box-shadow | **border** | +| Tagi | szare, małe | **uppercase, primary** | +| Footer | #1e293b | **#2E4872** | +| Animacje scroll | brak | **fadeIn + IntersectionObserver** | +| Landing hero | #1e40af/#2563eb | **#1e3050/#2E4872** | +| Karty firm radius | 8px | **0 (ostre rogi)** | +| Tagi kategorii | niebieski bg | **szary (#EDF0F5)** | +| Tekst body | #1e293b | **#303030** | + +--- + +## Screenshot IDs (do osadzenia w HTML) + +1. `ss_7892h2ggn` - PRZED zmianami +2. `ss_3438lwagj` - Po Sprint 1 +3. `ss_29596hr83` - Po Sprint 2 +4. `ss_6281tcv2v` - Po Sprint 3 (chat) +5. `ss_sprint4` - Po Sprint 4 (animacje) +6. `ss_sprint5` - Po Sprint 5 (landing page) +7. `ss_sprint6` - Po Sprint 6 (karty firm, tagi) + +--- + +Data dokumentacji: 2026-01-30 diff --git a/docs/screenshots/screenshot-0-PRZED.png b/docs/screenshots/screenshot-0-PRZED.png new file mode 100644 index 0000000..d07565b Binary files /dev/null and b/docs/screenshots/screenshot-0-PRZED.png differ diff --git a/docs/screenshots/screenshot-1-sprint1.png b/docs/screenshots/screenshot-1-sprint1.png new file mode 100644 index 0000000..773f903 Binary files /dev/null and b/docs/screenshots/screenshot-1-sprint1.png differ diff --git a/docs/screenshots/screenshot-2-sprint2.png b/docs/screenshots/screenshot-2-sprint2.png new file mode 100644 index 0000000..1b4abce Binary files /dev/null and b/docs/screenshots/screenshot-2-sprint2.png differ diff --git a/docs/screenshots/screenshot-3-sprint3.png b/docs/screenshots/screenshot-3-sprint3.png new file mode 100644 index 0000000..5eec0b4 Binary files /dev/null and b/docs/screenshots/screenshot-3-sprint3.png differ diff --git a/docs/screenshots/screenshot-4-chat.png b/docs/screenshots/screenshot-4-chat.png new file mode 100644 index 0000000..c5e4a39 Binary files /dev/null and b/docs/screenshots/screenshot-4-chat.png differ diff --git a/docs/screenshots/screenshot-4-sprint4.png b/docs/screenshots/screenshot-4-sprint4.png new file mode 100644 index 0000000..5b3c6ed Binary files /dev/null and b/docs/screenshots/screenshot-4-sprint4.png differ diff --git a/docs/screenshots/screenshot-5-sprint5.png b/docs/screenshots/screenshot-5-sprint5.png new file mode 100644 index 0000000..c9afafd Binary files /dev/null and b/docs/screenshots/screenshot-5-sprint5.png differ diff --git a/docs/screenshots/screenshot-6-sprint6.png b/docs/screenshots/screenshot-6-sprint6.png new file mode 100644 index 0000000..6879c2c Binary files /dev/null and b/docs/screenshots/screenshot-6-sprint6.png differ diff --git a/docs/screenshots/screenshot-before-sprint4.png b/docs/screenshots/screenshot-before-sprint4.png new file mode 100644 index 0000000..7e7e236 Binary files /dev/null and b/docs/screenshots/screenshot-before-sprint4.png differ diff --git a/docs/screenshots/screenshot-before-sprint5.png b/docs/screenshots/screenshot-before-sprint5.png new file mode 100644 index 0000000..c9afafd Binary files /dev/null and b/docs/screenshots/screenshot-before-sprint5.png differ diff --git a/docs/screenshots/screenshot-before-sprint6.png b/docs/screenshots/screenshot-before-sprint6.png new file mode 100644 index 0000000..966fad8 Binary files /dev/null and b/docs/screenshots/screenshot-before-sprint6.png differ diff --git a/docs/ui-redesign-comparison.html b/docs/ui-redesign-comparison.html new file mode 100644 index 0000000..9466d9e --- /dev/null +++ b/docs/ui-redesign-comparison.html @@ -0,0 +1,722 @@ + + + + + + NordaBiz UI Redesign - Porównanie zmian + + + + +
+

NordaBiz UI Redesign

+

Dokumentacja zmian graficznych: norda-biznes.info → nordabiznes.pl

+

Data: 30 stycznia 2026

+
+ +
+ +
+
+ PRZED +

Stan wyjściowy (Produkcja)

+
+ +
+
+

Czcionka

+
Inter (Google Fonts)
+
+
+

Kolor primary

+
+ + #2563eb (jasny niebieski) +
+
+
+

Tło strony

+
+ + #f8fafc +
+
+
+

Event banner

+
+ + #f59e0b (pomaranczowy) +
+
+
+

NordaGPT banner

+
+ + #7c3aed (fioletowy) +
+
+
+

Przyciski border-radius

+
8px (symetryczny)
+
+
+ +
+ Screenshot przed zmianami +
Stan przed zmianami (commit d9f32b7)
+
+
+ + +
+
+ SPRINT 1 +

Fundamenty

+ de46e12 +
+ +
+
+

Czcionka

+
+ Inter + + Poppins +
+
+
+

Kolor primary

+
+ + + + #2E4872 +
+
+
+

Tło strony

+
+ + + + #EDF0F5 +
+
+
+

Border-radius przycisków

+
+ 8px + + 12px 4px 12px 4px +
+
+
+

Header

+
+ border-bottom + + subtelny cien +
+
+
+

Footer

+
+ + + + #2E4872 +
+
+
+ +
+

Zmienione pliki:

+ templates/base.html +
+ +
+ Screenshot po Sprint 1 +
Po Sprint 1 (commit de46e12)
+
+
+ + +
+
+ SPRINT 2 +

Bannery i karty firm

+ 1da42f2 +
+ +
+
+

Event banner

+
+ + + + #2E4872 +
+
+
+

NordaGPT banner

+
+ + + + #2E4872 +
+
+
+

Karty firm - styl

+
+ box-shadow + + border 1px solid +
+
+
+

Karty firm - hover

+
+ translateY(-2px) + + border-color: primary +
+
+
+

Tagi kategorii

+
+ szare, male litery + + UPPERCASE, primary +
+
+
+

Przyciski w bannerach

+
+ asymetryczny border-radius +
+
+
+ +
+

Zmienione pliki:

+ templates/index.html +
+ +
+ Screenshot po Sprint 2 +
Po Sprint 2 (commit 1da42f2)
+
+
+ + +
+
+ SPRINT 3 +

Strona chatu NordaGPT

+ b680e3f +
+ +
+
+

Chat header

+
+ + + + #2E4872 +
+
+
+

Sidebar button

+
+ fioletowy + + niebieski +
+
+
+

AI Message avatar

+
+ fioletowy gradient + + niebieski gradient +
+
+
+

Input focus

+
+ #7c3aed + + #2E4872 +
+
+
+

Send button

+
+ fioletowy + + niebieski +
+
+
+

Fluent CSS

+
+ wszystkie zmienne primary +
+
+
+ +
+

Zmienione pliki:

+ templates/chat.html + static/css/fluent-nordabiz.css +
+ +
+ Screenshot po Sprint 3 - strona główna +
Po Sprint 3 - strona glowna (commit b680e3f)
+
+
+ Screenshot po Sprint 3 - strona chatu +
Po Sprint 3 - strona /chat (commit b680e3f)
+
+
+ + +
+
+ SPRINT 4 +

Animacje scroll

+ 6e1c46e +
+ +
+
+

IntersectionObserver

+
+ Nowy plik scroll-animations.js +
+
+
+

CSS Keyframes

+
+ fadeIn, fadeInUp, fadeInLeft, fadeInRight, scaleIn +
+
+
+

Event banner

+
+ data-animate="fadeIn" +
+
+
+

Chat banner

+
+ data-animate="fadeIn" +
+
+
+

Karty firm

+
+ data-animate="fadeInUp" + delay stagger +
+
+
+

Reduced motion

+
+ prefers-reduced-motion wsparcie +
+
+
+ +
+

Zmienione pliki:

+ templates/base.html + templates/index.html + static/js/scroll-animations.js (NOWY) +
+ +
+ Screenshot przed Sprint 4 +
Przed Sprint 4 (commit b680e3f)
+
+
+ Screenshot po Sprint 4 +
Po Sprint 4 (commit 6e1c46e)
+
+
+ + +
+
+ SPRINT 5 +

Landing page

+ ede9d09 +
+ +
+
+

Hero gradient

+
+ + + + NordaBiz blue +
+
+
+

Accent color

+
+ + + + #2E4872 +
+
+
+

Hero section

+
+ data-animate="fadeIn" +
+
+
+

Stats section

+
+ data-animate="fadeInUp" +
+
+
+

CTA section

+
+ data-animate="fadeInUp" +
+
+
+ +
+

Zmienione pliki:

+ templates/landing.html +
+ +
+ Screenshot przed Sprint 5 +
Przed Sprint 5 - landing page (commit 6e1c46e)
+
+
+ Screenshot po Sprint 5 +
Po Sprint 5 - landing page (commit ede9d09)
+
+
+ + +
+
+ PODSUMOWANIE +

Wszystkie zmiany

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementPRZEDPO
CzcionkaInterPoppins
Kolor primary #2563eb #2E4872
Tło strony #f8fafc #EDF0F5
Border-radius btn8px12px 4px
Event banner #f59e0b #2E4872
NordaGPT #7c3aed #2E4872
Karty firmbox-shadowborder
Tagi kategoriiszare, maleUPPERCASE, primary
Footer #1e293b #2E4872
Animacje scrollbrakfadeIn + IntersectionObserver
Landing hero stary niebieski NordaBiz blue
+
+
+ + + + diff --git a/scripts/fetch_ceidg_api.py b/scripts/fetch_ceidg_api.py index d4812f1..d0d399a 100644 --- a/scripts/fetch_ceidg_api.py +++ b/scripts/fetch_ceidg_api.py @@ -464,9 +464,9 @@ def update_company_from_ceidg(company_id: int, ceidg_data: dict, db) -> bool: company.pkd_code = pkd_glowny.get("kod") company.pkd_description = pkd_glowny.get("nazwa") - # Wszystkie PKD + # Wszystkie PKD z CEIDG if ceidg_data.get("pkd"): - company.pkd_codes = ceidg_data.get("pkd") + company.ceidg_pkd_list = ceidg_data.get("pkd") # Data rozpoczęcia działalności if ceidg_data.get("dataRozpoczecia"): diff --git a/scripts/search_ceidg_by_name.py b/scripts/search_ceidg_by_name.py new file mode 100644 index 0000000..0c2eeb2 --- /dev/null +++ b/scripts/search_ceidg_by_name.py @@ -0,0 +1,493 @@ +#!/usr/bin/env python3 +""" +CEIDG Search by Name - wyszukuje firmy w CEIDG po nazwie + +Dla firm bez NIP w bazie - szuka w portalu CEIDG po nazwie firmy +i weryfikuje wyniki przez porównanie adresu/telefonu. + +Portal CEIDG: https://aplikacja.ceidg.gov.pl/ceidg/ceidg.public.ui/search.aspx + +Usage: + python scripts/search_ceidg_by_name.py # Szukaj wszystkich + python scripts/search_ceidg_by_name.py --id 119 # Szukaj konkretnej firmy + python scripts/search_ceidg_by_name.py --apply # Zapisz znalezione NIP +""" + +import os +import sys +import re +import argparse +import time +import json +from pathlib import Path +from datetime import datetime +from dataclasses import dataclass, asdict, field +from typing import Optional, List +from difflib import SequenceMatcher + +# Add parent directory to path for imports +sys.path.insert(0, str(Path(__file__).parent.parent)) + +try: + from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeout +except ImportError: + print("Playwright nie jest zainstalowany. Uruchom: pip install playwright && playwright install chromium") + sys.exit(1) + +from database import SessionLocal, Company + +# Output directory +RESULTS_DIR = Path(__file__).parent.parent / "data" / "ceidg_search_results" +RESULTS_DIR.mkdir(parents=True, exist_ok=True) + +# Domains to skip (public email providers) +SKIP_DOMAINS = { + 'gmail.com', 'wp.pl', 'onet.pl', 'op.pl', 'interia.pl', + 'o2.pl', 'poczta.fm', 'yahoo.com', 'hotmail.com', 'outlook.com' +} + + +@dataclass +class CEIDGSearchResult: + """Wynik wyszukiwania w CEIDG""" + company_id: int + company_name: str + search_query: str + + # Znalezione dane + found_nip: Optional[str] = None + found_regon: Optional[str] = None + found_name: Optional[str] = None + found_owner: Optional[str] = None + found_address: Optional[str] = None + found_status: Optional[str] = None + + # Weryfikacja + matches: List[str] = field(default_factory=list) # Co się zgadza + confidence: str = "low" # low, medium, high + verified: bool = False + + error: Optional[str] = None + searched_at: str = "" + + def __post_init__(self): + if not self.searched_at: + self.searched_at = datetime.now().isoformat() + + def to_dict(self): + return asdict(self) + + +def normalize_phone(phone: str) -> str: + """Normalizuje numer telefonu do samych cyfr""" + if not phone: + return "" + return re.sub(r'[^0-9]', '', phone) + + +def normalize_address(address: str) -> str: + """Normalizuje adres do porównania""" + if not address: + return "" + # Lowercase, usuń znaki specjalne + addr = address.lower() + addr = re.sub(r'[^\w\s]', ' ', addr) + addr = re.sub(r'\s+', ' ', addr).strip() + return addr + + +def similarity(a: str, b: str) -> float: + """Oblicza podobieństwo dwóch stringów (0-1)""" + if not a or not b: + return 0.0 + return SequenceMatcher(None, a.lower(), b.lower()).ratio() + + +def validate_nip(nip: str) -> bool: + """Waliduje NIP (checksum)""" + nip = re.sub(r'[^0-9]', '', nip) + if len(nip) != 10: + return False + + weights = [6, 5, 7, 2, 3, 4, 5, 6, 7] + try: + checksum = sum(int(nip[i]) * weights[i] for i in range(9)) % 11 + return checksum == int(nip[9]) + except (ValueError, IndexError): + return False + + +def extract_nip_from_text(text: str) -> Optional[str]: + """Wyciąga NIP z tekstu""" + patterns = [ + r'NIP[:\s]*(\d{3}[-\s]?\d{3}[-\s]?\d{2}[-\s]?\d{2})', + r'NIP[:\s]*(\d{10})', + r'\b(\d{10})\b', # Standalone 10 digits + ] + + for pattern in patterns: + matches = re.findall(pattern, text, re.IGNORECASE) + for match in matches: + nip = re.sub(r'[^0-9]', '', match) + if validate_nip(nip): + return nip + return None + + +def extract_regon_from_text(text: str) -> Optional[str]: + """Wyciąga REGON z tekstu""" + patterns = [ + r'REGON[:\s]*(\d{9,14})', + ] + + for pattern in patterns: + matches = re.findall(pattern, text, re.IGNORECASE) + for match in matches: + regon = re.sub(r'[^0-9]', '', match) + if len(regon) in (9, 14): + return regon + return None + + +def search_ceidg(company: Company) -> CEIDGSearchResult: + """ + Szuka firmy w CEIDG po nazwie. + Portal CEIDG: https://aplikacja.ceidg.gov.pl/ceidg/ceidg.public.ui/search.aspx + """ + # Prepare search query + search_name = company.name + + # Remove common suffixes (CEIDG is for sole proprietorships, not companies) + for suffix in [' sp. z o.o.', ' sp.z o.o.', ' s.c.', ' s.j.']: + search_name = search_name.replace(suffix, '').replace(suffix.upper(), '') + + search_name = search_name.strip() + + result = CEIDGSearchResult( + company_id=company.id, + company_name=company.name, + search_query=search_name + ) + + print(f" Szukam w CEIDG: '{search_name}'") + + with sync_playwright() as p: + browser = p.chromium.launch(headless=True) + context = browser.new_context( + user_agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" + ) + page = context.new_page() + page.set_default_timeout(60000) # 60 seconds default timeout + + try: + # Go to CEIDG search page + print(" → Ładuję stronę CEIDG...") + page.goto("https://aplikacja.ceidg.gov.pl/ceidg/ceidg.public.ui/search.aspx", timeout=60000) + time.sleep(3) + + # Wait for page to be ready + page.wait_for_load_state("domcontentloaded", timeout=30000) + print(" → Strona załadowana") + + # Try multiple selectors for company name field + firma_input = None + selectors = [ + "input[id*='txtFirma']", + "input[id*='Firma']", + "input[name*='Firma']", + "#ctl00_MainContent_txtFirma", + "input[placeholder*='Nazwa firmy']", + ] + + for selector in selectors: + try: + elem = page.locator(selector).first + if elem.is_visible(timeout=2000): + firma_input = elem + print(f" → Znaleziono pole wyszukiwania: {selector}") + break + except: + continue + + if not firma_input: + # Take screenshot for debugging + screenshot_path = RESULTS_DIR / f"ceidg_debug_{company.id}.png" + page.screenshot(path=str(screenshot_path)) + result.error = f"Nie znaleziono pola wyszukiwania. Screenshot: {screenshot_path}" + return result + + # Fill in company name + firma_input.fill(search_name) + print(f" → Wpisano: '{search_name}'") + time.sleep(1) + + # Add city if available + if company.address_city: + city_selectors = [ + "input[id*='txtMiasto']", + "input[id*='Miasto']", + "#ctl00_MainContent_txtMiasto", + ] + for selector in city_selectors: + try: + city_input = page.locator(selector).first + if city_input.is_visible(timeout=2000): + city_input.fill(company.address_city) + print(f" → Dodano miasto: '{company.address_city}'") + break + except: + continue + + # Find and click search button + search_selectors = [ + "input[id*='btnSearch']", + "input[value='Szukaj']", + "button:has-text('Szukaj')", + "#ctl00_MainContent_btnSearch", + ] + + search_clicked = False + for selector in search_selectors: + try: + btn = page.locator(selector).first + if btn.is_visible(timeout=2000): + btn.click() + search_clicked = True + print(" → Kliknięto Szukaj") + break + except: + continue + + if not search_clicked: + page.keyboard.press("Enter") + print(" → Wysłano Enter") + + # Wait for results + time.sleep(5) + page.wait_for_load_state("networkidle", timeout=30000) + print(" → Wyniki załadowane") + + # Check for "no results" message + page_text_check = page.inner_text("body") + if "Brak wyników" in page_text_check or "nie znaleziono" in page_text_check.lower(): + result.error = "Nie znaleziono w CEIDG" + return result + + # Find details link + details_selectors = [ + "a:has-text('Szczegóły')", + "a[href*='SearchDetails']", + "a[id*='Details']", + "a.details-link", + ] + + details_link = None + for selector in details_selectors: + try: + link = page.locator(selector).first + if link.is_visible(timeout=3000): + details_link = link + break + except: + continue + + if not details_link: + # Maybe direct results page? + page_text = page.inner_text("body") + nip = extract_nip_from_text(page_text) + if nip: + result.found_nip = nip + result.found_regon = extract_regon_from_text(page_text) + result = verify_result(result, company) + return result + + result.error = "Brak linku do szczegółów" + screenshot_path = RESULTS_DIR / f"ceidg_results_{company.id}.png" + page.screenshot(path=str(screenshot_path)) + return result + + # Click details link + details_link.click() + print(" → Kliknięto Szczegóły") + time.sleep(4) + page.wait_for_load_state("networkidle", timeout=30000) + + # Extract data from details page + page_text = page.inner_text("body") + + # Extract NIP + result.found_nip = extract_nip_from_text(page_text) + result.found_regon = extract_regon_from_text(page_text) + + # Extract owner name + owner_match = re.search(r'Imię i nazwisko[:\s]*([A-ZĄĆĘŁŃÓŚŹŻ][a-ząćęłńóśźż]+\s+[A-ZĄĆĘŁŃÓŚŹŻ][a-ząćęłńóśźż]+)', page_text) + if owner_match: + result.found_owner = owner_match.group(1).strip() + + # Extract company name from CEIDG + firma_match = re.search(r'Firma przedsiębiorcy[:\s]*(.+?)(?:\n|Adres|Status)', page_text, re.DOTALL) + if firma_match: + result.found_name = firma_match.group(1).strip()[:200] + + # Extract address + addr_match = re.search(r'Adres[:\s]*(.+?)(?:\n\n|Status|Data)', page_text, re.DOTALL) + if addr_match: + result.found_address = addr_match.group(1).strip()[:200] + + # Extract status + if 'AKTYWNY' in page_text.upper(): + result.found_status = 'AKTYWNY' + elif 'ZAWIESZONY' in page_text.upper(): + result.found_status = 'ZAWIESZONY' + elif 'WYKREŚLONY' in page_text.upper(): + result.found_status = 'WYKREŚLONY' + + # Verify the result + result = verify_result(result, company) + + except PlaywrightTimeout: + result.error = "Timeout" + except Exception as e: + result.error = str(e)[:200] + finally: + browser.close() + + return result + + +def verify_result(result: CEIDGSearchResult, company: Company) -> CEIDGSearchResult: + """ + Weryfikuje czy znaleziony wynik pasuje do naszej firmy. + """ + if not result.found_nip: + result.error = "NIP nie znaleziony na stronie szczegółów" + return result + + matches = [] + + # 1. Sprawdź podobieństwo nazwy + if result.found_name: + name_sim = similarity(company.name, result.found_name) + if name_sim > 0.7: + matches.append(f"nazwa ({name_sim:.0%})") + elif name_sim > 0.5: + matches.append(f"nazwa częściowa ({name_sim:.0%})") + + # 2. Sprawdź adres/miasto + if result.found_address and company.address_city: + if company.address_city.lower() in result.found_address.lower(): + matches.append("miasto") + + if result.found_address and company.address_street: + if company.address_street.lower()[:10] in result.found_address.lower(): + matches.append("ulica") + + # 3. Sprawdź właściciela (jeśli mamy w nazwie) + if result.found_owner: + owner_parts = result.found_owner.lower().split() + company_name_lower = company.name.lower() + for part in owner_parts: + if len(part) > 3 and part in company_name_lower: + matches.append("właściciel w nazwie") + break + + # Determine confidence + result.matches = matches + + if len(matches) >= 2: + result.confidence = "high" + result.verified = True + elif len(matches) == 1 and "nazwa" in matches[0]: + result.confidence = "medium" + result.verified = True + elif len(matches) == 1: + result.confidence = "low" + result.verified = False + else: + result.confidence = "low" + result.verified = False + + return result + + +def get_companies_without_nip(db, company_id: int = None) -> List[Company]: + """Pobiera firmy bez NIP""" + query = db.query(Company).filter( + (Company.nip == None) | (Company.nip == '') + ) + + if company_id: + query = query.filter(Company.id == company_id) + + return query.order_by(Company.name).all() + + +def main(): + parser = argparse.ArgumentParser(description="Search CEIDG by company name") + parser.add_argument('--id', type=int, help="Search specific company ID") + parser.add_argument('--apply', action='store_true', help="Apply found NIPs to database") + parser.add_argument('--limit', type=int, default=50, help="Limit number of companies to search") + parser.add_argument('--output', type=str, help="Output JSON file path") + args = parser.parse_args() + + db = SessionLocal() + + try: + companies = get_companies_without_nip(db, args.id) + + if not args.id: + companies = companies[:args.limit] + + print(f"\n=== Wyszukiwanie {len(companies)} firm w CEIDG ===\n") + + results = [] + found_count = 0 + verified_count = 0 + + for i, company in enumerate(companies, 1): + print(f"[{i}/{len(companies)}] {company.name}") + + result = search_ceidg(company) + results.append(result) + + if result.found_nip: + found_count += 1 + status = "✓" if result.verified else "?" + print(f" {status} NIP: {result.found_nip} (confidence: {result.confidence})") + print(f" Matches: {', '.join(result.matches) if result.matches else 'brak'}") + + if result.verified: + verified_count += 1 + + if args.apply: + company.nip = result.found_nip + if result.found_regon and not company.regon: + company.regon = result.found_regon + db.commit() + print(f" → Zapisano do bazy") + elif result.error: + print(f" ✗ {result.error}") + + # Rate limiting - CEIDG może blokować + time.sleep(3) + + # Save results to JSON + output_file = args.output or (RESULTS_DIR / f"ceidg_search_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json") + with open(output_file, 'w', encoding='utf-8') as f: + json.dump([r.to_dict() for r in results], f, ensure_ascii=False, indent=2) + + print(f"\n=== Podsumowanie ===") + print(f"Przeszukano: {len(companies)} firm") + print(f"Znaleziono NIP: {found_count}") + print(f"Zweryfikowano: {verified_count}") + print(f"Wyniki zapisane: {output_file}") + + if verified_count > 0 and not args.apply: + print(f"\nUżyj --apply aby zapisać zweryfikowane NIP do bazy") + + finally: + db.close() + + +if __name__ == "__main__": + main() diff --git a/static/img/icons-preview-v2.html b/static/img/icons-preview-v2.html new file mode 100644 index 0000000..7edf81c --- /dev/null +++ b/static/img/icons-preview-v2.html @@ -0,0 +1,353 @@ + + + + + NordaGPT - Propozycje ikon v2 + + + +

NordaGPT - Propozycje ikon v2

+

5 wariantów robota + 5 wariantów litery N

+ +

🤖 Warianty: Przyjazny Robot

+
+ + +
+
R1
+
+ + + + + + + + + + + + + + +
+
Uśmiechnięty Krąg
+
Minimalistyczny, zamknięte oczy = szczęście
+
+ + +
+
R2
+
+ + + + + + + + + + + + + + + + + + + +
+
Duże Oczy
+
Zielony robot z dużymi, uroczymi oczami
+
+ + +
+
R3
+
+ + + + + + + + + + + + + + + + + + +
+
Pixel Robot
+
Styl retro/pixel art, fioletowy
+
+ + +
+
R4
+
+ + + + + + + + + + + + + + + + + + + + +
+
Nowoczesny
+
Sleek design z wizjerem
+
+ + +
+
R5
+
+ + + + + + + + + + + + + + + + + + + +
+
Różowy z Sercem
+
Przyjazny, ciepły, z rumieńcami
+
+ +
+ +
+ +

🅽 Warianty: Litera N + GPT

+
+ + +
+
N1
+
+ + + + + + + + + + + + + + + + GPT + +
+
Klasyczne N
+
Oryginalna wersja z badge GPT
+
+ + +
+
N2
+
+ + + + + + + + + + GPT + +
+
N Outline
+
Konturowe N z GPT na dole
+
+ + +
+
N3
+
+ + + + + + + + + + + + + + + GPT + + + +
+
Bold N
+
Grube N z chipem GPT
+
+ + +
+
N4
+
+ + + + + + + + + GPT + + + +
+
Geometryczne N
+
N z prostokątów z GPT w środku
+
+ + +
+
N5
+
+ + + + + + + + + + + + + + + + + + GPT + + + +
+
Neonowe N
+
Efekt neonu, nocny vibe
+
+ +
+ +
+

+ Wybierz numer ikony do wdrożenia +

+ + + \ No newline at end of file diff --git a/static/img/icons-preview-v3.html b/static/img/icons-preview-v3.html new file mode 100644 index 0000000..0b04c44 --- /dev/null +++ b/static/img/icons-preview-v3.html @@ -0,0 +1,337 @@ + + + + + NordaGPT - Propozycje ikon v3 + + + +

NordaGPT - Propozycje ikon v3

+

Warianty R4 (Nowoczesny Robot) + N5 (Neonowe N)

+ +

🤖 Warianty: Nowoczesny Robot z Wizjerem

+
+ + +
+
A
+
+ + + + + + + + + + + + + + + + + +
+
Zielony INPI
+
Kolory INPI, świecące oczy
+
+ + +
+
B
+
+ + + + + + + + + + + + + + + + + +
+
Niebieski + Uśmiech
+
Okrągłe oczy, delikatny uśmiech
+
+ + +
+
C
+
+ + + + + + + + + + + + + + + + + + GPT + +
+
Norda Navy
+
Granat Norda + GPT w ustach
+
+ + +
+
D
+
+ + + + + + + + + + +
+
Line Art
+
Minimalistyczny kontur
+
+ + +
+
E
+
+ + + + + + + + + + + + + + + + + + + GPT + +
+
Fiolet + Badge
+
Fioletowy z badge GPT
+
+ +
+ +
+ +

✨ Warianty: Neonowe N

+
+ + +
+
A
+
+ + + + + + + + + + + GPT + + +
+
Zielony Neon
+
Klasyczny zielony, styl INPI
+
+ + +
+
B
+
+ + + + + + + + + + + GPT + + +
+
Cyan Neon
+
Turkusowy, futurystyczny
+
+ + +
+
C
+
+ + + + + + + + + + + + + + + GPT + + +
+
Gradient Neon
+
Zielono-fioletowy gradient
+
+ + +
+
D
+
+ + + + + + + + + + + GPT + + +
+
Różowy Neon
+
Magenta, wyrazisty
+
+ + +
+
E
+
+ + + + + + + + + + + + + + + GPT + + +
+
Podwójne N
+
Efekt głębi z badge
+
+ +
+ +
+

+ Podaj kombinację np. "R4-C" lub "N5-A" do wdrożenia +

+ + + \ No newline at end of file diff --git a/static/img/icons-preview.html b/static/img/icons-preview.html new file mode 100644 index 0000000..a2d062f --- /dev/null +++ b/static/img/icons-preview.html @@ -0,0 +1,317 @@ + + + + + NordaGPT - Propozycje ikon + + + +

NordaGPT - Propozycje ikon

+
+ + +
+
1
+
+ + + + + + + + + + + + + + +
+
Gwiazda Polarna
+
Minimalistyczna 4-ramienna gwiazda z akcentem na północ
+
+ + +
+
2
+
+ + + + + + + + + + + + + + +
+
Przyjazny Chat
+
Dymek czatu z animowanymi kropkami i wskaźnikiem północy
+
+ + +
+
3
+
+ + + + + + + + + + + + + + + + N + +
+
Świecący Kompas
+
Klasyczny kompas z efektem świecenia i czerwoną igłą
+
+ + +
+
4
+
+ + + + + + + AI + + +
+
Fala Neuronowa
+
Abstrakcyjne fale mózgowe symbolizujące AI
+
+ + +
+
5
+
+ + + + + + + + + + + + + +
+
Latarnia Morska
+
Symbolizuje przewodnictwo i wskazywanie drogi w biznesie
+
+ + +
+
6
+
+ + + + + + + + + + + + + + + + + + + + + +
+
Przyjazny Robot
+
Uroczy robot z uśmiechem i anteną wskazującą północ
+
+ + +
+
7
+
+ + + + + + + + + + + + + + + + AI + +
+
Magiczna Iskra
+
Błyszcząca gwiazda symbolizująca magię AI
+
+ + +
+
8
+
+ + + + + + + + + + + + + + + + AI + +
+
Litera N
+
Stylizowana litera N (Norda) z badge AI
+
+ + +
+
9
+
+ + + + + + + + + AI + + + + + +
+
Orbita
+
Orbity symbolizujące połączenia i sieć biznesową
+
+ + +
+
10
+
+ + + + + + + + + + + + + + + + + + + N + +
+
Prosty Kompas
+
Elegancki, minimalistyczny kompas z gradientem
+
+ +
+ + \ No newline at end of file