{% extends "base.html" %} {% block title %}Nowa wiadomosc - Norda Biznes Partner{% endblock %} {% block head_extra %} {% endblock %} {% block extra_css %} {% endblock %} {% block content %}
Powrot do wiadomosci {% if from_company %} Powrot do {{ from_company.name }} {% endif %}

Nowa wiadomosc

{% if recipient %}
{{ (recipient.name or recipient.email)[0].upper() }}
{{ recipient.name or recipient.email.split('@')[0] }}
{% if recipient.privacy_show_email != False %}
{{ recipient.email }}
{% endif %}
{% endif %} {% if context %}
Dotyczy ogloszenia B2B:
{% endif %}
{% if context_type %} {% endif %} {% if recipient %} {% else %}
{% endif %}

Przeciągnij pliki tutaj lub wybierz z dysku

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

Anuluj {% if recipient and recipient.email and recipient.privacy_show_email != False %} Wyslij e-mail {% endif %}
📧 Odbiorca zostanie powiadomiony o nowej wiadomości emailem
{% endblock %} {% block extra_js %} {% if not recipient %} (function() { var users = [ {% for user in users %} {id: {{ user.id }}, name: {{ (user.name or user.email.split('@')[0]) | tojson }}, email: {{ user.email | tojson }}, showEmail: {{ 'true' if user.privacy_show_email != False else 'false' }}, companyName: {{ (user._company_name or '') | tojson }}, companySlug: {{ (user._company_slug or '') | tojson }}, position: {{ (user._position or '') | tojson }}}{{ ',' if not loop.last }} {% endfor %} ]; var searchInput = document.getElementById('recipient_search'); var resultsDiv = document.getElementById('autocomplete-results'); var hiddenInput = document.getElementById('recipient_id'); var selectedDiv = document.getElementById('recipient-selected'); var autocompleteDiv = document.getElementById('recipient-autocomplete'); var activeIndex = -1; function normalize(str) { return str.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, ''); } function filterUsers(query) { if (!query) return []; var q = normalize(query); return users.filter(function(u) { return normalize(u.name).indexOf(q) !== -1 || normalize(u.email).indexOf(q) !== -1; }); } function renderResults(matches) { activeIndex = -1; if (matches.length === 0) { resultsDiv.innerHTML = '
Nie znaleziono
'; resultsDiv.classList.add('visible'); return; } resultsDiv.innerHTML = matches.map(function(u, i) { var initial = (u.name || u.email)[0].toUpperCase(); var emailPart = u.showEmail ? '
' + u.email + '
' : ''; return '
' + '
' + initial + '
' + '
' + u.name + '
' + emailPart + '
'; }).join(''); resultsDiv.classList.add('visible'); } function selectRecipient(id, name, email, showEmail) { hiddenInput.value = id; document.getElementById('selected-avatar').textContent = (name || email)[0].toUpperCase(); document.getElementById('selected-name').textContent = name; document.getElementById('selected-email').textContent = showEmail ? email : ''; selectedDiv.style.display = 'flex'; autocompleteDiv.style.display = 'none'; resultsDiv.classList.remove('visible'); searchInput.value = ''; // Show recipient preview card var user = users.find(function(u) { return u.id === id; }); var previewDiv = document.getElementById('recipient-preview'); if (user && (user.companyName)) { document.getElementById('preview-avatar').textContent = (name || email)[0].toUpperCase(); document.getElementById('preview-name').textContent = name; var companyHtml = ''; if (user.companyName) { companyHtml = user.companySlug ? '' + user.companyName + '' : user.companyName; } if (user.position) { companyHtml = user.position + (companyHtml ? ' · ' + companyHtml : ''); } document.getElementById('preview-company').innerHTML = companyHtml; previewDiv.style.display = 'block'; } else { previewDiv.style.display = 'none'; } } window.clearRecipient = function() { hiddenInput.value = ''; selectedDiv.style.display = 'none'; autocompleteDiv.style.display = 'block'; searchInput.value = ''; searchInput.focus(); document.getElementById('recipient-preview').style.display = 'none'; }; searchInput.addEventListener('input', function() { var q = this.value.trim(); if (q.length === 0) { resultsDiv.classList.remove('visible'); return; } renderResults(filterUsers(q)); }); searchInput.addEventListener('focus', function() { if (this.value.trim().length > 0) { renderResults(filterUsers(this.value.trim())); } }); resultsDiv.addEventListener('click', function(e) { var item = e.target.closest('.autocomplete-item'); if (item) { selectRecipient(item.dataset.id, item.dataset.name, item.dataset.email, item.dataset.showEmail === 'true'); } }); searchInput.addEventListener('keydown', function(e) { var items = resultsDiv.querySelectorAll('.autocomplete-item'); if (!items.length) return; if (e.key === 'ArrowDown') { e.preventDefault(); activeIndex = Math.min(activeIndex + 1, items.length - 1); } else if (e.key === 'ArrowUp') { e.preventDefault(); activeIndex = Math.max(activeIndex - 1, 0); } else if (e.key === 'Enter' && activeIndex >= 0) { e.preventDefault(); var item = items[activeIndex]; selectRecipient(item.dataset.id, item.dataset.name, item.dataset.email, item.dataset.showEmail === 'true'); return; } else if (e.key === 'Escape') { resultsDiv.classList.remove('visible'); return; } else { return; } items.forEach(function(el) { el.classList.remove('active'); }); items[activeIndex].classList.add('active'); items[activeIndex].scrollIntoView({block: 'nearest'}); }); document.addEventListener('click', function(e) { if (!autocompleteDiv.contains(e.target)) { resultsDiv.classList.remove('visible'); } }); searchInput.closest('form').addEventListener('submit', function(e) { if (!hiddenInput.value) { e.preventDefault(); searchInput.focus(); searchInput.style.borderColor = 'var(--danger)'; setTimeout(function() { searchInput.style.borderColor = ''; }, 2000); } }); })(); {% endif %} // 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 wiadomość...', 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 || 'Błąd uploadu'); } }) .catch(function() { alert('Błąd połączenia'); }); } /* Handle paste with images (screenshots) — capture phase to beat Quill's handler */ 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); /* Sync Quill content to hidden textarea on every change */ var textarea = document.getElementById('content'); quill.on('text-change', function() { var html = quill.root.innerHTML; textarea.value = (html === '


') ? '' : html; }); /* Validate before submit */ document.querySelector('form').addEventListener('submit', function(e) { var html = quill.root.innerHTML; textarea.value = (html === '


') ? '' : html; if (!textarea.value.trim()) { e.preventDefault(); alert('Treść wiadomości jest wymagana.'); } }); })(); {% endblock %}