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
Added description_full, core_values, services_offered, and technologies_used to the AI context builder. Previously only description_short and founding_history were used by NordaGPT. Added "Wykorzystywany przez NordaGPT" hints to all relevant fields in the company edit form so users know their content feeds the AI. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1555 lines
72 KiB
HTML
1555 lines
72 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Edytuj profil — {{ company.name }}{% endblock %}
|
|
|
|
{% block head_extra %}
|
|
<link href="{{ url_for('static', filename='css/quill.snow.css') }}" rel="stylesheet">
|
|
<script src="{{ url_for('static', filename='js/vendor/quill.js') }}"></script>
|
|
{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.ce-container {
|
|
max-width: 1400px;
|
|
margin: 0 auto;
|
|
padding: var(--spacing-md) var(--spacing-lg);
|
|
}
|
|
|
|
/* Split layout: editor + preview */
|
|
.ce-layout {
|
|
display: grid;
|
|
grid-template-columns: 1fr 380px;
|
|
gap: var(--spacing-lg);
|
|
align-items: start;
|
|
}
|
|
|
|
/* Preview panel */
|
|
.ce-preview {
|
|
position: sticky;
|
|
top: 80px;
|
|
max-height: calc(100vh - 100px);
|
|
overflow-y: auto;
|
|
background: var(--surface, #fff);
|
|
border-radius: var(--radius-lg, 0.75rem);
|
|
box-shadow: var(--shadow);
|
|
padding: var(--spacing-lg);
|
|
}
|
|
.ce-preview-title {
|
|
font-size: var(--font-size-sm);
|
|
font-weight: 600;
|
|
color: white;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.05em;
|
|
margin: calc(-1 * var(--spacing-lg)) calc(-1 * var(--spacing-lg)) var(--spacing-md);
|
|
padding: var(--spacing-md) var(--spacing-lg);
|
|
background: linear-gradient(135deg, var(--primary, #2E4872), #4a6999);
|
|
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
}
|
|
.ce-preview-title svg { width: 16px; height: 16px; }
|
|
|
|
/* Preview sections */
|
|
.preview-company-name {
|
|
font-size: var(--font-size-xl, 1.25rem);
|
|
font-weight: 700;
|
|
color: var(--text-primary, #303030);
|
|
margin-bottom: var(--spacing-sm);
|
|
}
|
|
.preview-short-desc {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary, #464646);
|
|
margin-bottom: var(--spacing-lg);
|
|
font-style: italic;
|
|
}
|
|
.preview-section {
|
|
margin-bottom: var(--spacing-lg);
|
|
padding-bottom: var(--spacing-md);
|
|
border-bottom: 1px solid var(--border, #e0e4eb);
|
|
}
|
|
.preview-section:last-child {
|
|
border-bottom: none;
|
|
margin-bottom: 0;
|
|
padding-bottom: 0;
|
|
}
|
|
.preview-section-label {
|
|
font-size: var(--font-size-sm);
|
|
font-weight: 600;
|
|
color: var(--text-primary, #303030);
|
|
margin-bottom: var(--spacing-sm);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
.preview-section-label::before {
|
|
content: '';
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
flex-shrink: 0;
|
|
}
|
|
/* Preview dot colors matching tabs */
|
|
#previewDescriptionSection .preview-section-label::before,
|
|
#previewHistorySection .preview-section-label::before,
|
|
#previewValuesSection .preview-section-label::before { background: #6366f1; }
|
|
#previewServicesSection .preview-section-label::before { background: #f59e0b; }
|
|
#previewContactSection .preview-section-label::before { background: #10b981; }
|
|
#previewSocialSection .preview-section-label::before { background: #ec4899; }
|
|
.preview-section-content {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-primary, #303030);
|
|
line-height: 1.7;
|
|
}
|
|
.preview-section-content p { margin-bottom: var(--spacing-sm); }
|
|
.preview-section-content ul, .preview-section-content ol {
|
|
padding-left: var(--spacing-lg);
|
|
margin-bottom: var(--spacing-sm);
|
|
}
|
|
.preview-section-content li { margin-bottom: 2px; }
|
|
.preview-section-content a { color: var(--primary, #2E4872); }
|
|
.preview-section-content strong { font-weight: 600; }
|
|
.preview-empty {
|
|
color: var(--text-secondary, #464646);
|
|
font-style: italic;
|
|
font-size: var(--font-size-sm);
|
|
opacity: 0.6;
|
|
}
|
|
|
|
/* Preview contact and social items */
|
|
.preview-contact-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
font-size: var(--font-size-sm);
|
|
margin-bottom: var(--spacing-xs);
|
|
}
|
|
.preview-contact-item svg { width: 14px; height: 14px; color: var(--primary); flex-shrink: 0; }
|
|
.preview-social-item {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
font-size: var(--font-size-sm);
|
|
color: var(--primary, #2E4872);
|
|
margin-right: var(--spacing-md);
|
|
margin-bottom: var(--spacing-xs);
|
|
}
|
|
|
|
/* Mobile preview button & bottom sheet */
|
|
.ce-preview-mobile-btn {
|
|
display: none;
|
|
position: fixed;
|
|
bottom: var(--spacing-lg);
|
|
right: var(--spacing-lg);
|
|
z-index: 900;
|
|
padding: 12px 20px;
|
|
background: var(--primary, #2E4872);
|
|
color: white;
|
|
border: none;
|
|
border-radius: 50px;
|
|
font-size: var(--font-size-sm);
|
|
font-weight: 600;
|
|
font-family: var(--font-family);
|
|
cursor: pointer;
|
|
box-shadow: 0 4px 12px rgba(46, 72, 114, 0.3);
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
transition: all 0.2s;
|
|
}
|
|
.ce-preview-mobile-btn:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 6px 16px rgba(46, 72, 114, 0.4);
|
|
}
|
|
.ce-preview-mobile-btn svg { width: 18px; height: 18px; }
|
|
.ce-preview-sheet-overlay {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0; left: 0; right: 0; bottom: 0;
|
|
background: rgba(0,0,0,0.5);
|
|
z-index: 1100;
|
|
}
|
|
.ce-preview-sheet-overlay.active { display: block; }
|
|
.ce-preview-sheet {
|
|
position: fixed;
|
|
bottom: 0; left: 0; right: 0;
|
|
max-height: 80vh;
|
|
background: var(--surface, #fff);
|
|
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
|
|
box-shadow: 0 -4px 20px rgba(0,0,0,0.15);
|
|
z-index: 1200;
|
|
overflow-y: auto;
|
|
padding: var(--spacing-lg);
|
|
transform: translateY(100%);
|
|
transition: transform 0.3s ease;
|
|
}
|
|
.ce-preview-sheet-overlay.active .ce-preview-sheet {
|
|
transform: translateY(0);
|
|
}
|
|
.ce-preview-sheet-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: var(--spacing-md);
|
|
padding-bottom: var(--spacing-sm);
|
|
border-bottom: 1px solid var(--border, #e0e4eb);
|
|
}
|
|
.ce-preview-sheet-close {
|
|
background: none;
|
|
border: 1px solid var(--border, #e0e4eb);
|
|
border-radius: var(--radius);
|
|
padding: 6px 12px;
|
|
cursor: pointer;
|
|
font-size: var(--font-size-sm);
|
|
font-family: var(--font-family);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
/* 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 — colored per section */
|
|
.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.5; }
|
|
.ce-tab:hover {
|
|
color: var(--text-primary, #303030);
|
|
background: rgba(255,255,255,0.5);
|
|
}
|
|
.ce-tab:hover svg { opacity: 0.8; }
|
|
.ce-tab.active { background: var(--surface, #fff); font-weight: 600; }
|
|
.ce-tab.active svg { opacity: 1; }
|
|
/* Per-tab colors */
|
|
.ce-tab[data-tab="description"].active { color: #6366f1; border-bottom-color: #6366f1; }
|
|
.ce-tab[data-tab="description"].active svg { color: #6366f1; }
|
|
.ce-tab[data-tab="services"].active { color: #f59e0b; border-bottom-color: #f59e0b; }
|
|
.ce-tab[data-tab="services"].active svg { color: #f59e0b; }
|
|
.ce-tab[data-tab="contacts"].active { color: #10b981; border-bottom-color: #10b981; }
|
|
.ce-tab[data-tab="contacts"].active svg { color: #10b981; }
|
|
.ce-tab[data-tab="social"].active { color: #ec4899; border-bottom-color: #ec4899; }
|
|
.ce-tab[data-tab="social"].active svg { color: #ec4899; }
|
|
.ce-tab[data-tab="visibility"].active { color: #8b5cf6; border-bottom-color: #8b5cf6; }
|
|
.ce-tab[data-tab="visibility"].active svg { color: #8b5cf6; }
|
|
|
|
/* 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: var(--spacing-sm) var(--spacing-md);
|
|
background: linear-gradient(90deg, rgba(16, 185, 129, 0.08), transparent);
|
|
border-left: 3px solid #10b981;
|
|
border-radius: 0 var(--radius) var(--radius) 0;
|
|
display: block;
|
|
}
|
|
|
|
/* Form overrides for this page */
|
|
.ce-card .form-group { margin-bottom: var(--spacing-lg); }
|
|
.ce-card .form-label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-weight: 600;
|
|
margin-bottom: var(--spacing-sm);
|
|
color: var(--text-primary, #303030);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
.ce-card .form-label::before {
|
|
content: '';
|
|
width: 3px;
|
|
height: 14px;
|
|
border-radius: 2px;
|
|
flex-shrink: 0;
|
|
}
|
|
/* Label accent colors per tab */
|
|
#tab-description .form-label::before { background: #6366f1; }
|
|
#tab-services .form-label::before { background: #f59e0b; }
|
|
#tab-contacts .form-label::before { background: #10b981; }
|
|
#tab-social .form-label::before { background: #ec4899; }
|
|
.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: 0.8rem;
|
|
color: var(--text-secondary, #464646);
|
|
margin-top: var(--spacing-xs);
|
|
padding: 4px 10px;
|
|
background: #f8fafc;
|
|
border-radius: var(--radius, 0.5rem);
|
|
border-left: 2px solid var(--border, #e0e4eb);
|
|
}
|
|
.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: linear-gradient(135deg, #fef3c7, #fde68a20);
|
|
border: 1px solid #fde68a;
|
|
border-left: 3px solid #f59e0b;
|
|
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);
|
|
font-weight: 500;
|
|
}
|
|
.ce-no-permission svg { width: 20px; height: 20px; flex-shrink: 0; color: #f59e0b; }
|
|
|
|
/* Info box */
|
|
.ce-info-box {
|
|
background: linear-gradient(135deg, #f0f9ff, #e0f2fe);
|
|
border: 1px solid #bae6fd;
|
|
border-left: 3px solid #0ea5e9;
|
|
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: 2px dashed 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: linear-gradient(135deg, rgba(46, 72, 114, 0.04), rgba(46, 72, 114, 0.08));
|
|
border: 1px dashed var(--primary, #2E4872);
|
|
border-radius: var(--radius);
|
|
color: var(--primary, #2E4872);
|
|
font-size: var(--font-size-sm);
|
|
font-weight: 500;
|
|
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; }
|
|
|
|
/* Website type select */
|
|
.website-type-select { flex: 0 0 140px; font-weight: 500; }
|
|
|
|
/* Visibility tab */
|
|
.visibility-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: var(--spacing-md);
|
|
border-bottom: 1px solid var(--border, #e0e4eb);
|
|
}
|
|
.visibility-row:last-child { border-bottom: none; }
|
|
.visibility-info { flex: 1; min-width: 0; }
|
|
.visibility-label {
|
|
display: block;
|
|
font-weight: 500;
|
|
color: var(--text-primary, #303030);
|
|
font-size: var(--font-size-base);
|
|
}
|
|
.visibility-desc {
|
|
display: block;
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary, #464646);
|
|
margin-top: 2px;
|
|
}
|
|
.visibility-toggle {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 6px 14px;
|
|
border: 1px solid var(--border, #e0e4eb);
|
|
border-radius: var(--radius);
|
|
background: #ecfdf5;
|
|
color: #059669;
|
|
font-size: var(--font-size-sm);
|
|
font-family: var(--font-family);
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
white-space: nowrap;
|
|
flex-shrink: 0;
|
|
}
|
|
.visibility-toggle svg { width: 18px; height: 18px; }
|
|
.visibility-toggle:hover { opacity: 0.8; }
|
|
.visibility-toggle.hidden-state {
|
|
background: #fef3c7;
|
|
color: #92400e;
|
|
border-color: #fde68a;
|
|
}
|
|
.visibility-toggle.saving {
|
|
opacity: 0.5;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Sub-section rows */
|
|
.visibility-sub {
|
|
padding-left: calc(var(--spacing-md) + 24px);
|
|
background: #f8fafc;
|
|
border-bottom-color: #f1f5f9;
|
|
}
|
|
.visibility-sub .visibility-label {
|
|
font-size: var(--font-size-sm);
|
|
font-weight: 400;
|
|
color: var(--text-secondary, #464646);
|
|
}
|
|
.visibility-toggle-sub {
|
|
padding: 4px 10px;
|
|
font-size: 0.8rem;
|
|
}
|
|
.visibility-toggle-sub svg { width: 15px; height: 15px; }
|
|
.visibility-toggle-sub.hidden-state {
|
|
background: #fef9c3;
|
|
color: #a16207;
|
|
border-color: #fde68a;
|
|
}
|
|
|
|
/* Website primary radio */
|
|
.website-primary-label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
flex: 0 0 auto;
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
}
|
|
.website-primary-label input[type="radio"]:checked + span {
|
|
color: var(--primary, #2E4872);
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* 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: linear-gradient(180deg, #f8fafc, var(--background, #EDF0F5));
|
|
}
|
|
.ce-actions .btn-primary {
|
|
background: linear-gradient(135deg, var(--primary, #2E4872), #4a6999);
|
|
border: none;
|
|
color: white;
|
|
padding: 10px 28px;
|
|
font-weight: 600;
|
|
border-radius: var(--radius);
|
|
cursor: pointer;
|
|
font-size: var(--font-size-base);
|
|
font-family: var(--font-family);
|
|
transition: all 0.2s;
|
|
box-shadow: 0 2px 8px rgba(46, 72, 114, 0.25);
|
|
}
|
|
.ce-actions .btn-primary:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(46, 72, 114, 0.35);
|
|
}
|
|
|
|
/* Quill editor overrides */
|
|
.quill-container {
|
|
border: 1px solid var(--border, #e0e4eb);
|
|
border-radius: var(--radius, 0.5rem);
|
|
overflow: hidden;
|
|
background: var(--surface, #fff);
|
|
transition: var(--transition);
|
|
}
|
|
.quill-container:focus-within {
|
|
border-color: var(--primary, #2E4872);
|
|
box-shadow: 0 0 0 3px rgba(46, 72, 114, 0.1);
|
|
}
|
|
.quill-container .ql-toolbar {
|
|
border: none !important;
|
|
border-bottom: 1px solid var(--border, #e0e4eb) !important;
|
|
background: linear-gradient(180deg, #f1f5f9, var(--background, #EDF0F5));
|
|
font-family: var(--font-family) !important;
|
|
padding: 6px 10px !important;
|
|
}
|
|
.quill-container .ql-toolbar button:hover {
|
|
color: var(--primary, #2E4872) !important;
|
|
}
|
|
.quill-container .ql-toolbar button.ql-active {
|
|
color: var(--primary, #2E4872) !important;
|
|
}
|
|
.quill-container .ql-container {
|
|
border: none !important;
|
|
font-family: var(--font-family) !important;
|
|
font-size: var(--font-size-base, 1rem) !important;
|
|
}
|
|
.quill-container .ql-editor {
|
|
min-height: 120px;
|
|
line-height: 1.7;
|
|
color: var(--text-primary, #303030);
|
|
}
|
|
.quill-container .ql-editor.ql-blank::before {
|
|
color: var(--text-secondary, #464646);
|
|
opacity: 0.5;
|
|
font-style: italic;
|
|
}
|
|
.quill-container.quill-tall .ql-editor {
|
|
min-height: 200px;
|
|
}
|
|
fieldset[disabled] .quill-container {
|
|
opacity: 0.5;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Responsive */
|
|
@media (max-width: 1024px) {
|
|
.ce-layout {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
.ce-preview {
|
|
display: none;
|
|
}
|
|
.ce-preview-mobile-btn {
|
|
display: flex;
|
|
}
|
|
}
|
|
@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>
|
|
|
|
<!-- Split layout: editor + preview -->
|
|
<div class="ce-layout">
|
|
|
|
<!-- 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>
|
|
<button type="button" class="ce-tab" data-tab="visibility">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
<span class="tab-label">Widoczność</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="year_established" class="form-label">Rok założenia firmy</label>
|
|
<input type="number" id="year_established" name="year_established" class="form-input" style="max-width: 200px;"
|
|
min="1800" max="2030" placeholder="np. 2015"
|
|
value="{{ company.year_established or '' }}"
|
|
{% if company.krs_registration_date or company.business_start_date %}readonly{% endif %}>
|
|
{% if company.krs_registration_date or company.business_start_date %}
|
|
<p class="form-help">Rok pochodzi z rejestru {% if company.krs_registration_date %}KRS{% else %}CEIDG{% endif %} — aby zmienić, skontaktuj się z administratorem</p>
|
|
{% else %}
|
|
<p class="form-help">Rok rozpoczęcia działalności firmy</p>
|
|
{% endif %}
|
|
</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 · <strong>Wykorzystywany przez NordaGPT</strong></p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">Pełny opis działalności</label>
|
|
<div class="quill-container quill-tall" id="quill-description_full"></div>
|
|
<textarea id="description_full" name="description_full" style="display:none;">{{ company.description_full or '' }}</textarea>
|
|
<p class="form-help">Użyj paska narzędzi do formatowania tekstu · <strong>Wykorzystywany przez NordaGPT</strong></p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">Historia i doświadczenie</label>
|
|
<div class="quill-container" id="quill-founding_history"></div>
|
|
<textarea id="founding_history" name="founding_history" style="display:none;">{{ company.founding_history or '' }}</textarea>
|
|
<p class="form-help"><strong>Wykorzystywany przez NordaGPT</strong> — historia firmy, założyciele, doświadczenie</p>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label">Wartości i misja</label>
|
|
<div class="quill-container" id="quill-core_values"></div>
|
|
<textarea id="core_values" name="core_values" style="display:none;">{{ company.core_values or '' }}</textarea>
|
|
<p class="form-help"><strong>Wykorzystywany przez NordaGPT</strong> — wartości i misja firmy</p>
|
|
</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 class="form-label">Oferowane usługi i produkty</label>
|
|
<div class="quill-container quill-tall" id="quill-services_offered"></div>
|
|
<textarea id="services_offered" name="services_offered" style="display:none;">{{ company.services_offered or '' }}</textarea>
|
|
<p class="form-help">Użyj paska narzędzi do formatowania tekstu · <strong>Wykorzystywany przez NordaGPT</strong></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>
|
|
<p class="form-help"><strong>Wykorzystywany przez NordaGPT</strong> — technologie i specjalizacje</p>
|
|
</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-group" style="margin-bottom: var(--spacing-lg);">
|
|
<label class="form-label">Strony internetowe <span style="font-weight: normal; color: var(--text-secondary);">(max 5)</span></label>
|
|
<div id="websiteList">
|
|
{% for w in company_websites %}
|
|
<div class="social-row website-row">
|
|
<select name="website_types[]" class="form-input website-type-select">
|
|
<option value="website" {% if w.website_type == 'website' or not w.website_type %}selected{% endif %}>Strona firmowa</option>
|
|
<option value="store" {% if w.website_type == 'store' %}selected{% endif %}>Sklep</option>
|
|
<option value="booking" {% if w.website_type == 'booking' %}selected{% endif %}>Rezerwacje</option>
|
|
<option value="blog" {% if w.website_type == 'blog' %}selected{% endif %}>Blog</option>
|
|
<option value="portfolio" {% if w.website_type == 'portfolio' %}selected{% endif %}>Portfolio</option>
|
|
<option value="other" {% if w.website_type == 'other' %}selected{% endif %}>Inna</option>
|
|
</select>
|
|
<input type="url" name="website_urls[]" class="form-input social-url-input" value="{{ w.url }}" placeholder="https://www.twojafirma.pl">
|
|
<input type="text" name="website_labels[]" class="form-input" style="flex: 0 0 120px;" value="{{ w.label or '' }}" placeholder="Etykieta">
|
|
<label class="website-primary-label" title="Strona główna">
|
|
<input type="radio" name="website_primary" value="{{ loop.index0 }}" {% if w.is_primary %}checked{% endif %}>
|
|
<span>Gł.</span>
|
|
</label>
|
|
<button type="button" class="btn-remove" onclick="removeWebsiteRow(this)" title="Usuń">✕</button>
|
|
</div>
|
|
{% endfor %}
|
|
{% if not company_websites %}
|
|
{% if company.website %}
|
|
<div class="social-row website-row">
|
|
<select name="website_types[]" class="form-input website-type-select">
|
|
<option value="website" selected>Strona firmowa</option>
|
|
<option value="store">Sklep</option>
|
|
<option value="booking">Rezerwacje</option>
|
|
<option value="blog">Blog</option>
|
|
<option value="portfolio">Portfolio</option>
|
|
<option value="other">Inna</option>
|
|
</select>
|
|
<input type="url" name="website_urls[]" class="form-input social-url-input" value="{{ company.website }}" placeholder="https://www.twojafirma.pl">
|
|
<input type="text" name="website_labels[]" class="form-input" style="flex: 0 0 120px;" value="" placeholder="Etykieta">
|
|
<label class="website-primary-label" title="Strona główna">
|
|
<input type="radio" name="website_primary" value="0" checked>
|
|
<span>Gł.</span>
|
|
</label>
|
|
<button type="button" class="btn-remove" onclick="removeWebsiteRow(this)" title="Usuń">✕</button>
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
</div>
|
|
<button type="button" class="btn-add" id="addWebsiteBtn">
|
|
<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 stronę WWW
|
|
</button>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<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>
|
|
|
|
<!-- TAB 5: Widoczność -->
|
|
<div class="ce-tab-content" id="tab-visibility">
|
|
<div class="ce-info-box">
|
|
<strong>Zarządzaj widocznością sekcji profilu</strong>
|
|
Ukryte sekcje nie będą widoczne dla odwiedzających Twój profil.
|
|
Ty i kadra zarządzająca nadal widzicie ukryte sekcje z oznaczeniem.
|
|
</div>
|
|
|
|
<div id="visibilitySections" style="margin-top: var(--spacing-lg);">
|
|
{% for key, label, description, subs in section_definitions %}
|
|
<div class="visibility-row" data-section="{{ key }}">
|
|
<div class="visibility-info">
|
|
<span class="visibility-label">{{ label }}</span>
|
|
<span class="visibility-desc">{{ description }}</span>
|
|
</div>
|
|
<button type="button" class="visibility-toggle {% if company.is_section_hidden(key) %}hidden-state{% endif %}"
|
|
onclick="toggleSection('{{ key }}', this)" title="Kliknij aby zmienić widoczność">
|
|
{% if company.is_section_hidden(key) %}
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
|
|
<span>Ukryta</span>
|
|
{% else %}
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
<span>Widoczna</span>
|
|
{% endif %}
|
|
</button>
|
|
</div>
|
|
{% if subs %}
|
|
{% for sub_key, sub_label in subs %}
|
|
<div class="visibility-row visibility-sub" data-section="{{ sub_key }}">
|
|
<div class="visibility-info">
|
|
<span class="visibility-label">{{ sub_label }}</span>
|
|
</div>
|
|
<button type="button" class="visibility-toggle visibility-toggle-sub {% if company.is_section_hidden(sub_key) %}hidden-state{% endif %}"
|
|
onclick="toggleSection('{{ sub_key }}', this)" title="Kliknij aby zmienić widoczność">
|
|
{% if company.is_section_hidden(sub_key) %}
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
|
|
<span>Ukryta</span>
|
|
{% else %}
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
<span>Widoczna</span>
|
|
{% endif %}
|
|
</button>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<div id="visibilityStatus" style="margin-top: var(--spacing-md); display: none;" class="ce-info-box"></div>
|
|
</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 class="ce-preview" id="livePreview">
|
|
<div class="ce-preview-title">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
Podgląd profilu
|
|
</div>
|
|
<div class="preview-company-name">{{ company.name }}</div>
|
|
<div class="preview-short-desc" id="previewShortDesc">{{ company.description_short or 'Brak krótkiego opisu' }}</div>
|
|
|
|
<div class="preview-section" id="previewDescriptionSection">
|
|
<div class="preview-section-label">Opis firmy</div>
|
|
<div class="preview-section-content" id="previewDescFull">
|
|
{% if company.description_full %}{{ company.description_full | safe }}{% else %}<span class="preview-empty">Uzupełnij opis firmy...</span>{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="preview-section" id="previewHistorySection">
|
|
<div class="preview-section-label">Historia i doświadczenie</div>
|
|
<div class="preview-section-content" id="previewHistory">
|
|
{% if company.founding_history %}{{ company.founding_history | safe }}{% else %}<span class="preview-empty">Uzupełnij historię...</span>{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="preview-section" id="previewValuesSection">
|
|
<div class="preview-section-label">Wartości i misja</div>
|
|
<div class="preview-section-content" id="previewValues">
|
|
{% if company.core_values %}{{ company.core_values | safe }}{% else %}<span class="preview-empty">Uzupełnij wartości...</span>{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="preview-section" id="previewServicesSection">
|
|
<div class="preview-section-label">Oferowane usługi</div>
|
|
<div class="preview-section-content" id="previewServices">
|
|
{% if company.services_offered %}{{ company.services_offered | safe }}{% else %}<span class="preview-empty">Uzupełnij usługi...</span>{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="preview-section" id="previewContactSection">
|
|
<div class="preview-section-label">Dane kontaktowe</div>
|
|
<div class="preview-section-content" id="previewContact">
|
|
{% if company.email %}<div class="preview-contact-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>{{ company.email }}</div>{% endif %}
|
|
{% if company.phone %}<div class="preview-contact-item"><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>{{ company.phone }}</div>{% endif %}
|
|
{% if company.website %}<div class="preview-contact-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>{{ company.website }}</div>{% endif %}
|
|
{% if not company.email and not company.phone and not company.website %}<span class="preview-empty">Brak danych kontaktowych</span>{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="preview-section" id="previewSocialSection">
|
|
<div class="preview-section-label">Social Media</div>
|
|
<div class="preview-section-content" id="previewSocial">
|
|
{% for sm in social_media %}
|
|
<span class="preview-social-item">{{ sm.platform | capitalize }}</span>
|
|
{% endfor %}
|
|
{% if not social_media %}<span class="preview-empty">Brak profili social media</span>{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div><!-- /ce-layout -->
|
|
|
|
</div>
|
|
|
|
<!-- Mobile preview button -->
|
|
<button type="button" class="ce-preview-mobile-btn" id="mobilePreviewBtn" onclick="openMobilePreview()">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
|
|
Podgląd
|
|
</button>
|
|
|
|
<!-- Mobile preview bottom sheet -->
|
|
<div class="ce-preview-sheet-overlay" id="previewSheetOverlay">
|
|
<div class="ce-preview-sheet" id="previewSheet">
|
|
<div class="ce-preview-sheet-header">
|
|
<span style="font-weight: 600;">Podgląd profilu</span>
|
|
<button type="button" class="ce-preview-sheet-close" onclick="closeMobilePreview()">Zamknij</button>
|
|
</div>
|
|
<div id="mobilePreviewContent"></div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
// ============================================
|
|
// Quill.js WYSIWYG Initialization
|
|
// ============================================
|
|
var quillInstances = {};
|
|
var QUILL_TOOLBAR = [
|
|
['bold', 'italic'],
|
|
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
|
|
['link'],
|
|
['clean']
|
|
];
|
|
|
|
function initQuillEditor(fieldName, placeholder) {
|
|
var container = document.getElementById('quill-' + fieldName);
|
|
var textarea = document.getElementById(fieldName);
|
|
if (!container || !textarea) return null;
|
|
|
|
var quill = new Quill(container, {
|
|
theme: 'snow',
|
|
modules: { toolbar: QUILL_TOOLBAR },
|
|
placeholder: placeholder || 'Wpisz tekst...'
|
|
});
|
|
|
|
// Load existing content from hidden textarea
|
|
var existing = textarea.value.trim();
|
|
if (existing) {
|
|
quill.root.innerHTML = existing;
|
|
}
|
|
|
|
// Sync to hidden textarea on every change + update preview
|
|
quill.on('text-change', function() {
|
|
var html = quill.root.innerHTML;
|
|
textarea.value = (html === '<p><br></p>') ? '' : html;
|
|
updatePreview(fieldName, textarea.value);
|
|
});
|
|
|
|
quillInstances[fieldName] = quill;
|
|
return quill;
|
|
}
|
|
|
|
// Initialize all Quill editors
|
|
if (typeof Quill !== 'undefined') {
|
|
initQuillEditor('description_full', 'Szczegółowy opis tego czym zajmuje się firma...');
|
|
initQuillEditor('founding_history', 'Kiedy firma powstała, jakie ma doświadczenie...');
|
|
initQuillEditor('core_values', 'Kluczowe wartości firmy, misja...');
|
|
initQuillEditor('services_offered', 'Wymień główne usługi i produkty...');
|
|
}
|
|
|
|
// ============================================
|
|
// Live Preview Updates
|
|
// ============================================
|
|
var previewDebounceTimers = {};
|
|
|
|
function updatePreview(fieldName, value) {
|
|
clearTimeout(previewDebounceTimers[fieldName]);
|
|
previewDebounceTimers[fieldName] = setTimeout(function() {
|
|
doUpdatePreview(fieldName, value);
|
|
}, 300);
|
|
}
|
|
|
|
function doUpdatePreview(fieldName, value) {
|
|
var mapping = {
|
|
'description_short': 'previewShortDesc',
|
|
'description_full': 'previewDescFull',
|
|
'founding_history': 'previewHistory',
|
|
'core_values': 'previewValues',
|
|
'services_offered': 'previewServices'
|
|
};
|
|
|
|
var emptyTexts = {
|
|
'description_short': 'Brak krótkiego opisu',
|
|
'description_full': 'Uzupełnij opis firmy...',
|
|
'founding_history': 'Uzupełnij historię...',
|
|
'core_values': 'Uzupełnij wartości...',
|
|
'services_offered': 'Uzupełnij usługi...'
|
|
};
|
|
|
|
var targetId = mapping[fieldName];
|
|
if (!targetId) return;
|
|
var el = document.getElementById(targetId);
|
|
if (!el) return;
|
|
|
|
if (value && value.trim() && value !== '<p><br></p>') {
|
|
el.innerHTML = value;
|
|
el.classList.remove('preview-empty');
|
|
} else {
|
|
el.innerHTML = '<span class="preview-empty">' + (emptyTexts[fieldName] || '') + '</span>';
|
|
}
|
|
}
|
|
|
|
// Hook plain text fields to preview
|
|
var shortDescField = document.getElementById('description_short');
|
|
if (shortDescField) {
|
|
shortDescField.addEventListener('input', function() {
|
|
updatePreview('description_short', this.value);
|
|
});
|
|
}
|
|
|
|
// Hook contact fields to preview
|
|
function updateContactPreview() {
|
|
var email = (document.getElementById('email') || {}).value || '';
|
|
var phone = (document.getElementById('phone') || {}).value || '';
|
|
var el = document.getElementById('previewContact');
|
|
if (!el) return;
|
|
var html = '';
|
|
if (email) html += '<div class="preview-contact-item"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>' + email + '</div>';
|
|
if (phone) html += '<div class="preview-contact-item"><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>' + phone + '</div>';
|
|
el.innerHTML = html || '<span class="preview-empty">Brak danych kontaktowych</span>';
|
|
}
|
|
|
|
['email', 'phone'].forEach(function(id) {
|
|
var field = document.getElementById(id);
|
|
if (field) field.addEventListener('input', updateContactPreview);
|
|
});
|
|
|
|
// Highlight preview section matching active tab
|
|
function highlightPreviewTab(tabName) {
|
|
var sections = document.querySelectorAll('.ce-preview .preview-section');
|
|
sections.forEach(function(s) { s.style.opacity = '0.4'; s.style.transition = 'opacity 0.3s'; });
|
|
|
|
var tabToSections = {
|
|
'description': ['previewDescriptionSection', 'previewHistorySection', 'previewValuesSection'],
|
|
'services': ['previewServicesSection'],
|
|
'contacts': ['previewContactSection'],
|
|
'social': ['previewSocialSection']
|
|
};
|
|
|
|
var active = tabToSections[tabName] || [];
|
|
active.forEach(function(id) {
|
|
var el = document.getElementById(id);
|
|
if (el) el.style.opacity = '1';
|
|
});
|
|
|
|
if (tabName === 'visibility') {
|
|
sections.forEach(function(s) { s.style.opacity = '1'; });
|
|
}
|
|
}
|
|
|
|
// Initial highlight for default tab
|
|
highlightPreviewTab('description');
|
|
|
|
// 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;
|
|
highlightPreviewTab(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;
|
|
}
|
|
}
|
|
// Auto-prefix https:// for all website URL inputs
|
|
document.querySelectorAll('#websiteList input[name="website_urls[]"]').forEach(function(f) {
|
|
if (f.value.trim() && !f.value.match(/^https?:\/\//)) {
|
|
f.value = 'https://' + f.value.trim();
|
|
}
|
|
});
|
|
});
|
|
})();
|
|
|
|
// Website list management
|
|
function removeWebsiteRow(btn) {
|
|
btn.closest('.website-row').remove();
|
|
reindexWebsiteRadios();
|
|
toggleWebsiteBtn();
|
|
}
|
|
|
|
function reindexWebsiteRadios() {
|
|
var rows = document.querySelectorAll('#websiteList .website-row');
|
|
var hadChecked = false;
|
|
rows.forEach(function(row, i) {
|
|
var radio = row.querySelector('input[type="radio"]');
|
|
radio.value = i;
|
|
if (radio.checked) hadChecked = true;
|
|
});
|
|
if (!hadChecked && rows.length > 0) {
|
|
rows[0].querySelector('input[type="radio"]').checked = true;
|
|
}
|
|
}
|
|
|
|
function toggleWebsiteBtn() {
|
|
var btn = document.getElementById('addWebsiteBtn');
|
|
if (btn) {
|
|
btn.style.display = document.querySelectorAll('#websiteList .website-row').length >= 5 ? 'none' : '';
|
|
}
|
|
}
|
|
|
|
(function() {
|
|
var addBtn = document.getElementById('addWebsiteBtn');
|
|
if (addBtn) {
|
|
addBtn.addEventListener('click', function() {
|
|
var list = document.getElementById('websiteList');
|
|
var idx = list.querySelectorAll('.website-row').length;
|
|
if (idx >= 5) return;
|
|
var row = document.createElement('div');
|
|
row.className = 'social-row website-row';
|
|
row.innerHTML = '<select name="website_types[]" class="form-input website-type-select"><option value="website">Strona firmowa</option><option value="store">Sklep</option><option value="booking">Rezerwacje</option><option value="blog">Blog</option><option value="portfolio">Portfolio</option><option value="other">Inna</option></select>'
|
|
+ '<input type="url" name="website_urls[]" class="form-input social-url-input" value="" placeholder="https://www.twojafirma.pl">'
|
|
+ '<input type="text" name="website_labels[]" class="form-input" style="flex: 0 0 120px;" value="" placeholder="Etykieta">'
|
|
+ '<label class="website-primary-label" title="Strona główna"><input type="radio" name="website_primary" value="' + idx + '"><span>Gł.</span></label>'
|
|
+ '<button type="button" class="btn-remove" onclick="removeWebsiteRow(this)" title="Usuń">✕</button>';
|
|
list.appendChild(row);
|
|
if (idx === 0) row.querySelector('input[type="radio"]').checked = true;
|
|
toggleWebsiteBtn();
|
|
});
|
|
toggleWebsiteBtn();
|
|
}
|
|
})();
|
|
|
|
// Section visibility toggle (AJAX)
|
|
var hiddenSections = {{ company.hidden_sections | tojson }};
|
|
|
|
function toggleSection(key, btn) {
|
|
btn.classList.add('saving');
|
|
var idx = hiddenSections.indexOf(key);
|
|
if (idx >= 0) {
|
|
hiddenSections.splice(idx, 1);
|
|
} else {
|
|
hiddenSections.push(key);
|
|
}
|
|
|
|
fetch('{{ url_for("public.company_edit_visibility", company_id=company.id) }}', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': '{{ csrf_token() }}'
|
|
},
|
|
body: JSON.stringify({ hidden_sections: hiddenSections })
|
|
})
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
btn.classList.remove('saving');
|
|
if (data.success) {
|
|
hiddenSections = data.hidden_sections;
|
|
var isHidden = hiddenSections.indexOf(key) >= 0;
|
|
btn.className = 'visibility-toggle' + (isHidden ? ' hidden-state' : '');
|
|
btn.innerHTML = isHidden
|
|
? '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg><span>Ukryta</span>'
|
|
: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg><span>Widoczna</span>';
|
|
} else {
|
|
// Revert on error
|
|
if (idx >= 0) hiddenSections.push(key);
|
|
else hiddenSections.splice(hiddenSections.indexOf(key), 1);
|
|
}
|
|
})
|
|
.catch(function() {
|
|
btn.classList.remove('saving');
|
|
if (idx >= 0) hiddenSections.push(key);
|
|
else hiddenSections.splice(hiddenSections.indexOf(key), 1);
|
|
});
|
|
}
|
|
|
|
// Mobile preview
|
|
function openMobilePreview() {
|
|
var mobileContent = document.getElementById('mobilePreviewContent');
|
|
var desktopPreview = document.getElementById('livePreview');
|
|
if (mobileContent && desktopPreview) {
|
|
var clone = desktopPreview.cloneNode(true);
|
|
var title = clone.querySelector('.ce-preview-title');
|
|
if (title) title.remove();
|
|
mobileContent.innerHTML = clone.innerHTML;
|
|
}
|
|
document.getElementById('previewSheetOverlay').classList.add('active');
|
|
document.body.style.overflow = 'hidden';
|
|
}
|
|
|
|
function closeMobilePreview() {
|
|
document.getElementById('previewSheetOverlay').classList.remove('active');
|
|
document.body.style.overflow = '';
|
|
}
|
|
|
|
var previewOverlay = document.getElementById('previewSheetOverlay');
|
|
if (previewOverlay) {
|
|
previewOverlay.addEventListener('click', function(e) {
|
|
if (e.target === this) closeMobilePreview();
|
|
});
|
|
}
|
|
{% endblock %}
|