nordabiz/templates/calendar/admin_new.html
Maciej Pienczyn 7a3955d0fa
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
feat(calendar): add external events support for KIG/ARP integration
External events from partner organizations (ARP, KIG, etc.) can now
be added to the calendar with distinct visual treatment:
- Grey badge "ZEWNĘTRZNE" and muted date box in list view
- Grey color in grid view with border accent
- "Jestem zainteresowany" instead of "Zapisz się" (no commitment)
- Prominent "Przejdź do rejestracji" button linking to external organizer
- "Zainteresowani" section instead of "Uczestnicy"
- Toggle filter "Pokaż zewnętrzne" with localStorage persistence
- Admin form checkbox to mark events as external

New fields: is_external, external_url, external_source on NordaEvent.
Migration: 086_external_events.sql

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:23:10 +01:00

239 lines
9.0 KiB
HTML
Executable File

{% extends "base.html" %}
{% block title %}Nowe wydarzenie - Norda Biznes Partner{% endblock %}
{% block extra_css %}
<style>
.form-container {
max-width: 700px;
margin: 0 auto;
}
.form-header {
margin-bottom: var(--spacing-xl);
}
.form-header h1 {
font-size: var(--font-size-3xl);
color: var(--text-primary);
}
.form-card {
background: var(--surface);
border-radius: var(--radius-lg);
padding: var(--spacing-xl);
box-shadow: var(--shadow);
}
.form-group {
margin-bottom: var(--spacing-lg);
}
.form-group label {
display: block;
font-weight: 500;
margin-bottom: var(--spacing-xs);
color: var(--text-primary);
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: var(--spacing-sm) var(--spacing-md);
border: 1px solid var(--border);
border-radius: var(--radius);
font-size: var(--font-size-base);
transition: var(--transition);
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}
.form-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--spacing-md);
}
.form-hint {
font-size: var(--font-size-sm);
color: var(--text-secondary);
margin-top: var(--spacing-xs);
}
.form-actions {
display: flex;
gap: var(--spacing-md);
margin-top: var(--spacing-xl);
}
.back-link {
display: inline-flex;
align-items: center;
gap: var(--spacing-xs);
color: var(--text-secondary);
text-decoration: none;
margin-bottom: var(--spacing-lg);
}
.back-link:hover {
color: var(--primary);
}
</style>
{% endblock %}
{% block content %}
<div class="form-container">
<a href="{{ url_for('admin.admin_calendar') }}" class="back-link">
<svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M19 12H5M12 19l-7-7 7-7"/>
</svg>
Powrot do listy wydarzen
</a>
<div class="form-header">
<h1>Nowe wydarzenie</h1>
<p class="text-muted">Dodaj spotkanie lub wydarzenie Norda Biznes</p>
</div>
<div class="form-card">
<form method="POST" action="{{ url_for('admin.admin_calendar_new') }}" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="form-group" style="background: var(--bg-secondary); padding: var(--spacing-md); border-radius: var(--radius); border: 1px solid var(--border);">
<label style="display: flex; align-items: center; gap: var(--spacing-sm); cursor: pointer; margin-bottom: 0;">
<input type="checkbox" id="is_external" name="is_external" style="width: auto;">
<span>Wydarzenie zewnętrzne</span>
</label>
<div class="form-hint">Zaznacz dla wydarzeń organizowanych przez podmioty zewnętrzne (ARP, KIG, urzędy). Użytkownicy zobaczą przycisk "Jestem zainteresowany" zamiast "Zapisz się".</div>
</div>
<div id="external-fields" style="display: none;">
<div class="form-group">
<label for="external_source">Organizator / Źródło *</label>
<input type="text" id="external_source" name="external_source" maxlength="255" placeholder="np. Agencja Rozwoju Pomorza">
</div>
<div class="form-group">
<label for="external_url">Link do rejestracji *</label>
<input type="url" id="external_url" name="external_url" placeholder="https://brokereksportowy.pl/...">
<div class="form-hint">Link do strony zewnętrznej, gdzie użytkownicy mogą się zarejestrować</div>
</div>
</div>
<div class="form-group">
<label for="title">Tytul wydarzenia *</label>
<input type="text" id="title" name="title" required maxlength="255" placeholder="np. Spotkanie czlonkow Norda Biznes">
</div>
<div class="form-group">
<label for="description">Opis</label>
<textarea id="description" name="description" rows="4" placeholder="Opisz co bedzie sie dzialo na wydarzeniu..."></textarea>
</div>
<div class="form-row">
<div class="form-group">
<label for="event_type">Typ wydarzenia</label>
<select id="event_type" name="event_type">
<option value="meeting">Spotkanie</option>
<option value="webinar">Webinar</option>
<option value="networking">Networking</option>
<option value="rada">Rada Izby</option>
<option value="other">Inne</option>
</select>
</div>
<div class="form-group">
<label for="event_date">Data *</label>
<input type="date" id="event_date" name="event_date" required>
</div>
</div>
<div class="form-group">
<label for="access_level">Poziom dostępu *</label>
<select id="access_level" name="access_level">
<option value="members_only">Tylko członkowie Izby NORDA</option>
<option value="rada_only">Tylko Rada Izby</option>
<option value="public">Publiczne (wszyscy zalogowani)</option>
</select>
<div class="form-hint">
<strong>Członkowie</strong> - wszyscy członkowie Izby NORDA mogą widzieć i zapisać się<br>
<strong>Rada Izby</strong> - tylko wyznaczeni członkowie Rady Izby<br>
<strong>Publiczne</strong> - widoczne dla wszystkich zalogowanych użytkowników
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="time_start">Godzina rozpoczecia</label>
<input type="time" id="time_start" name="time_start">
</div>
<div class="form-group">
<label for="time_end">Godzina zakonczenia</label>
<input type="time" id="time_end" name="time_end">
</div>
</div>
<div class="form-group">
<label for="location">Miejsce</label>
<input type="text" id="location" name="location" maxlength="500" placeholder="np. ul. Tomasza Rogali 11, Wejherowo lub Online">
</div>
<div class="form-group">
<label for="location_url">Link do lokalizacji</label>
<input type="url" id="location_url" name="location_url" placeholder="np. link do Google Maps lub Zoom">
<div class="form-hint">Opcjonalny link do mapy lub platformy online</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="speaker_name">Prelegent</label>
<input type="text" id="speaker_name" name="speaker_name" maxlength="255" placeholder="Imie i nazwisko">
</div>
<div class="form-group">
<label for="max_attendees">Limit uczestnikow</label>
<input type="number" id="max_attendees" name="max_attendees" min="1" placeholder="Pozostaw puste = bez limitu">
</div>
</div>
<div class="form-group">
<label for="attachment">Załącznik (PDF, DOCX)</label>
<input type="file" id="attachment" name="attachment" accept=".pdf,.docx,.doc">
<div class="form-hint">Opcjonalny plik do pobrania przez uczestników (np. zaproszenie, agenda)</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Utworz wydarzenie</button>
<a href="{{ url_for('admin.admin_calendar') }}" class="btn btn-secondary">Anuluj</a>
</div>
</form>
</div>
</div>
{% endblock %}
{% block extra_js %}
(function() {
const cb = document.getElementById('is_external');
const extFields = document.getElementById('external-fields');
const maxAtt = document.getElementById('max_attendees');
const maxAttGroup = maxAtt ? maxAtt.closest('.form-group') : null;
function toggle() {
const isExt = cb.checked;
extFields.style.display = isExt ? 'block' : 'none';
if (maxAttGroup) maxAttGroup.style.display = isExt ? 'none' : 'block';
}
cb.addEventListener('change', toggle);
toggle();
})();
{% endblock %}