feat(ui): Norda Partner, Strefa Gościa, uproszczenie forum

- Landing page: przycisk "Norda Partner" + kontakt Izby (email, WhatsApp)
- Landing page: link "Strefa Gościa" → norda-biznes.info
- Menu "Więcej": dodano "Strefa Gościa (Izba)" dla zalogowanych
- Forum: ukryto filtry kategorii/statusów (uproszczenie UX)
- README: zmiana "AI Assistant" → "NordaGPT"
- Skrypt import firmy testowej "Kaszubia 2030"
- .gitignore: wykluczenie notatek ze spotkań (MEETING_*.md)

Zmiany na podstawie spotkania 2026-01-28 i uwag Artura Wiertla.
Wzór nawigacji: Vaillant.pl (Klienci indywidualni / Profesjonaliści)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-28 20:11:35 +01:00
parent bc1657b900
commit b6bbb32483
6 changed files with 125 additions and 11 deletions

1
.gitignore vendored
View File

@ -91,3 +91,4 @@ data/ceidg_json/
# Poufne materiały - NIGDY nie commitować
.private/
docs/MEETING_*.md

View File

@ -1077,7 +1077,7 @@ curl -X POST https://nordabiznes.pl/api/verify-nip \
These endpoints require user authentication (regular or admin):
#### Chat & AI Assistant
#### Chat & NordaGPT
| Endpoint | Method | Description |
|----------|--------|-------------|

View File

@ -0,0 +1,86 @@
#!/usr/bin/env python3
"""
Import firmy testowej Kaszubia 2030 do bazy NordaBiz.
Kaszubia 2030 - firma demonstracyjna/testowa dla celów rozwoju projektu Norda Partner.
"""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from datetime import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database import Company, Category
# DEV: localhost:5433, PROD: 10.22.68.249:5432
DATABASE_URL = os.environ.get('DATABASE_URL', 'postgresql://nordabiz_app:dev_password@localhost:5433/nordabiz')
def import_company():
"""Importuj firmę testową Kaszubia 2030."""
engine = create_engine(DATABASE_URL)
Session = sessionmaker(bind=engine)
session = Session()
try:
# Sprawdź czy firma już istnieje
existing = session.query(Company).filter_by(slug='kaszubia-2030').first()
if existing:
print(f"Firma Kaszubia 2030 już istnieje (ID: {existing.id})")
return existing.id
# Znajdź kategorię "Services" (Usługi)
category = session.query(Category).filter_by(name='Services').first()
if not category:
# Fallback do "Usługi"
category = session.query(Category).filter_by(name='Usługi').first()
company = Company(
slug='kaszubia-2030',
name='Kaszubia 2030',
legal_name='Kaszubia 2030 - Firma Demonstracyjna',
nip=None, # Firma testowa - bez NIP
regon=None,
krs=None,
email='test@kaszubia2030.pl',
phone='+48 000 000 000',
website='https://kaszubia2030.pl',
address_street='ul. Testowa 1',
address_city='Wejherowo',
address_postal='84-200',
category_id=category.id if category else None,
description_short='Firma demonstracyjna projektu Norda Partner - Kaszubia 2030',
description_full='''Kaszubia 2030 to przykładowa firma stworzona na potrzeby testowania
i demonstracji funkcjonalności platformy Norda Biznes Hub (Norda Partner).
Firma reprezentuje wizję rozwoju regionu Kaszub do roku 2030, łącząc:
- Innowacje technologiczne
- Zrównoważony rozwój
- Współpracę regionalną
- Networking biznesowy
Jest powiązana z kontem testowym użytkownika "Testuser Kaszubia 2030"
do celów prezentacyjnych i testowych funkcji platformy.''',
data_quality='enhanced',
status='active'
)
session.add(company)
session.commit()
print(f"✅ Firma Kaszubia 2030 dodana pomyślnie! ID: {company.id}")
print(f" Slug: {company.slug}")
print(f" Kategoria: {category.name if category else 'brak'}")
return company.id
except Exception as e:
session.rollback()
print(f"❌ Błąd podczas importu: {e}")
raise
finally:
session.close()
if __name__ == '__main__':
import_company()

View File

@ -982,6 +982,14 @@
<li><a href="{{ url_for('contacts.contacts_list') }}">Kontakty zewnętrzne</a></li>
<li><a href="{{ url_for('reports.reports_index') }}">Raporty</a></li>
<li><a href="#" onclick="openConnectionsMap(); return false;">Mapa Powiązań</a></li>
<li style="border-top: 1px solid var(--border-color); margin-top: 8px; padding-top: 8px;">
<a href="https://norda-biznes.info" target="_blank" style="display: flex; align-items: center; gap: 8px;">
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/>
</svg>
Strefa Gościa (Izba)
</a>
</li>
</ul>
</li>

View File

@ -355,21 +355,18 @@
</a>
</div>
<!-- Filters -->
<!-- Filters - Uproszczone (ukryte kategorie i statusy) -->
<div class="filters-bar">
<!-- Filtry kategorii i statusów ukryte - forum w fazie upraszczania -->
<!-- Oryginalny kod zachowany w komentarzu na wypadek przywrócenia:
<div class="filter-group">
<span class="filter-label">Kategoria:</span>
<a href="{{ url_for('forum_index', status=status_filter) }}" class="filter-btn {% if not category_filter %}active{% endif %}">Wszystkie</a>
{% for cat in categories %}
<a href="{{ url_for('forum_index', category=cat, status=status_filter) }}" class="filter-btn {% if category_filter == cat %}active{% endif %}">{{ category_labels.get(cat, cat) }}</a>
{% endfor %}
<a href="{{ url_for('forum_index', status=status_filter) }}" class="filter-btn active">Wszystkie</a>
</div>
-->
<div class="filter-group">
<span class="filter-label">Status:</span>
<a href="{{ url_for('forum_index', category=category_filter) }}" class="filter-btn {% if not status_filter %}active{% endif %}">Wszystkie</a>
{% for st in statuses %}
<a href="{{ url_for('forum_index', category=category_filter, status=st) }}" class="filter-btn {% if status_filter == st %}active{% endif %}">{{ status_labels.get(st, st) }}</a>
{% endfor %}
<span class="filter-label" style="color: var(--text-secondary);">💬 Uwagi rozwojowe</span>
<span style="color: var(--text-muted); font-size: var(--font-size-sm); margin-left: var(--spacing-sm);">Zapraszamy do podzielenia się swoimi opiniami</span>
</div>
<div class="filter-group" style="margin-left: auto;">
<button type="button" id="toggleTestBtn" class="filter-btn toggle-test-btn" onclick="toggleTestTopics()">

View File

@ -283,6 +283,12 @@
</div>
<div class="hero-cta">
<a href="{{ url_for('login') }}" class="btn btn-hero btn-white" style="background: linear-gradient(135deg, #10b981 0%, #059669 100%); border: none;">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 8px;">
<path d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
</svg>
Norda Partner
</a>
<a href="{{ url_for('register') }}" class="btn btn-hero btn-white">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 8px;">
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/>
@ -294,6 +300,22 @@
Zaloguj się
</a>
</div>
<!-- Kontakt z Izbą -->
<div style="margin-top: var(--spacing-lg); display: flex; flex-wrap: wrap; justify-content: center; gap: var(--spacing-md); font-size: var(--font-size-sm); color: rgba(255,255,255,0.9);">
<a href="https://norda-biznes.info" target="_blank" style="color: white; text-decoration: none; display: flex; align-items: center; gap: 6px; background: rgba(255,255,255,0.15); padding: 6px 12px; border-radius: 6px;">
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
Strefa Gościa (Izba NORDA)
</a>
<a href="mailto:kontakt@nordabiznes.pl" style="color: white; text-decoration: none; display: flex; align-items: center; gap: 6px;">
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
kontakt@nordabiznes.pl
</a>
<a href="https://wa.me/48XXXXXXXXX" style="color: white; text-decoration: none; display: flex; align-items: center; gap: 6px;">
<svg width="16" height="16" fill="currentColor" viewBox="0 0 24 24"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/></svg>
WhatsApp
</a>
</div>
</div>
<!-- How it works - FIRST (moved up per UX feedback) -->