nordabiz/templates/messages/view.html
Maciej Pienczyn 830ef0ea1e feat: Add B2B classifieds interactions (interest, Q&A, context messages)
- Add ClassifiedInterest model for tracking user interest in listings
- Add ClassifiedQuestion model for public Q&A on listings
- Add context_type/context_id to PrivateMessage for B2B linking
- Add interest toggle button and interests list modal
- Add Q&A section with ask/answer/hide functionality
- Update messages to show B2B context badge
- Create migration 034_classified_interactions.sql

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 21:15:30 +01:00

244 lines
6.9 KiB
HTML
Executable File

{% extends "base.html" %}
{% block title %}{{ message.subject or 'Wiadomosc' }} - Norda Biznes Partner{% endblock %}
{% block extra_css %}
<style>
.message-container {
max-width: 800px;
margin: 0 auto;
}
.message-card {
background: var(--surface);
border-radius: var(--radius-lg);
padding: var(--spacing-xl);
box-shadow: var(--shadow);
margin-bottom: var(--spacing-xl);
}
.message-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: var(--spacing-lg);
padding-bottom: var(--spacing-lg);
border-bottom: 1px solid var(--border);
}
.message-subject {
font-size: var(--font-size-xl);
font-weight: 600;
color: var(--text-primary);
margin-bottom: var(--spacing-sm);
}
.message-participants {
display: flex;
align-items: center;
gap: var(--spacing-md);
}
.participant-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
background: var(--primary);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
font-size: var(--font-size-lg);
}
.participant-info {
flex: 1;
}
.participant-name {
font-weight: 500;
color: var(--text-primary);
}
.participant-role {
font-size: var(--font-size-sm);
color: var(--text-secondary);
}
.message-date {
font-size: var(--font-size-sm);
color: var(--text-secondary);
}
.message-body {
line-height: 1.7;
color: var(--text-primary);
white-space: pre-wrap;
}
.reply-section {
background: var(--surface);
border-radius: var(--radius-lg);
padding: var(--spacing-xl);
box-shadow: var(--shadow);
}
.reply-section h3 {
font-size: var(--font-size-lg);
margin-bottom: var(--spacing-lg);
}
.form-group {
margin-bottom: var(--spacing-lg);
}
.form-group textarea {
width: 100%;
padding: var(--spacing-md);
border: 1px solid var(--border);
border-radius: var(--radius);
font-size: var(--font-size-base);
resize: vertical;
}
.form-group textarea:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}
.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);
}
.thread-message {
padding: var(--spacing-lg);
border-left: 3px solid var(--border);
margin-left: var(--spacing-lg);
margin-top: var(--spacing-lg);
background: var(--background);
border-radius: 0 var(--radius) var(--radius) 0;
}
.thread-message .participant-name {
font-size: var(--font-size-sm);
}
.thread-message .message-body {
margin-top: var(--spacing-sm);
font-size: var(--font-size-sm);
}
.context-badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
background: #eff6ff;
border: 1px solid #bfdbfe;
border-radius: var(--radius);
font-size: var(--font-size-sm);
color: var(--primary);
margin-bottom: var(--spacing-md);
}
.context-badge svg {
width: 16px;
height: 16px;
}
.context-badge a {
color: var(--primary);
text-decoration: none;
font-weight: 500;
}
.context-badge a:hover {
text-decoration: underline;
}
.context-badge.inactive {
background: #f3f4f6;
border-color: #d1d5db;
color: var(--text-secondary);
}
.context-badge.inactive a {
color: var(--text-secondary);
}
</style>
{% endblock %}
{% block content %}
<div class="message-container">
<a href="{{ url_for('messages_inbox') }}" 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 wiadomosci
</a>
<div class="message-card">
{% if context %}
<div class="context-badge {% if not context.is_active %}inactive{% endif %}">
<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
Dotyczy ogloszenia: <a href="{{ context.url }}">{{ context.title }}</a>
{% if not context.is_active %}<span style="color: var(--text-secondary);">(nieaktywne)</span>{% endif %}
</div>
{% endif %}
<div class="message-header">
<div>
<div class="message-subject">{{ message.subject or '(brak tematu)' }}</div>
<div class="message-participants">
<div class="participant-avatar">
{{ (message.sender.name or message.sender.email)[0].upper() }}
</div>
<div class="participant-info">
<div class="participant-name">{{ message.sender.name or message.sender.email.split('@')[0] }}</div>
<div class="participant-role">
{% if message.sender_id == current_user.id %}
Do: {{ message.recipient.name or message.recipient.email.split('@')[0] }}
{% else %}
Do: mnie
{% endif %}
</div>
</div>
</div>
</div>
<div class="message-date">
{{ message.created_at.strftime('%d.%m.%Y %H:%M') }}
</div>
</div>
<div class="message-body">{{ message.content }}</div>
</div>
<!-- Odpowiedź -->
{% if message.sender_id != current_user.id or message.recipient_id != current_user.id %}
<div class="reply-section">
<h3>Odpowiedz</h3>
<form method="POST" action="{{ url_for('messages_reply', message_id=message.id) }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="form-group">
<textarea name="content" rows="4" required placeholder="Napisz odpowiedz..."></textarea>
</div>
<button type="submit" class="btn btn-primary">Wyslij odpowiedz</button>
</form>
</div>
{% endif %}
</div>
{% endblock %}