nordabiz/templates/company/recommend.html
Maciej Pienczyn cebe52f303 refactor: Rebranding i aktualizacja modelu AI
- Zmiana nazwy: "Norda Biznes Hub" → "Norda Biznes Partner"
- Aktualizacja modelu AI: Gemini 2.0 Flash → Gemini 3 Flash
- Zachowano historyczne odniesienia w timeline i dokumentacji

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 14:08:39 +01:00

346 lines
10 KiB
HTML
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}Polec firmę - {{ company.name }} - Norda Biznes Partner{% endblock %}
{% block extra_css %}
<style>
.recommend-container {
max-width: 800px;
margin: 0 auto;
}
.recommend-breadcrumb {
margin-bottom: var(--spacing-lg);
font-size: var(--font-size-sm);
color: var(--text-secondary);
}
.recommend-breadcrumb a {
color: var(--primary);
text-decoration: none;
}
.recommend-breadcrumb a:hover {
text-decoration: underline;
}
.recommend-form {
background: var(--surface);
border-radius: var(--radius-xl);
padding: var(--spacing-2xl);
box-shadow: var(--shadow-lg);
}
.form-header {
margin-bottom: var(--spacing-xl);
}
.form-header h1 {
font-size: var(--font-size-2xl);
color: var(--text-primary);
margin-bottom: var(--spacing-sm);
}
.form-header p {
color: var(--text-secondary);
}
.company-info {
background: #f0f9ff;
border: 1px solid #bae6fd;
border-radius: var(--radius);
padding: var(--spacing-lg);
margin-bottom: var(--spacing-xl);
}
.company-info h3 {
font-size: var(--font-size-base);
font-weight: 600;
color: #0369a1;
margin-bottom: var(--spacing-sm);
}
.company-info p {
margin: 0;
color: #0c4a6e;
font-size: var(--font-size-sm);
}
.form-group {
margin-bottom: var(--spacing-lg);
}
.form-label {
display: block;
font-weight: 500;
margin-bottom: var(--spacing-sm);
color: var(--text-primary);
}
.form-label .required {
color: var(--error);
}
.form-input {
width: 100%;
padding: var(--spacing-md);
border: 1px solid var(--border);
border-radius: var(--radius);
font-size: var(--font-size-base);
font-family: var(--font-family);
transition: var(--transition);
}
.form-input:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}
.form-textarea {
min-height: 200px;
resize: vertical;
}
.form-hint {
font-size: var(--font-size-sm);
color: var(--text-secondary);
margin-top: var(--spacing-xs);
}
.form-checkbox {
display: flex;
align-items: flex-start;
gap: var(--spacing-sm);
}
.form-checkbox input[type="checkbox"] {
margin-top: 4px;
width: 18px;
height: 18px;
cursor: pointer;
}
.form-checkbox label {
cursor: pointer;
font-weight: normal;
}
.form-actions {
display: flex;
gap: var(--spacing-md);
margin-top: var(--spacing-xl);
}
.guidelines {
background: #fef3c7;
border: 1px solid #fde68a;
border-radius: var(--radius);
padding: var(--spacing-lg);
margin-bottom: var(--spacing-xl);
}
.guidelines h3 {
font-size: var(--font-size-base);
font-weight: 600;
color: #92400e;
margin-bottom: var(--spacing-sm);
}
.guidelines ul {
margin: 0;
padding-left: var(--spacing-lg);
color: #78350f;
font-size: var(--font-size-sm);
}
.guidelines li {
margin-bottom: var(--spacing-xs);
}
.char-counter {
font-size: var(--font-size-sm);
color: var(--text-secondary);
text-align: right;
margin-top: var(--spacing-xs);
}
.char-counter.error {
color: var(--error);
}
@media (max-width: 768px) {
.recommend-form {
padding: var(--spacing-lg);
}
.form-actions {
flex-direction: column;
}
.form-actions .btn {
width: 100%;
}
}
</style>
{% endblock %}
{% block content %}
<div class="recommend-container">
<nav class="recommend-breadcrumb">
<a href="{{ url_for('index') }}">Katalog</a> &raquo;
<a href="{{ url_for('company_detail', company_id=company.id) }}">{{ company.name }}</a> &raquo;
Polec firmę
</nav>
<div class="recommend-form">
<div class="form-header">
<h1>Polec firmę</h1>
<p>Podziel się swoją opinią i pomóż innym członkom Norda Biznes</p>
</div>
<div class="company-info">
<h3>📋 Polecaną firmą</h3>
<p><strong>{{ company.name }}</strong></p>
<p>{{ company.description_short[:150] }}{% if company.description_short and company.description_short|length > 150 %}...{% endif %}</p>
</div>
<div class="guidelines">
<h3>💡 Wskazówki</h3>
<ul>
<li>Opisz swoje doświadczenia współpracy z firmą</li>
<li>Wspomnij konkretne usługi lub projekty</li>
<li>Bądź szczery i konstruktywny</li>
<li>Twoja rekomendacja będzie widoczna dla innych członków</li>
</ul>
</div>
<form method="POST" action="{{ url_for('company_recommend', slug=company.slug) }}" novalidate>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="form-group">
<label for="recommendation_text" class="form-label">
Rekomendacja <span class="required">*</span>
</label>
<textarea
id="recommendation_text"
name="recommendation_text"
class="form-input form-textarea"
placeholder="Opisz swoje doświadczenia z firmą, zrealizowane projekty, jakość współpracy..."
required
minlength="50"
maxlength="2000"
autofocus
></textarea>
<p class="form-hint">Minimum 50 znaków, maksimum 2000 znaków.</p>
<div class="char-counter" id="charCounter">0 / 2000 znaków</div>
</div>
<div class="form-group">
<label for="service_category" class="form-label">
Kategoria usługi (opcjonalnie)
</label>
<input
type="text"
id="service_category"
name="service_category"
class="form-input"
placeholder="np. Tworzenie stron WWW, Usługi prawne, Produkcja..."
maxlength="200"
>
<p class="form-hint">Jeśli polecanienie dotyczy konkretnej usługi, możesz ją tutaj wskazać.</p>
</div>
<div class="form-group">
<div class="form-checkbox">
<input
type="checkbox"
id="show_contact"
name="show_contact"
value="1"
checked
>
<label for="show_contact">
Udostępnij moje dane kontaktowe (email i telefon) innym członkom, aby mogli zadać pytania o szczegóły współpracy
</label>
</div>
<p class="form-hint" style="margin-left: 26px;">
Domyślnie zaznaczone. Transparentność wzmacnia zaufanie w sieci Norda Biznes.
</p>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary btn-lg">
Wyślij rekomendację
</button>
<a href="{{ url_for('company_detail', company_id=company.id) }}" class="btn btn-outline btn-lg">
Anuluj
</a>
</div>
</form>
</div>
</div>
<div id="toastContainer" style="position: fixed; top: 80px; right: 20px; z-index: 1100; display: flex; flex-direction: column; gap: 10px;"></div>
<style>
.toast { padding: 12px 20px; border-radius: var(--radius); background: var(--surface); border-left: 4px solid var(--primary); box-shadow: 0 4px 12px rgba(0,0,0,0.15); display: flex; align-items: center; gap: 10px; animation: toastIn 0.3s ease; }
.toast.success { border-left-color: var(--success); }
.toast.error { border-left-color: var(--error); }
.toast.warning { border-left-color: var(--warning); }
@keyframes toastIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes toastOut { from { opacity: 1; } to { opacity: 0; } }
</style>
{% endblock %}
{% block extra_js %}
function showToast(message, type = 'info', duration = 4000) {
const container = document.getElementById('toastContainer');
const icons = { success: '✓', error: '✕', warning: '⚠', info: '' };
const toast = document.createElement('div');
toast.className = `toast ${type}`;
toast.innerHTML = `<span style="font-size:1.2em">${icons[type]||''}</span><span>${message}</span>`;
container.appendChild(toast);
setTimeout(() => { toast.style.animation = 'toastOut 0.3s ease forwards'; setTimeout(() => toast.remove(), 300); }, duration);
}
// Character counter
const textarea = document.getElementById('recommendation_text');
const counter = document.getElementById('charCounter');
textarea.addEventListener('input', function() {
const length = this.value.length;
counter.textContent = `${length} / 2000 znaków`;
if (length < 50) {
counter.classList.add('error');
counter.textContent = `${length} / 2000 znaków (minimum 50)`;
} else if (length > 2000) {
counter.classList.add('error');
} else {
counter.classList.remove('error');
}
});
// Client-side validation
document.querySelector('form').addEventListener('submit', function(e) {
const text = textarea.value.trim();
let valid = true;
if (text.length < 50) {
textarea.style.borderColor = 'var(--error)';
showToast('Rekomendacja musi mieć co najmniej 50 znaków.', 'error');
valid = false;
} else if (text.length > 2000) {
textarea.style.borderColor = 'var(--error)';
showToast('Rekomendacja może mieć maksymalnie 2000 znaków.', 'error');
valid = false;
} else {
textarea.style.borderColor = '';
}
if (!valid) {
e.preventDefault();
}
});
{% endblock %}