{% extends "base.html" %} {% block title %}Nowa grupa - Norda Biznes Partner{% endblock %} {% block head_extra %} {% endblock %} {% block extra_css %} .quill-container { border: 1px solid var(--border); border-radius: var(--radius); } .quill-container .ql-toolbar { border-top-left-radius: var(--radius); border-top-right-radius: var(--radius); } .quill-container .ql-container { border-bottom-left-radius: var(--radius); border-bottom-right-radius: var(--radius); font-size: var(--font-size-base); } .quill-container .ql-editor { min-height: 200px; } .quill-container .ql-editor img { max-width: 100%; height: auto; border-radius: var(--radius); margin: var(--spacing-sm) 0; } .compose-container { max-width: 700px; margin: 0 auto; } .compose-header { margin-bottom: var(--spacing-xl); } .compose-header h1 { font-size: var(--font-size-3xl); color: var(--text-primary); } .compose-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-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); } /* Member picker */ .member-picker { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; } .selected-members { display: flex; flex-wrap: wrap; gap: var(--spacing-xs); padding: var(--spacing-sm) var(--spacing-md); min-height: 44px; align-items: center; border-bottom: 1px solid var(--border); background: var(--background); } .selected-members:empty { border-bottom: none; } .member-pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; background: var(--primary); color: white; border-radius: 16px; font-size: var(--font-size-sm); font-weight: 500; } .member-pill-avatar { width: 22px; height: 22px; border-radius: 50%; object-fit: cover; } .member-pill-initial { width: 22px; height: 22px; border-radius: 50%; background: rgba(255,255,255,0.3); display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; } .member-pill-remove { background: none; border: none; color: rgba(255,255,255,0.7); cursor: pointer; padding: 0; font-size: 14px; line-height: 1; } .member-pill-remove:hover { color: white; } .member-search-box { padding: var(--spacing-sm) var(--spacing-md); border-bottom: 1px solid var(--border); } .member-search-box input { width: 100%; border: none; outline: none; font-size: var(--font-size-sm); padding: 4px 0; background: transparent; } .member-picker-collapsible { display: none; } .member-picker.open .member-picker-collapsible { display: block; } .member-picker-toggle { display: flex; align-items: center; justify-content: space-between; padding: var(--spacing-xs) var(--spacing-md); background: var(--background); cursor: pointer; font-size: var(--font-size-sm); color: var(--primary); font-weight: 500; border-top: 1px solid var(--border); user-select: none; } .member-picker-toggle:hover { background: rgba(46, 72, 114, 0.05); } .member-picker-toggle .toggle-arrow { transition: transform 0.2s; } .member-picker.open .member-picker-toggle .toggle-arrow { transform: rotate(180deg); } .member-list { max-height: 240px; overflow-y: auto; } .member-list-item { display: flex; align-items: center; gap: var(--spacing-xs); padding: 6px var(--spacing-md); cursor: pointer; transition: background 0.15s; } .member-list-item:hover { background: var(--background); } .member-list-item.selected { background: rgba(37, 99, 235, 0.06); } .member-list-item input[type="checkbox"] { width: auto; flex-shrink: 0; } .member-list-avatar { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; flex-shrink: 0; } .member-list-initial { width: 28px; height: 28px; border-radius: 50%; background: var(--primary); color: white; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 12px; flex-shrink: 0; } .member-list-info { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; overflow: hidden; } .member-list-name { font-weight: 500; font-size: var(--font-size-sm); color: var(--text-primary); white-space: nowrap; } .member-list-sep { color: var(--border-color, #cbd5e1); flex-shrink: 0; } .member-list-company { font-size: var(--font-size-xs); color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .member-list-empty { padding: var(--spacing-md); text-align: center; color: var(--text-secondary); font-size: var(--font-size-sm); } .selected-count { font-size: var(--font-size-sm); color: var(--text-secondary); } @media (max-width: 640px) { .compose-card { padding: var(--spacing-md); } } {% endblock %} {% block content %}
Powrot do wiadomosci

Nowa grupa

Wybierz uczestnikow z listy ponizej...
▼ Rozwiń listę osób Wybrano: 0

Przeciagnij pliki tutaj lub wybierz z dysku

JPG, PNG, GIF (5MB) · PDF, DOCX, XLSX (10MB)

Anuluj
{% endblock %} {% block extra_js %} /* Member picker */ (function() { var users = [ {% for user in users %} {id: {{ user.id }}, name: {{ (user.name or user.email.split('@')[0]) | tojson }}, email: {{ user.email | tojson }}, companyName: {{ (user._company_name or '') | tojson }}, avatarPath: {% if user.avatar_path %}{{ url_for('static', filename=user.avatar_path) | tojson }}{% else %}""{% endif %}}{{ ',' if not loop.last }} {% endfor %} ]; var selectedIds = new Set(); var searchInput = document.getElementById('member-search'); var listDiv = document.getElementById('member-list'); var selectedDiv = document.getElementById('selected-members'); var countDiv = document.getElementById('selected-count'); var hiddenInputsDiv = document.getElementById('members-hidden-inputs'); var placeholderText = document.getElementById('placeholder-text'); function normalize(str) { return str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, ''); } function filterUsers(query) { if (!query) return users; var q = normalize(query); return users.filter(function(u) { return normalize(u.name).indexOf(q) !== -1 || normalize(u.companyName).indexOf(q) !== -1 || normalize(u.email).indexOf(q) !== -1; }); } function renderList() { var query = searchInput.value.trim(); var filtered = filterUsers(query); if (filtered.length === 0) { listDiv.innerHTML = '
Nie znaleziono
'; return; } listDiv.innerHTML = filtered.map(function(u) { var checked = selectedIds.has(u.id) ? 'checked' : ''; var selectedClass = selectedIds.has(u.id) ? ' selected' : ''; var initial = (u.name || u.email)[0].toUpperCase(); var avatarHtml = u.avatarPath ? '' : '
' + initial + '
'; var companyHtml = u.companyName ? '|' + u.companyName + '' : ''; return ''; }).join(''); } function renderPills() { if (selectedIds.size === 0) { selectedDiv.innerHTML = 'Wybierz uczestnikow z listy ponizej...'; } else { var html = ''; selectedIds.forEach(function(id) { var user = users.find(function(u) { return u.id === id; }); if (!user) return; var initial = (user.name || user.email)[0].toUpperCase(); var avatarHtml = user.avatarPath ? '' : '
' + initial + '
'; html += '' + avatarHtml + '' + user.name + '' + '' + ''; }); selectedDiv.innerHTML = html; } countDiv.textContent = 'Wybrano: ' + selectedIds.size + ' osob'; } function updateHiddenInputs() { hiddenInputsDiv.innerHTML = ''; selectedIds.forEach(function(id) { var input = document.createElement('input'); input.type = 'hidden'; input.name = 'members'; input.value = id; hiddenInputsDiv.appendChild(input); }); } function toggleUser(id) { if (selectedIds.has(id)) { selectedIds.delete(id); } else { selectedIds.add(id); searchInput.value = ''; searchInput.focus(); } renderPills(); updateHiddenInputs(); renderList(); } listDiv.addEventListener('change', function(e) { if (e.target.type === 'checkbox') { toggleUser(parseInt(e.target.dataset.id)); } }); selectedDiv.addEventListener('click', function(e) { var btn = e.target.closest('.member-pill-remove'); if (btn) { toggleUser(parseInt(btn.dataset.id)); } }); searchInput.addEventListener('input', renderList); // Toggle collapsible picker var picker = document.getElementById('member-picker'); var toggleBtn = document.getElementById('member-picker-toggle'); var toggleLabel = document.getElementById('toggle-label'); toggleBtn.addEventListener('click', function() { picker.classList.toggle('open'); toggleLabel.textContent = picker.classList.contains('open') ? '▲ Zwiń listę osób' : '▼ Rozwiń listę osób'; if (picker.classList.contains('open')) { searchInput.focus(); } }); // Close picker when clicking outside document.addEventListener('click', function(e) { if (picker.classList.contains('open') && !picker.contains(e.target)) { picker.classList.remove('open'); toggleLabel.textContent = '▼ Rozwiń listę osób'; } }); renderList(); /* Form validation */ document.getElementById('group-form').addEventListener('submit', function(e) { if (selectedIds.size < 1) { e.preventDefault(); alert('Wybierz co najmniej jednego uczestnika.'); return; } }); })(); /* File attachment handling */ (function() { var dropZone = document.getElementById('file-drop-zone'); var fileInput = document.getElementById('file-input'); var fileList = document.getElementById('file-list'); if (!dropZone) return; dropZone.addEventListener('click', function(e) { if (e.target.tagName !== 'A') fileInput.click(); }); dropZone.addEventListener('dragover', function(e) { e.preventDefault(); dropZone.style.borderColor = 'var(--primary)'; }); dropZone.addEventListener('dragleave', function() { dropZone.style.borderColor = 'var(--border-color)'; }); dropZone.addEventListener('drop', function(e) { e.preventDefault(); dropZone.style.borderColor = 'var(--border-color)'; var dt = new DataTransfer(); Array.from(e.dataTransfer.files).forEach(function(f) { dt.items.add(f); }); Array.from(fileInput.files).forEach(function(f) { dt.items.add(f); }); fileInput.files = dt.files; updateFileList(); }); fileInput.addEventListener('change', updateFileList); function updateFileList() { var files = Array.from(fileInput.files); if (files.length === 0) { fileList.innerHTML = ''; return; } fileList.innerHTML = files.map(function(f, i) { var sizeMB = (f.size / 1024 / 1024).toFixed(1); return '
' + '📎 ' + '' + f.name + ' ' + '(' + sizeMB + ' MB) ' + '' + '
'; }).join(''); } window.removeFile = function(index) { var dt = new DataTransfer(); Array.from(fileInput.files).forEach(function(f, i) { if (i !== index) dt.items.add(f); }); fileInput.files = dt.files; updateFileList(); }; })(); /* Quill editor for message content */ (function() { var csrfToken = '{{ csrf_token() }}'; var quill = new Quill('#quill-content', { theme: 'snow', placeholder: 'Napisz wiadomosc...', modules: { toolbar: { container: [ ['bold', 'italic'], [{'list': 'ordered'}, {'list': 'bullet'}], ['link', 'image'], ['clean'] ], handlers: { image: function() { var input = document.createElement('input'); input.setAttribute('type', 'file'); input.setAttribute('accept', 'image/*'); input.click(); input.onchange = function() { if (input.files && input.files[0]) { uploadImage(input.files[0]); } }; } } } } }); function uploadImage(file) { var fd = new FormData(); fd.append('image', file); fetch('/api/messages/upload-image', { method: 'POST', headers: {'X-CSRFToken': csrfToken}, body: fd }) .then(function(r) { return r.json(); }) .then(function(data) { if (data.url) { var range = quill.getSelection(true); quill.insertEmbed(range.index, 'image', data.url); quill.setSelection(range.index + 1); } else { alert(data.error || 'Blad uploadu'); } }) .catch(function() { alert('Blad polaczenia'); }); } quill.root.addEventListener('paste', function(e) { var items = (e.clipboardData || {}).items || []; for (var i = 0; i < items.length; i++) { if (items[i].type.indexOf('image') !== -1) { e.stopImmediatePropagation(); e.preventDefault(); var file = items[i].getAsFile(); if (file) uploadImage(file); return; } } }, true); var textarea = document.getElementById('content'); quill.on('text-change', function() { var html = quill.root.innerHTML; textarea.value = (html === '


') ? '' : html; }); document.getElementById('group-form').addEventListener('submit', function(e) { var html = quill.root.innerHTML; textarea.value = (html === '


') ? '' : html; if (!textarea.value.trim()) { e.preventDefault(); alert('Tresc wiadomosci jest wymagana.'); } }); })(); {% endblock %}