feat(calendar): Show 3 upcoming events on homepage + WhatsApp data import
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
- Display up to 3 next events with RSVP status instead of just one - Add import script for WhatsApp Norda group data (Feb 2026): events, company updates, Alter Energy, Croatia announcement Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
963f9ec5c8
commit
72ba8e05f1
@ -91,27 +91,29 @@ def index():
|
||||
total_companies = len(companies)
|
||||
total_categories = len([c for c in categories if db.query(Company).filter_by(category_id=c.id).count() > 0])
|
||||
|
||||
# Najbliższe wydarzenie (dla bannera "Kto weźmie udział?")
|
||||
# Znajdź pierwsze wydarzenie, które użytkownik może ZOBACZYĆ
|
||||
# Najbliższe wydarzenia (dla bannera "Kto weźmie udział?")
|
||||
all_upcoming = db.query(NordaEvent).filter(
|
||||
NordaEvent.event_date >= date.today()
|
||||
).order_by(NordaEvent.event_date.asc()).all()
|
||||
|
||||
next_event = None
|
||||
upcoming_events = []
|
||||
for event in all_upcoming:
|
||||
if event.can_user_view(current_user):
|
||||
next_event = event
|
||||
break
|
||||
|
||||
# Sprawdź czy użytkownik jest zapisany i czy MOŻE się zapisać
|
||||
user_registered = False
|
||||
user_can_attend = False
|
||||
if next_event:
|
||||
user_registered = db.query(EventAttendee).filter(
|
||||
EventAttendee.event_id == next_event.id,
|
||||
registered = db.query(EventAttendee).filter(
|
||||
EventAttendee.event_id == event.id,
|
||||
EventAttendee.user_id == current_user.id
|
||||
).first() is not None
|
||||
user_can_attend = next_event.can_user_attend(current_user)
|
||||
can_attend = event.can_user_attend(current_user)
|
||||
upcoming_events.append({
|
||||
'event': event,
|
||||
'user_registered': registered,
|
||||
'user_can_attend': can_attend,
|
||||
})
|
||||
if len(upcoming_events) >= 3:
|
||||
break
|
||||
|
||||
# Backward compat — next_event used by other parts
|
||||
next_event = upcoming_events[0]['event'] if upcoming_events else None
|
||||
|
||||
# ZOPK Knowledge facts — admin only widget
|
||||
zopk_facts = []
|
||||
@ -140,8 +142,7 @@ def index():
|
||||
total_companies=total_companies,
|
||||
total_categories=total_categories,
|
||||
next_event=next_event,
|
||||
user_registered=user_registered,
|
||||
user_can_attend=user_can_attend,
|
||||
upcoming_events=upcoming_events,
|
||||
pending_application=pending_application,
|
||||
zopk_facts=zopk_facts
|
||||
)
|
||||
|
||||
349
scripts/import_whatsapp_feb2026.py
Normal file
349
scripts/import_whatsapp_feb2026.py
Normal file
@ -0,0 +1,349 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Import danych z WhatsApp grupy Norda Biznes (4-11.02.2026)
|
||||
|
||||
Zawiera:
|
||||
- Nowe wydarzenia: Szkolenie KSeF 23.02, Chwila dla Biznesu 26.02 (jeśli brak)
|
||||
- Update speaker info: Śniadanie 20.02 (ID=43)
|
||||
- Uzupełnienie opisów firm: Fiume Studio (128), PG Construction (49), Green House Systems (24)
|
||||
- Nowa firma: Alter Energy (child brand pod Fiume Studio)
|
||||
- UserCompany: Irmina (user 67) → Alter Energy
|
||||
- Ogłoszenie: Chorwacja pod Żaglami
|
||||
|
||||
Użycie:
|
||||
python3 scripts/import_whatsapp_feb2026.py # dry-run
|
||||
python3 scripts/import_whatsapp_feb2026.py --apply # zapis do bazy
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from datetime import date, time, datetime
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from sqlalchemy import create_engine, text
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
|
||||
def load_env():
|
||||
"""Załaduj .env z katalogu projektu."""
|
||||
env_path = Path(__file__).parent.parent / '.env'
|
||||
if env_path.exists():
|
||||
with open(env_path, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line and not line.startswith('#') and '=' in line:
|
||||
key, value = line.split('=', 1)
|
||||
os.environ.setdefault(key.strip(), value.strip())
|
||||
|
||||
|
||||
load_env()
|
||||
|
||||
DATABASE_URL = os.getenv('DATABASE_URL', 'postgresql://nordabiz_app:CHANGE_ME@127.0.0.1:5432/nordabiz')
|
||||
|
||||
SOURCE = 'whatsapp_norda_feb2026'
|
||||
|
||||
|
||||
def main():
|
||||
dry_run = '--apply' not in sys.argv
|
||||
|
||||
print("=" * 70)
|
||||
print("IMPORT: WhatsApp Norda Biznes (4-11.02.2026)")
|
||||
print(f"MODE: {'DRY-RUN (brak zapisu)' if dry_run else 'APPLY (zapis do bazy!)'}")
|
||||
print("=" * 70)
|
||||
|
||||
engine = create_engine(DATABASE_URL)
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
|
||||
stats = {'added': 0, 'updated': 0, 'skipped': 0}
|
||||
|
||||
try:
|
||||
# ============================================================
|
||||
# 1. WYDARZENIA
|
||||
# ============================================================
|
||||
print("\n--- 1. WYDARZENIA ---\n")
|
||||
|
||||
# 1a. Szkolenie KSeF 23.02
|
||||
existing = session.execute(
|
||||
text("SELECT id FROM norda_events WHERE event_date = :d AND title ILIKE :t"),
|
||||
{"d": date(2026, 2, 23), "t": "%KSeF%"}
|
||||
).fetchone()
|
||||
|
||||
if existing:
|
||||
print(f" SKIP: Szkolenie KSeF 23.02 juz istnieje (ID={existing[0]})")
|
||||
stats['skipped'] += 1
|
||||
else:
|
||||
print(" + ADD: Szkolenie KSeF 23.02")
|
||||
if not dry_run:
|
||||
session.execute(text("""
|
||||
INSERT INTO norda_events
|
||||
(title, description, event_type, event_date, time_start, time_end,
|
||||
location, source, source_note, access_level, created_at)
|
||||
VALUES (:title, :desc, :etype, :edate, :tstart, :tend,
|
||||
:loc, :src, :src_note, :access, NOW())
|
||||
"""), {
|
||||
"title": "Szkolenie — Zmiany podatkowe i KSeF 2026",
|
||||
"desc": "Szkolenie z zakresu zmian podatkowych obowiazujacych od nowego roku oraz KSeF. "
|
||||
"Dostepne dla czlonkow Izby NORDA, ich pracownikow i osob prowadzacych rozliczenia ksiegowe. "
|
||||
"Firmy spoza Izby — koszt 250 zl/os. Kontakt: sekretariat Nordy (Magda).",
|
||||
"etype": "meeting",
|
||||
"edate": date(2026, 2, 23),
|
||||
"tstart": time(9, 0),
|
||||
"tend": time(14, 30),
|
||||
"loc": "Urzad Miejski Wejherowo, ul. 12 Marca, ostatnie pietro",
|
||||
"src": SOURCE,
|
||||
"src_note": "WhatsApp grupa Norda, Roman, 8.02.2026",
|
||||
"access": "members_only",
|
||||
})
|
||||
stats['added'] += 1
|
||||
|
||||
# 1b. Chwila dla Biznesu 26.02 — sprawdz czy istnieje
|
||||
existing = session.execute(
|
||||
text("SELECT id FROM norda_events WHERE event_date = :d AND title ILIKE :t"),
|
||||
{"d": date(2026, 2, 26), "t": "%Chwila%"}
|
||||
).fetchone()
|
||||
|
||||
if existing:
|
||||
print(f" SKIP: Chwila dla Biznesu 26.02 juz istnieje (ID={existing[0]})")
|
||||
stats['skipped'] += 1
|
||||
else:
|
||||
print(" + ADD: Chwila dla Biznesu 26.02")
|
||||
if not dry_run:
|
||||
session.execute(text("""
|
||||
INSERT INTO norda_events
|
||||
(title, description, event_type, event_date, time_start,
|
||||
location, source, source_note, access_level, created_at)
|
||||
VALUES (:title, :desc, :etype, :edate, :tstart,
|
||||
:loc, :src, :src_note, :access, NOW())
|
||||
"""), {
|
||||
"title": "Chwila dla Biznesu — luty 2026",
|
||||
"desc": "Comiesięczne spotkanie networkingowe członków Izby NORDA.",
|
||||
"etype": "networking",
|
||||
"edate": date(2026, 2, 26),
|
||||
"tstart": time(19, 0),
|
||||
"loc": "Hotel Olimp, V piętro, Wejherowo",
|
||||
"src": SOURCE,
|
||||
"src_note": "WhatsApp grupa Norda, Roman, 11.02.2026",
|
||||
"access": "members_only",
|
||||
})
|
||||
stats['added'] += 1
|
||||
|
||||
# 1c. Śniadanie 20.02 (ID=43) — UPDATE speaker info
|
||||
event43 = session.execute(
|
||||
text("SELECT id, speaker_name, speaker_company_id FROM norda_events WHERE id = 43")
|
||||
).fetchone()
|
||||
|
||||
if not event43:
|
||||
print(" WARN: Wydarzenie ID=43 nie istnieje!")
|
||||
elif event43[1] and event43[2]:
|
||||
print(f" SKIP: Sniadanie ID=43 ma juz speaker: {event43[1]} (company_id={event43[2]})")
|
||||
stats['skipped'] += 1
|
||||
else:
|
||||
print(f" ~ UPD: Sniadanie ID=43 — speaker: Alicja Domachowska, company_id=40 (Lean Idea)")
|
||||
if not dry_run:
|
||||
session.execute(text("""
|
||||
UPDATE norda_events
|
||||
SET speaker_name = :speaker, speaker_company_id = :cid
|
||||
WHERE id = 43
|
||||
"""), {"speaker": "Alicja Domachowska", "cid": 40})
|
||||
stats['updated'] += 1
|
||||
|
||||
# ============================================================
|
||||
# 2. UZUPEŁNIENIE OPISÓW FIRM
|
||||
# ============================================================
|
||||
print("\n--- 2. UZUPELNIENIE OPISOW FIRM ---\n")
|
||||
|
||||
company_updates = [
|
||||
{
|
||||
"id": 128,
|
||||
"name": "Fiume Studio",
|
||||
"description_short": "Fiume Studio — atelier kulinarne i sala eventowa w Redzie. Warsztaty kulinarne, eventy firmowe, catering.",
|
||||
"services_offered": "Warsztaty kulinarne, sala bankietowa, eventy firmowe, warsztaty pizzy, catering",
|
||||
},
|
||||
{
|
||||
"id": 49,
|
||||
"name": "PG Construction",
|
||||
"description_short": "Projektowanie, nadzór budowlany, kompleksowa obsługa inwestycji budowlanych, obsługa deweloperów.",
|
||||
"services_offered": "Projektowanie budowlane, nadzór budowlany, kompleksowa obsługa inwestycji budowlanych, obsługa deweloperów",
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"name": "Green House Systems",
|
||||
"description_short": "Firma instalacyjna — wod-kan, ogrzewanie podłogowe, rekuperacja, klimatyzacja, instalacje elektryczne z automatyką budynkową, fotowoltaika z magazynem energii.",
|
||||
"services_offered": "Instalacje wod-kan, ogrzewanie podłogowe, rekuperacja, klimatyzacja, instalacje elektryczne, automatyka budynkowa, fotowoltaika, magazyny energii",
|
||||
"website": "https://www.greenhousesystems.pl",
|
||||
},
|
||||
]
|
||||
|
||||
for cu in company_updates:
|
||||
row = session.execute(
|
||||
text("SELECT id, name, description_short, services_offered, website FROM companies WHERE id = :id"),
|
||||
{"id": cu["id"]}
|
||||
).fetchone()
|
||||
|
||||
if not row:
|
||||
print(f" WARN: Firma ID={cu['id']} ({cu['name']}) nie istnieje!")
|
||||
continue
|
||||
|
||||
updates = []
|
||||
params = {"id": cu["id"]}
|
||||
|
||||
# description_short — update only if empty
|
||||
if not row[2] or row[2].strip() == '':
|
||||
updates.append("description_short = :desc_short")
|
||||
params["desc_short"] = cu["description_short"]
|
||||
else:
|
||||
print(f" SKIP: {cu['name']} (ID={cu['id']}) — description_short juz wypelnione")
|
||||
|
||||
# services_offered — update only if empty
|
||||
if not row[3] or row[3].strip() == '':
|
||||
updates.append("services_offered = :services")
|
||||
params["services"] = cu["services_offered"]
|
||||
else:
|
||||
print(f" SKIP: {cu['name']} (ID={cu['id']}) — services_offered juz wypelnione")
|
||||
|
||||
# website — update only if empty and provided
|
||||
if "website" in cu:
|
||||
if not row[4] or row[4].strip() == '':
|
||||
updates.append("website = :website")
|
||||
params["website"] = cu["website"]
|
||||
else:
|
||||
print(f" SKIP: {cu['name']} (ID={cu['id']}) — website juz wypelnione")
|
||||
|
||||
if updates:
|
||||
set_clause = ", ".join(updates)
|
||||
print(f" ~ UPD: {cu['name']} (ID={cu['id']}) — {', '.join(u.split(' =')[0] for u in updates)}")
|
||||
if not dry_run:
|
||||
session.execute(
|
||||
text(f"UPDATE companies SET {set_clause}, last_updated = NOW() WHERE id = :id"),
|
||||
params
|
||||
)
|
||||
stats['updated'] += 1
|
||||
else:
|
||||
stats['skipped'] += 1
|
||||
|
||||
# ============================================================
|
||||
# 3. NOWA FIRMA: Alter Energy
|
||||
# ============================================================
|
||||
print("\n--- 3. NOWA FIRMA: Alter Energy ---\n")
|
||||
|
||||
existing_alter = session.execute(
|
||||
text("SELECT id FROM companies WHERE slug = 'alter-energy'")
|
||||
).fetchone()
|
||||
|
||||
alter_energy_id = None
|
||||
|
||||
if existing_alter:
|
||||
alter_energy_id = existing_alter[0]
|
||||
print(f" SKIP: Alter Energy juz istnieje (ID={alter_energy_id})")
|
||||
stats['skipped'] += 1
|
||||
else:
|
||||
print(" + ADD: Alter Energy (child brand pod Fiume Studio, ID=128)")
|
||||
if not dry_run:
|
||||
result = session.execute(text("""
|
||||
INSERT INTO companies
|
||||
(name, slug, phone, parent_company_id, status, data_quality, data_source, created_at, last_updated)
|
||||
VALUES (:name, :slug, :phone, :parent_id, :status, :dq, :ds, NOW(), NOW())
|
||||
RETURNING id
|
||||
"""), {
|
||||
"name": "Alter Energy",
|
||||
"slug": "alter-energy",
|
||||
"phone": "508259086",
|
||||
"parent_id": 128,
|
||||
"status": "active",
|
||||
"dq": "basic",
|
||||
"ds": SOURCE,
|
||||
})
|
||||
alter_energy_id = result.fetchone()[0]
|
||||
print(f" → ID={alter_energy_id}")
|
||||
stats['added'] += 1
|
||||
|
||||
# 3b. UserCompany: Irmina (user 67) → Alter Energy
|
||||
if alter_energy_id:
|
||||
existing_uc = session.execute(
|
||||
text("SELECT id FROM user_companies WHERE user_id = 67 AND company_id = :cid"),
|
||||
{"cid": alter_energy_id}
|
||||
).fetchone()
|
||||
|
||||
if existing_uc:
|
||||
print(f" SKIP: UserCompany Irmina(67) → Alter Energy({alter_energy_id}) juz istnieje")
|
||||
stats['skipped'] += 1
|
||||
else:
|
||||
print(f" + ADD: UserCompany Irmina(67) → Alter Energy({alter_energy_id}), role=MANAGER, is_primary=false")
|
||||
if not dry_run:
|
||||
session.execute(text("""
|
||||
INSERT INTO user_companies (user_id, company_id, role, is_primary, created_at, updated_at)
|
||||
VALUES (67, :cid, 'MANAGER', false, NOW(), NOW())
|
||||
"""), {"cid": alter_energy_id})
|
||||
stats['added'] += 1
|
||||
else:
|
||||
if dry_run:
|
||||
print(" (dry-run) UserCompany Irmina → Alter Energy zostanie dodane przy --apply")
|
||||
|
||||
# ============================================================
|
||||
# 4. OGŁOSZENIE: Chorwacja pod Żaglami
|
||||
# ============================================================
|
||||
print("\n--- 4. OGLOSZENIE: Chorwacja pod Zaglami ---\n")
|
||||
|
||||
existing_ann = session.execute(
|
||||
text("SELECT id FROM announcements WHERE slug = 'chorwacja-pod-zaglami'")
|
||||
).fetchone()
|
||||
|
||||
if existing_ann:
|
||||
print(f" SKIP: Ogłoszenie 'Chorwacja pod Zaglami' juz istnieje (ID={existing_ann[0]})")
|
||||
stats['skipped'] += 1
|
||||
else:
|
||||
# Find admin user for created_by
|
||||
admin_user = session.execute(
|
||||
text("SELECT id FROM users WHERE is_admin = true ORDER BY id LIMIT 1")
|
||||
).fetchone()
|
||||
admin_id = admin_user[0] if admin_user else 1
|
||||
|
||||
print(" + ADD: Ogloszenie 'Chorwacja pod Zaglami'")
|
||||
if not dry_run:
|
||||
session.execute(text("""
|
||||
INSERT INTO announcements
|
||||
(title, slug, excerpt, content, categories, status, published_at, created_by, created_at, updated_at)
|
||||
VALUES (:title, :slug, :excerpt, :content, :cats, 'published', NOW(), :created_by, NOW(), NOW())
|
||||
"""), {
|
||||
"title": "Chorwacja pod Żaglami — wyjazd integracyjny",
|
||||
"slug": "chorwacja-pod-zaglami",
|
||||
"excerpt": "Pomysł Prezesa Leszka Glazy — wspólny wyjazd pod żaglami do Chorwacji. Kontakt: sekretariat Nordy (Magda) lub Prezes.",
|
||||
"content": "<p>Zapraszamy na wyjazd integracyjny do Chorwacji pod żaglami! Pomysł naszego Prezesa Leszka Glazy.</p>"
|
||||
"<p>Poprzednie wspólne wyjazdy (USA, Hawaje) były wielkim sukcesem. "
|
||||
"Szczegóły do uzgodnienia — prosimy o kontakt z sekretariatem Nordy (Magda) lub bezpośrednio z Prezesem.</p>",
|
||||
"cats": ["event"],
|
||||
"created_by": admin_id,
|
||||
})
|
||||
stats['added'] += 1
|
||||
|
||||
# ============================================================
|
||||
# COMMIT
|
||||
# ============================================================
|
||||
if not dry_run:
|
||||
session.commit()
|
||||
print("\n>>> COMMIT OK")
|
||||
|
||||
# ============================================================
|
||||
# PODSUMOWANIE
|
||||
# ============================================================
|
||||
print("\n" + "=" * 70)
|
||||
print(f"PODSUMOWANIE: dodano={stats['added']}, zaktualizowano={stats['updated']}, pominieto={stats['skipped']}")
|
||||
if dry_run:
|
||||
print("[DRY-RUN] Zadne dane NIE zostaly zapisane. Uzyj --apply aby zapisac.")
|
||||
print("=" * 70)
|
||||
|
||||
except Exception as e:
|
||||
session.rollback()
|
||||
print(f"\nBLAD: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -863,36 +863,41 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Event Banner - Ankieta "Kto weźmie udział?" -->
|
||||
{% if next_event %}
|
||||
<a href="{{ url_for('calendar.calendar_event', event_id=next_event.id) }}" class="event-banner" data-animate="fadeIn">
|
||||
<!-- Event Banners - Najbliższe wydarzenia -->
|
||||
{% if upcoming_events %}
|
||||
{% for ue in upcoming_events %}
|
||||
{% set ev = ue.event %}
|
||||
<a href="{{ url_for('calendar.calendar_event', event_id=ev.id) }}" class="event-banner" data-animate="fadeIn"{% if not loop.first %} style="margin-top: -8px;"{% endif %}>
|
||||
<div class="event-banner-icon">📅</div>
|
||||
<div class="event-banner-content">
|
||||
<div class="event-banner-label">Najbliższe wydarzenie – Kto weźmie udział?</div>
|
||||
<div class="event-banner-title">{{ next_event.title }} →</div>
|
||||
<div class="event-banner-meta">
|
||||
<span>📆 {{ next_event.event_date.strftime('%d.%m.%Y') }} ({{ ['Pon', 'Wt', 'Śr', 'Czw', 'Pt', 'Sob', 'Nd'][next_event.event_date.weekday()] }})</span>
|
||||
{% if next_event.time_start %}
|
||||
<span>🕕 {{ next_event.time_start.strftime('%H:%M') }}</span>
|
||||
{% if loop.first %}
|
||||
<div class="event-banner-label">Najbliższe wydarzenia – Kto weźmie udział?</div>
|
||||
{% endif %}
|
||||
{% if next_event.location %}
|
||||
<span>📍 {{ next_event.location[:30] }}{% if next_event.location|length > 30 %}...{% endif %}</span>
|
||||
<div class="event-banner-title">{{ ev.title }} →</div>
|
||||
<div class="event-banner-meta">
|
||||
<span>📆 {{ ev.event_date.strftime('%d.%m.%Y') }} ({{ ['Pon', 'Wt', 'Śr', 'Czw', 'Pt', 'Sob', 'Nd'][ev.event_date.weekday()] }})</span>
|
||||
{% if ev.time_start %}
|
||||
<span>🕕 {{ ev.time_start.strftime('%H:%M') }}</span>
|
||||
{% endif %}
|
||||
{% if ev.location %}
|
||||
<span>📍 {{ ev.location[:30] }}{% if ev.location|length > 30 %}...{% endif %}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="event-banner-attendees">
|
||||
👥 Zapisanych: {{ next_event.attendee_count }} {% if next_event.attendee_count == 1 %}osoba{% elif next_event.attendee_count in [2,3,4] %}osoby{% else %}osób{% endif %}
|
||||
👥 Zapisanych: {{ ev.attendee_count }} {% if ev.attendee_count == 1 %}osoba{% elif ev.attendee_count in [2,3,4] %}osoby{% else %}osób{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="event-banner-action">
|
||||
{% if user_registered %}
|
||||
{% if ue.user_registered %}
|
||||
<span class="btn-light btn-registered">✓ Jesteś zapisany/a</span>
|
||||
{% elif user_can_attend %}
|
||||
<button type="button" class="btn-light" onclick="rsvpAndGo(event, {{ next_event.id }})">Zapisz się →</button>
|
||||
{% elif next_event.access_level == 'rada_only' %}
|
||||
{% elif ue.user_can_attend %}
|
||||
<button type="button" class="btn-light" onclick="rsvpAndGo(event, {{ ev.id }})">Zapisz się →</button>
|
||||
{% elif ev.access_level == 'rada_only' %}
|
||||
<span class="btn-light" style="background: #fef3c7; color: #92400e; border: 1px solid #fde68a;">🔒 Rada Izby</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user