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
Adds user_companies table with BEFORE/AFTER triggers to sync primary company to users.company_id. Dashboard shows all user's companies with edit buttons. Company edit routes accept optional company_id parameter. Admin API endpoints for managing user-company associations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
701 lines
34 KiB
HTML
701 lines
34 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Edytuj profil — {{ company.name }}{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.ce-container {
|
|
max-width: 860px;
|
|
margin: 0 auto;
|
|
padding: var(--spacing-md) var(--spacing-lg);
|
|
}
|
|
|
|
/* Header card */
|
|
.ce-header {
|
|
background: var(--surface, #fff);
|
|
border-radius: var(--radius-lg, 0.75rem);
|
|
padding: var(--spacing-xl);
|
|
box-shadow: var(--shadow);
|
|
margin-bottom: var(--spacing-lg);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-lg);
|
|
}
|
|
.ce-header-icon {
|
|
width: 56px;
|
|
height: 56px;
|
|
border-radius: 50%;
|
|
background: linear-gradient(135deg, var(--primary, #2E4872), var(--primary-light, #4a6999));
|
|
color: white;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
}
|
|
.ce-header-icon svg { width: 28px; height: 28px; }
|
|
.ce-header-info h1 {
|
|
font-size: var(--font-size-2xl, 1.5rem);
|
|
color: var(--text-primary, #303030);
|
|
margin: 0 0 var(--spacing-xs);
|
|
}
|
|
.ce-header-info p {
|
|
color: var(--text-secondary, #464646);
|
|
margin: 0;
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
.ce-header-actions {
|
|
margin-left: auto;
|
|
}
|
|
|
|
/* Main form card */
|
|
.ce-card {
|
|
background: var(--surface, #fff);
|
|
border-radius: var(--radius-lg, 0.75rem);
|
|
box-shadow: var(--shadow);
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Tabs */
|
|
.ce-tabs {
|
|
display: flex;
|
|
background: var(--background, #EDF0F5);
|
|
border-bottom: 1px solid var(--border, #e0e4eb);
|
|
overflow-x: auto;
|
|
}
|
|
.ce-tab {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
padding: var(--spacing-md) var(--spacing-lg);
|
|
border: none;
|
|
background: none;
|
|
cursor: pointer;
|
|
font-size: var(--font-size-sm);
|
|
font-family: var(--font-family);
|
|
color: var(--text-secondary, #464646);
|
|
white-space: nowrap;
|
|
transition: all 0.2s;
|
|
border-bottom: 3px solid transparent;
|
|
margin-bottom: -1px;
|
|
font-weight: 500;
|
|
}
|
|
.ce-tab svg { width: 18px; height: 18px; flex-shrink: 0; opacity: 0.7; }
|
|
.ce-tab:hover {
|
|
color: var(--text-primary, #303030);
|
|
background: rgba(255,255,255,0.5);
|
|
}
|
|
.ce-tab.active {
|
|
color: var(--primary, #2E4872);
|
|
background: var(--surface, #fff);
|
|
border-bottom-color: var(--primary, #2E4872);
|
|
font-weight: 600;
|
|
}
|
|
.ce-tab.active svg { opacity: 1; }
|
|
|
|
/* Tab content */
|
|
.ce-tab-content { display: none; padding: var(--spacing-xl); }
|
|
.ce-tab-content.active { display: block; }
|
|
|
|
/* Section headers inside tabs */
|
|
.ce-section-title {
|
|
font-size: var(--font-size-lg, 1.125rem);
|
|
font-weight: 600;
|
|
color: var(--text-primary, #303030);
|
|
margin: 0 0 var(--spacing-md);
|
|
padding-bottom: var(--spacing-sm);
|
|
border-bottom: 2px solid var(--primary, #2E4872);
|
|
display: inline-block;
|
|
}
|
|
|
|
/* Form overrides for this page */
|
|
.ce-card .form-group { margin-bottom: var(--spacing-lg); }
|
|
.ce-card .form-label {
|
|
display: block;
|
|
font-weight: 500;
|
|
margin-bottom: var(--spacing-sm);
|
|
color: var(--text-primary, #303030);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
.ce-card .form-input {
|
|
width: 100%;
|
|
padding: 10px 14px;
|
|
border: 1px solid var(--border, #e0e4eb);
|
|
border-radius: var(--radius, 0.5rem);
|
|
font-size: var(--font-size-base, 1rem);
|
|
font-family: var(--font-family);
|
|
transition: var(--transition);
|
|
background: var(--surface, #fff);
|
|
color: var(--text-primary, #303030);
|
|
box-sizing: border-box;
|
|
}
|
|
.ce-card .form-input:focus {
|
|
outline: none;
|
|
border-color: var(--primary, #2E4872);
|
|
box-shadow: 0 0 0 3px rgba(46, 72, 114, 0.1);
|
|
}
|
|
.ce-card .form-input:disabled {
|
|
background: var(--background, #EDF0F5);
|
|
color: var(--text-secondary);
|
|
cursor: not-allowed;
|
|
}
|
|
.ce-card select.form-input {
|
|
cursor: pointer;
|
|
appearance: auto;
|
|
}
|
|
.ce-card textarea.form-input {
|
|
resize: vertical;
|
|
min-height: 100px;
|
|
line-height: 1.6;
|
|
}
|
|
.ce-card .form-help {
|
|
font-size: var(--font-size-sm, 0.875rem);
|
|
color: var(--text-secondary, #464646);
|
|
margin-top: var(--spacing-xs);
|
|
}
|
|
.ce-card .form-row {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: var(--spacing-md);
|
|
}
|
|
|
|
/* Char counter */
|
|
.char-counter {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
text-align: right;
|
|
margin-top: var(--spacing-xs);
|
|
}
|
|
.char-counter.warning { color: var(--warning, #f59e0b); }
|
|
.char-counter.error { color: var(--error, #ef4444); }
|
|
|
|
/* Fieldset */
|
|
fieldset { border: none; padding: 0; margin: 0; }
|
|
fieldset[disabled] { opacity: 0.5; pointer-events: none; }
|
|
|
|
/* Permission warning */
|
|
.ce-no-permission {
|
|
background: #fef3c7;
|
|
border: 1px solid #fde68a;
|
|
border-radius: var(--radius);
|
|
padding: var(--spacing-md);
|
|
margin-bottom: var(--spacing-lg);
|
|
font-size: var(--font-size-sm);
|
|
color: #92400e;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
}
|
|
.ce-no-permission svg { width: 20px; height: 20px; flex-shrink: 0; }
|
|
|
|
/* Info box */
|
|
.ce-info-box {
|
|
background: #f0f9ff;
|
|
border: 1px solid #bae6fd;
|
|
border-radius: var(--radius);
|
|
padding: var(--spacing-md);
|
|
margin-bottom: var(--spacing-lg);
|
|
font-size: var(--font-size-sm);
|
|
color: #0369a1;
|
|
}
|
|
.ce-info-box strong { display: block; margin-bottom: var(--spacing-xs); }
|
|
.ce-info-box ul { margin: var(--spacing-xs) 0 0; padding-left: var(--spacing-lg); }
|
|
.ce-info-box li { margin-bottom: 2px; }
|
|
.ce-info-box a { color: #0369a1; font-weight: 500; }
|
|
|
|
/* Dynamic rows (contacts, social) */
|
|
.ce-dynamic-section {
|
|
margin-top: var(--spacing-lg);
|
|
padding-top: var(--spacing-lg);
|
|
border-top: 1px solid var(--border, #e0e4eb);
|
|
}
|
|
.ce-dynamic-title {
|
|
font-size: var(--font-size-base);
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
margin: 0 0 var(--spacing-xs);
|
|
}
|
|
.ce-dynamic-help {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
margin: 0 0 var(--spacing-md);
|
|
}
|
|
|
|
.contact-row, .social-row {
|
|
display: flex;
|
|
gap: var(--spacing-sm);
|
|
align-items: center;
|
|
margin-bottom: var(--spacing-sm);
|
|
padding: var(--spacing-sm);
|
|
background: var(--background, #EDF0F5);
|
|
border-radius: var(--radius);
|
|
border: 1px solid var(--border, #e0e4eb);
|
|
}
|
|
.contact-type-select, .social-platform-select { flex: 0 0 140px; }
|
|
.contact-value-input, .social-url-input { flex: 1; }
|
|
.contact-purpose-input { flex: 0 0 170px; }
|
|
|
|
.btn-remove {
|
|
flex: 0 0 36px;
|
|
height: 36px;
|
|
border: 1px solid var(--border, #e0e4eb);
|
|
background: var(--surface, #fff);
|
|
color: var(--text-secondary);
|
|
border-radius: var(--radius);
|
|
cursor: pointer;
|
|
font-size: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transition: all 0.2s;
|
|
}
|
|
.btn-remove:hover {
|
|
background: #fee2e2;
|
|
color: #dc2626;
|
|
border-color: #fca5a5;
|
|
}
|
|
|
|
.btn-add {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
padding: var(--spacing-sm) var(--spacing-md);
|
|
background: var(--surface, #fff);
|
|
border: 1px dashed var(--primary, #2E4872);
|
|
border-radius: var(--radius);
|
|
color: var(--primary, #2E4872);
|
|
font-size: var(--font-size-sm);
|
|
font-family: var(--font-family);
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
margin-top: var(--spacing-sm);
|
|
}
|
|
.btn-add:hover {
|
|
background: rgba(46, 72, 114, 0.05);
|
|
border-style: solid;
|
|
}
|
|
.btn-add svg { width: 16px; height: 16px; }
|
|
|
|
/* Social platform icon hints */
|
|
.social-row .social-platform-select { font-weight: 500; }
|
|
|
|
/* Form actions (sticky bottom) */
|
|
.ce-actions {
|
|
display: flex;
|
|
gap: var(--spacing-md);
|
|
padding: var(--spacing-lg) var(--spacing-xl);
|
|
border-top: 1px solid var(--border, #e0e4eb);
|
|
background: var(--background, #EDF0F5);
|
|
}
|
|
|
|
/* Responsive */
|
|
@media (max-width: 768px) {
|
|
.ce-header { flex-direction: column; text-align: center; }
|
|
.ce-header-actions { margin-left: 0; }
|
|
.ce-card .form-row { grid-template-columns: 1fr; }
|
|
.contact-row, .social-row { flex-wrap: wrap; }
|
|
.contact-type-select, .social-platform-select { flex: 1 1 100%; }
|
|
.contact-purpose-input { flex: 1 1 100%; }
|
|
.ce-tab { padding: var(--spacing-sm) var(--spacing-md); font-size: 13px; }
|
|
.ce-tab span.tab-label { display: none; }
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="ce-container">
|
|
|
|
<!-- Header -->
|
|
<div class="ce-header">
|
|
<div class="ce-header-icon">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
|
|
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
|
|
</svg>
|
|
</div>
|
|
<div class="ce-header-info">
|
|
<h1>{{ company.name }}</h1>
|
|
<p>Edytuj dane profilu firmy widoczne w katalogu Izby NORDA</p>
|
|
</div>
|
|
<div class="ce-header-actions">
|
|
<a href="{{ url_for('public.company_detail', company_id=company.id) }}" class="btn btn-outline btn-sm">
|
|
← Powrót do profilu
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main card -->
|
|
<div class="ce-card">
|
|
<!-- Tabs -->
|
|
<div class="ce-tabs">
|
|
<button type="button" class="ce-tab active" data-tab="description">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>
|
|
<span class="tab-label">Opis</span>
|
|
</button>
|
|
<button type="button" class="ce-tab" data-tab="services">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
|
|
<span class="tab-label">Usługi</span>
|
|
</button>
|
|
<button type="button" class="ce-tab" data-tab="contacts">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
|
|
<span class="tab-label">Kontakt</span>
|
|
</button>
|
|
<button type="button" class="ce-tab" data-tab="social">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"/><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"/></svg>
|
|
<span class="tab-label">Social Media</span>
|
|
</button>
|
|
</div>
|
|
|
|
<form method="POST" action="{{ url_for('public.company_edit_save', company_id=company.id) }}" id="companyEditForm">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
<input type="hidden" name="active_tab" id="activeTabInput" value="description">
|
|
|
|
<!-- TAB 1: Opis -->
|
|
<div class="ce-tab-content active" id="tab-description">
|
|
{% if not permissions.description %}
|
|
<div class="ce-no-permission">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
|
Nie masz uprawnień do edycji tej sekcji. Skontaktuj się z managerem firmy.
|
|
</div>
|
|
{% endif %}
|
|
<fieldset {% if not permissions.description %}disabled{% endif %}>
|
|
<div class="form-group">
|
|
<label for="category_id" class="form-label">Kategoria działalności</label>
|
|
<select id="category_id" name="category_id" class="form-input">
|
|
<option value="">— Wybierz kategorię —</option>
|
|
{% for cat in categories %}
|
|
{% if cat.parent_id is none %}
|
|
{% set children = categories | selectattr('parent_id', 'equalto', cat.id) | list %}
|
|
{% if children %}
|
|
<optgroup label="{{ cat.name }}">
|
|
{% for sub in children %}
|
|
<option value="{{ sub.id }}" {% if company.category_id == sub.id %}selected{% endif %}>{{ sub.name }}</option>
|
|
{% endfor %}
|
|
</optgroup>
|
|
{% else %}
|
|
<option value="{{ cat.id }}" {% if company.category_id == cat.id %}selected{% endif %}>{{ cat.name }}</option>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
</select>
|
|
<p class="form-help">Główna kategoria widoczna przy nazwie firmy w katalogu</p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="description_short" class="form-label">Krótki opis firmy</label>
|
|
<textarea id="description_short" name="description_short" class="form-input" rows="3" maxlength="500" placeholder="Np. Specjalizujemy się w usługach IT dla firm z Pomorza...">{{ company.description_short or '' }}</textarea>
|
|
<div class="char-counter" id="shortDescCounter">
|
|
<span id="shortDescCount">{{ (company.description_short or '') | length }}</span>/500 znaków
|
|
</div>
|
|
<p class="form-help">Widoczny na liście firm i w wynikach wyszukiwania</p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="description_full" class="form-label">Pełny opis działalności</label>
|
|
<textarea id="description_full" name="description_full" class="form-input" rows="10" placeholder="Szczegółowy opis tego czym zajmuje się firma, jakie ma doświadczenie i co ją wyróżnia...">{{ company.description_full or '' }}</textarea>
|
|
<p class="form-help">Główny opis na stronie profilu firmy. Dozwolone tagi HTML: <p>, <strong>, <em>, <ul>, <li>, <a></p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="founding_history" class="form-label">Historia i doświadczenie</label>
|
|
<textarea id="founding_history" name="founding_history" class="form-input" rows="5" placeholder="Kiedy firma powstała, jakie ma doświadczenie, kluczowe osiągnięcia...">{{ company.founding_history or '' }}</textarea>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="core_values" class="form-label">Wartości i misja</label>
|
|
<textarea id="core_values" name="core_values" class="form-input" rows="4" placeholder="Kluczowe wartości firmy, misja, podejście do klienta...">{{ company.core_values or '' }}</textarea>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
|
|
<!-- TAB 2: Usługi -->
|
|
<div class="ce-tab-content" id="tab-services">
|
|
{% if not permissions.services %}
|
|
<div class="ce-no-permission">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
|
Nie masz uprawnień do edycji tej sekcji. Skontaktuj się z managerem firmy.
|
|
</div>
|
|
{% endif %}
|
|
<fieldset {% if not permissions.services %}disabled{% endif %}>
|
|
<div class="form-group">
|
|
<label for="services_offered" class="form-label">Oferowane usługi i produkty</label>
|
|
<textarea id="services_offered" name="services_offered" class="form-input" rows="8" placeholder="Wymień główne usługi i produkty oferowane przez firmę...">{{ company.services_offered or '' }}</textarea>
|
|
<p class="form-help">Lista usług pomagająca klientom znaleźć Twoją firmę</p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="technologies_used" class="form-label">Technologie i specjalizacje</label>
|
|
<textarea id="technologies_used" name="technologies_used" class="form-input" rows="4" placeholder="Używane technologie, narzędzia, certyfikaty...">{{ company.technologies_used or '' }}</textarea>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="operational_area" class="form-label">Obszar działania</label>
|
|
<input type="text" id="operational_area" name="operational_area" class="form-input" value="{{ company.operational_area or '' }}" placeholder="np. Wejherowo, Trójmiasto, cała Polska" maxlength="500">
|
|
<p class="form-help">Gdzie firma świadczy usługi</p>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="languages_offered" class="form-label">Języki obsługi</label>
|
|
<input type="text" id="languages_offered" name="languages_offered" class="form-input" value="{{ company.languages_offered or '' }}" placeholder="np. Polski, Angielski, Niemiecki" maxlength="200">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="employee_count_range" class="form-label">Liczba pracowników</label>
|
|
<select id="employee_count_range" name="employee_count_range" class="form-input" style="max-width: 300px;">
|
|
<option value="">— Wybierz przedział —</option>
|
|
{% for range_val in ['1-5', '6-10', '11-25', '26-50', '51-100', '101-250', '250+'] %}
|
|
<option value="{{ range_val }}" {% if company.employee_count_range == range_val %}selected{% endif %}>{{ range_val }} pracowników</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
|
|
<!-- TAB 3: Kontakt -->
|
|
<div class="ce-tab-content" id="tab-contacts">
|
|
{% if not permissions.contacts %}
|
|
<div class="ce-no-permission">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
|
Nie masz uprawnień do edycji tej sekcji. Skontaktuj się z managerem firmy.
|
|
</div>
|
|
{% endif %}
|
|
<fieldset {% if not permissions.contacts %}disabled{% endif %}>
|
|
<span class="ce-section-title">Dane kontaktowe</span>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="website" class="form-label">Strona internetowa</label>
|
|
<input type="url" id="website" name="website" class="form-input" value="{{ company.website or '' }}" placeholder="https://www.twojafirma.pl">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="email" class="form-label">Email firmowy</label>
|
|
<input type="email" id="email" name="email" class="form-input" value="{{ company.email or '' }}" placeholder="kontakt@twojafirma.pl">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="phone" class="form-label">Telefon główny</label>
|
|
<input type="tel" id="phone" name="phone" class="form-input" value="{{ company.phone or '' }}" placeholder="+48 58 123 45 67" maxlength="50">
|
|
</div>
|
|
<div class="form-group"></div>
|
|
</div>
|
|
|
|
<span class="ce-section-title" style="margin-top: var(--spacing-lg);">Adres siedziby</span>
|
|
|
|
<div class="form-group">
|
|
<label for="address_street" class="form-label">Ulica i numer</label>
|
|
<input type="text" id="address_street" name="address_street" class="form-input" value="{{ company.address_street or '' }}" placeholder="ul. Dworcowa 7/3" maxlength="255">
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="address_postal" class="form-label">Kod pocztowy</label>
|
|
<input type="text" id="address_postal" name="address_postal" class="form-input" value="{{ company.address_postal or '' }}" placeholder="84-200" maxlength="10" style="max-width: 150px;">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="address_city" class="form-label">Miasto</label>
|
|
<input type="text" id="address_city" name="address_city" class="form-input" value="{{ company.address_city or '' }}" placeholder="Wejherowo" maxlength="100">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Dynamic contacts -->
|
|
<div class="ce-dynamic-section">
|
|
<p class="ce-dynamic-title">Dodatkowe numery i adresy email</p>
|
|
<p class="ce-dynamic-help">Dodaj kolejne numery telefonów, adresy email lub fax z opisem przeznaczenia.</p>
|
|
|
|
<div id="contactsList">
|
|
{% for contact in contacts %}
|
|
<div class="contact-row">
|
|
<select name="contact_types[]" class="form-input contact-type-select">
|
|
<option value="phone" {% if contact.contact_type == 'phone' %}selected{% endif %}>📞 Telefon</option>
|
|
<option value="mobile" {% if contact.contact_type == 'mobile' %}selected{% endif %}>📱 Komórka</option>
|
|
<option value="email" {% if contact.contact_type == 'email' %}selected{% endif %}>✉️ Email</option>
|
|
<option value="fax" {% if contact.contact_type == 'fax' %}selected{% endif %}>📠 Fax</option>
|
|
</select>
|
|
<input type="text" name="contact_values[]" class="form-input contact-value-input" value="{{ contact.value }}" placeholder="Numer lub adres">
|
|
<input type="text" name="contact_purposes[]" class="form-input contact-purpose-input" value="{{ contact.purpose or '' }}" placeholder="np. Biuro, Sprzedaż">
|
|
<button type="button" class="btn-remove" onclick="this.parentElement.remove()" title="Usuń">✕</button>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
<button type="button" class="btn-add" id="addContactBtn">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
Dodaj kontakt
|
|
</button>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
|
|
<!-- TAB 4: Social Media -->
|
|
<div class="ce-tab-content" id="tab-social">
|
|
{% if not permissions.social %}
|
|
<div class="ce-no-permission">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
|
Nie masz uprawnień do edycji tej sekcji. Skontaktuj się z managerem firmy.
|
|
</div>
|
|
{% endif %}
|
|
<fieldset {% if not permissions.social %}disabled{% endif %}>
|
|
<p class="ce-dynamic-help" style="margin-top: 0;">Dodaj linki do profili firmy w mediach społecznościowych.</p>
|
|
|
|
<div id="socialList">
|
|
{% for sm in social_media %}
|
|
{% if sm.source is none or sm.source == 'manual_edit' or sm.source == 'manual' %}
|
|
<div class="social-row">
|
|
<select name="social_platforms[]" class="form-input social-platform-select">
|
|
<option value="facebook" {% if sm.platform == 'facebook' %}selected{% endif %}>Facebook</option>
|
|
<option value="linkedin" {% if sm.platform == 'linkedin' %}selected{% endif %}>LinkedIn</option>
|
|
<option value="instagram" {% if sm.platform == 'instagram' %}selected{% endif %}>Instagram</option>
|
|
<option value="youtube" {% if sm.platform == 'youtube' %}selected{% endif %}>YouTube</option>
|
|
<option value="twitter" {% if sm.platform == 'twitter' %}selected{% endif %}>X (Twitter)</option>
|
|
<option value="tiktok" {% if sm.platform == 'tiktok' %}selected{% endif %}>TikTok</option>
|
|
</select>
|
|
<input type="url" name="social_urls[]" class="form-input social-url-input" value="{{ sm.url }}" placeholder="https://facebook.com/twojafirma">
|
|
<button type="button" class="btn-remove" onclick="this.parentElement.remove()" title="Usuń">✕</button>
|
|
</div>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<button type="button" class="btn-add" id="addSocialBtn">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
Dodaj profil
|
|
</button>
|
|
|
|
{% set ns = namespace(has_auto=false) %}
|
|
{% for sm in social_media %}
|
|
{% if sm.source is not none and sm.source != 'manual_edit' and sm.source != 'manual' %}
|
|
{% set ns.has_auto = true %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% if ns.has_auto %}
|
|
<div class="ce-info-box" style="margin-top: var(--spacing-lg);">
|
|
<strong>Profile wykryte automatycznie</strong>
|
|
Te profile zostały wykryte przez system i nie podlegają ręcznej edycji:
|
|
<ul>
|
|
{% for sm in social_media %}
|
|
{% if sm.source is not none and sm.source != 'manual_edit' and sm.source != 'manual' %}
|
|
<li><strong>{{ sm.platform | capitalize }}</strong>: <a href="{{ sm.url }}" target="_blank" rel="noopener">{{ sm.url | truncate(60) }}</a></li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
{% endif %}
|
|
</fieldset>
|
|
</div>
|
|
|
|
<!-- Form actions -->
|
|
<div class="ce-actions">
|
|
<button type="submit" class="btn btn-primary">
|
|
Zapisz zmiany
|
|
</button>
|
|
<a href="{{ url_for('public.company_detail', company_id=company.id) }}" class="btn btn-outline">Anuluj</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
// Company Edit — tabs, dynamic fields, validation
|
|
(function() {
|
|
// Tab switching
|
|
var tabs = document.querySelectorAll('.ce-tab');
|
|
var contents = document.querySelectorAll('.ce-tab-content');
|
|
var activeTabInput = document.getElementById('activeTabInput');
|
|
|
|
tabs.forEach(function(tab) {
|
|
tab.addEventListener('click', function() {
|
|
var target = this.getAttribute('data-tab');
|
|
tabs.forEach(function(t) { t.classList.remove('active'); });
|
|
this.classList.add('active');
|
|
contents.forEach(function(c) { c.classList.remove('active'); });
|
|
document.getElementById('tab-' + target).classList.add('active');
|
|
activeTabInput.value = target;
|
|
});
|
|
});
|
|
|
|
// Character counter for short description
|
|
var shortDesc = document.getElementById('description_short');
|
|
var shortCount = document.getElementById('shortDescCount');
|
|
var shortCounter = document.getElementById('shortDescCounter');
|
|
if (shortDesc && shortCount) {
|
|
shortDesc.addEventListener('input', function() {
|
|
var len = this.value.length;
|
|
shortCount.textContent = len;
|
|
shortCounter.className = 'char-counter' + (len > 450 ? (len >= 500 ? ' error' : ' warning') : '');
|
|
});
|
|
}
|
|
|
|
// Helper: create contact row HTML
|
|
function makeContactRow() {
|
|
var row = document.createElement('div');
|
|
row.className = 'contact-row';
|
|
row.innerHTML =
|
|
'<select name="contact_types[]" class="form-input contact-type-select">' +
|
|
'<option value="phone">\uD83D\uDCDE Telefon</option>' +
|
|
'<option value="mobile">\uD83D\uDCF1 Kom\u00f3rka</option>' +
|
|
'<option value="email">\u2709\uFE0F Email</option>' +
|
|
'<option value="fax">\uD83D\uDCE0 Fax</option>' +
|
|
'</select>' +
|
|
'<input type="text" name="contact_values[]" class="form-input contact-value-input" placeholder="Numer lub adres">' +
|
|
'<input type="text" name="contact_purposes[]" class="form-input contact-purpose-input" placeholder="np. Biuro, Sprzeda\u017c">' +
|
|
'<button type="button" class="btn-remove" onclick="this.parentElement.remove()" title="Usu\u0144">\u2715</button>';
|
|
return row;
|
|
}
|
|
|
|
// Helper: create social row HTML
|
|
function makeSocialRow() {
|
|
var row = document.createElement('div');
|
|
row.className = 'social-row';
|
|
row.innerHTML =
|
|
'<select name="social_platforms[]" class="form-input social-platform-select">' +
|
|
'<option value="facebook">Facebook</option>' +
|
|
'<option value="linkedin">LinkedIn</option>' +
|
|
'<option value="instagram">Instagram</option>' +
|
|
'<option value="youtube">YouTube</option>' +
|
|
'<option value="twitter">X (Twitter)</option>' +
|
|
'<option value="tiktok">TikTok</option>' +
|
|
'</select>' +
|
|
'<input type="url" name="social_urls[]" class="form-input social-url-input" placeholder="https://...">' +
|
|
'<button type="button" class="btn-remove" onclick="this.parentElement.remove()" title="Usu\u0144">\u2715</button>';
|
|
return row;
|
|
}
|
|
|
|
// Add contact
|
|
var addContactBtn = document.getElementById('addContactBtn');
|
|
if (addContactBtn) {
|
|
addContactBtn.addEventListener('click', function() {
|
|
document.getElementById('contactsList').appendChild(makeContactRow());
|
|
});
|
|
}
|
|
|
|
// Add social
|
|
var addSocialBtn = document.getElementById('addSocialBtn');
|
|
if (addSocialBtn) {
|
|
addSocialBtn.addEventListener('click', function() {
|
|
document.getElementById('socialList').appendChild(makeSocialRow());
|
|
});
|
|
}
|
|
|
|
// Client-side validation
|
|
document.getElementById('companyEditForm').addEventListener('submit', function(e) {
|
|
var emailField = document.getElementById('email');
|
|
if (emailField && emailField.value.trim()) {
|
|
var emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
|
if (!emailPattern.test(emailField.value.trim())) {
|
|
e.preventDefault();
|
|
emailField.focus();
|
|
emailField.style.borderColor = 'var(--error, #ef4444)';
|
|
emailField.style.boxShadow = '0 0 0 3px rgba(239,68,68,0.1)';
|
|
return;
|
|
}
|
|
}
|
|
var websiteField = document.getElementById('website');
|
|
if (websiteField && websiteField.value.trim() && !websiteField.value.match(/^https?:\/\//)) {
|
|
websiteField.value = 'https://' + websiteField.value.trim();
|
|
}
|
|
});
|
|
})();
|
|
{% endblock %}
|