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
Replace ~20 remaining is_admin references across backend, templates and scripts with proper SystemRole checks. Column is_admin stays as deprecated (synced by set_role()) until DB migration removes it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1080 lines
31 KiB
HTML
1080 lines
31 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Przegląd proponowanych zmian - Norda Biznes Partner{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.review-container {
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.review-header {
|
|
margin-bottom: var(--spacing-2xl);
|
|
}
|
|
|
|
.review-header h1 {
|
|
font-size: var(--font-size-2xl);
|
|
color: var(--text-primary);
|
|
margin: 0 0 var(--spacing-sm) 0;
|
|
}
|
|
|
|
.review-header p {
|
|
color: var(--text-secondary);
|
|
margin: 0;
|
|
}
|
|
|
|
.review-card {
|
|
background: var(--surface);
|
|
border-radius: var(--radius-lg);
|
|
box-shadow: var(--shadow);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.review-card-header {
|
|
background: linear-gradient(135deg, #0ea5e9 0%, #0284c7 100%);
|
|
color: white;
|
|
padding: var(--spacing-xl);
|
|
}
|
|
|
|
.review-card-header h2 {
|
|
margin: 0 0 var(--spacing-sm) 0;
|
|
font-size: var(--font-size-lg);
|
|
}
|
|
|
|
.review-card-header .company-info {
|
|
opacity: 0.9;
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.review-card-body {
|
|
padding: var(--spacing-xl);
|
|
}
|
|
|
|
.info-box {
|
|
background: rgba(14, 165, 233, 0.1);
|
|
border: 1px solid rgba(14, 165, 233, 0.3);
|
|
border-radius: var(--radius);
|
|
padding: var(--spacing-lg);
|
|
margin-bottom: var(--spacing-xl);
|
|
}
|
|
|
|
.info-box p {
|
|
margin: 0;
|
|
color: var(--text-primary);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.info-box strong {
|
|
color: #0ea5e9;
|
|
}
|
|
|
|
.changes-list {
|
|
margin-bottom: var(--spacing-xl);
|
|
}
|
|
|
|
.change-item {
|
|
background: var(--background);
|
|
border-radius: var(--radius);
|
|
padding: var(--spacing-lg);
|
|
margin-bottom: var(--spacing-md);
|
|
border-left: 4px solid var(--primary);
|
|
}
|
|
|
|
.change-label {
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
margin-bottom: var(--spacing-sm);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
}
|
|
|
|
.change-label svg {
|
|
color: var(--primary);
|
|
}
|
|
|
|
.change-values {
|
|
display: grid;
|
|
grid-template-columns: 1fr 40px 1fr;
|
|
align-items: center;
|
|
gap: var(--spacing-md);
|
|
margin-top: var(--spacing-md);
|
|
}
|
|
|
|
.old-value, .new-value {
|
|
padding: var(--spacing-md);
|
|
border-radius: var(--radius);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.old-value {
|
|
background: rgba(239, 68, 68, 0.1);
|
|
border: 1px dashed rgba(239, 68, 68, 0.3);
|
|
color: var(--text-secondary);
|
|
text-decoration: line-through;
|
|
}
|
|
|
|
.new-value {
|
|
background: rgba(34, 197, 94, 0.1);
|
|
border: 1px solid rgba(34, 197, 94, 0.3);
|
|
color: var(--text-primary);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.arrow-icon {
|
|
color: var(--text-secondary);
|
|
text-align: center;
|
|
}
|
|
|
|
.value-empty {
|
|
color: var(--text-secondary);
|
|
font-style: italic;
|
|
}
|
|
|
|
.admin-comment {
|
|
background: var(--background);
|
|
border-radius: var(--radius);
|
|
padding: var(--spacing-lg);
|
|
margin-bottom: var(--spacing-xl);
|
|
}
|
|
|
|
.admin-comment-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
margin-bottom: var(--spacing-sm);
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.admin-comment p {
|
|
margin: 0;
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.reviewer-role {
|
|
font-size: var(--font-size-xs);
|
|
color: var(--text-secondary);
|
|
background: var(--background);
|
|
padding: 2px 8px;
|
|
border-radius: var(--radius);
|
|
margin-left: var(--spacing-sm);
|
|
}
|
|
|
|
.actions-section {
|
|
border-top: 1px solid var(--border);
|
|
padding-top: var(--spacing-xl);
|
|
}
|
|
|
|
.actions-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: var(--spacing-lg);
|
|
}
|
|
|
|
.action-card {
|
|
padding: var(--spacing-xl);
|
|
border-radius: var(--radius-lg);
|
|
text-align: center;
|
|
}
|
|
|
|
.action-card.accept {
|
|
background: rgba(34, 197, 94, 0.1);
|
|
border: 2px solid rgba(34, 197, 94, 0.3);
|
|
}
|
|
|
|
.action-card.reject {
|
|
background: rgba(239, 68, 68, 0.05);
|
|
border: 2px solid rgba(239, 68, 68, 0.2);
|
|
}
|
|
|
|
.action-card h3 {
|
|
margin: 0 0 var(--spacing-sm) 0;
|
|
font-size: var(--font-size-lg);
|
|
}
|
|
|
|
.action-card.accept h3 {
|
|
color: #16a34a;
|
|
}
|
|
|
|
.action-card.reject h3 {
|
|
color: #dc2626;
|
|
}
|
|
|
|
.action-card p {
|
|
margin: 0 0 var(--spacing-lg) 0;
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.btn-action {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--spacing-sm);
|
|
padding: var(--spacing-md) var(--spacing-xl);
|
|
border: none;
|
|
border-radius: var(--radius);
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
width: 100%;
|
|
}
|
|
|
|
.btn-accept {
|
|
background: #16a34a;
|
|
color: white;
|
|
}
|
|
|
|
.btn-accept:hover {
|
|
background: #15803d;
|
|
}
|
|
|
|
.btn-reject {
|
|
background: transparent;
|
|
color: #dc2626;
|
|
border: 2px solid #dc2626;
|
|
}
|
|
|
|
.btn-reject:hover {
|
|
background: rgba(239, 68, 68, 0.1);
|
|
}
|
|
|
|
.reject-comment {
|
|
margin-top: var(--spacing-md);
|
|
display: none;
|
|
}
|
|
|
|
.reject-comment.show {
|
|
display: block;
|
|
}
|
|
|
|
.reject-comment textarea {
|
|
width: 100%;
|
|
padding: var(--spacing-md);
|
|
border: 1px solid var(--border);
|
|
border-radius: var(--radius);
|
|
resize: vertical;
|
|
min-height: 80px;
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.reject-comment textarea:focus {
|
|
outline: none;
|
|
border-color: var(--primary);
|
|
}
|
|
|
|
/* Modal potwierdzenia */
|
|
.confirm-modal {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: none;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 1001;
|
|
backdrop-filter: blur(4px);
|
|
}
|
|
|
|
.confirm-modal.show {
|
|
display: flex;
|
|
}
|
|
|
|
.confirm-modal-content {
|
|
background: var(--surface);
|
|
padding: var(--spacing-2xl);
|
|
border-radius: var(--radius-lg);
|
|
max-width: 400px;
|
|
width: 90%;
|
|
text-align: center;
|
|
box-shadow: var(--shadow-lg);
|
|
animation: modalSlideIn 0.2s ease-out;
|
|
}
|
|
|
|
@keyframes modalSlideIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: scale(0.95) translateY(-10px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: scale(1) translateY(0);
|
|
}
|
|
}
|
|
|
|
.confirm-modal-icon {
|
|
margin-bottom: var(--spacing-lg);
|
|
}
|
|
|
|
.confirm-modal-icon.accept svg {
|
|
color: #16a34a;
|
|
}
|
|
|
|
.confirm-modal-icon.reject svg {
|
|
color: #dc2626;
|
|
}
|
|
|
|
.confirm-modal-icon.info svg {
|
|
color: #0ea5e9;
|
|
}
|
|
|
|
.confirm-modal-content h3 {
|
|
margin: 0 0 var(--spacing-sm) 0;
|
|
font-size: var(--font-size-lg);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.confirm-modal-content p {
|
|
margin: 0 0 var(--spacing-xl) 0;
|
|
color: var(--text-secondary);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.confirm-modal-buttons {
|
|
display: flex;
|
|
gap: var(--spacing-md);
|
|
justify-content: center;
|
|
}
|
|
|
|
.btn-modal {
|
|
padding: var(--spacing-sm) var(--spacing-xl);
|
|
border-radius: var(--radius);
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: var(--transition);
|
|
min-width: 100px;
|
|
}
|
|
|
|
.btn-modal-cancel {
|
|
background: var(--surface);
|
|
border: 1px solid var(--border);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.btn-modal-cancel:hover {
|
|
background: var(--background);
|
|
}
|
|
|
|
.btn-modal-confirm {
|
|
border: none;
|
|
color: white;
|
|
}
|
|
|
|
.btn-modal-confirm.accept {
|
|
background: #16a34a;
|
|
}
|
|
|
|
.btn-modal-confirm.accept:hover {
|
|
background: #15803d;
|
|
}
|
|
|
|
.btn-modal-confirm.reject {
|
|
background: #dc2626;
|
|
}
|
|
|
|
.btn-modal-confirm.reject:hover {
|
|
background: #b91c1c;
|
|
}
|
|
|
|
.loading-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
display: none;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.loading-overlay.show {
|
|
display: flex;
|
|
}
|
|
|
|
.loading-box {
|
|
background: var(--surface);
|
|
padding: var(--spacing-2xl);
|
|
border-radius: var(--radius-lg);
|
|
text-align: center;
|
|
}
|
|
|
|
.loading-spinner {
|
|
width: 40px;
|
|
height: 40px;
|
|
border: 3px solid var(--border);
|
|
border-top-color: var(--primary);
|
|
border-radius: 50%;
|
|
animation: spin 1s linear infinite;
|
|
margin: 0 auto var(--spacing-md);
|
|
}
|
|
|
|
@keyframes spin {
|
|
to { transform: rotate(360deg); }
|
|
}
|
|
|
|
/* Ekran sukcesu */
|
|
.success-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: var(--background);
|
|
display: none;
|
|
align-items: center;
|
|
justify-content: center;
|
|
z-index: 1002;
|
|
}
|
|
|
|
.success-overlay.show {
|
|
display: flex;
|
|
}
|
|
|
|
.success-box {
|
|
background: var(--surface);
|
|
padding: var(--spacing-2xl) var(--spacing-3xl);
|
|
border-radius: var(--radius-lg);
|
|
text-align: center;
|
|
max-width: 600px;
|
|
width: 90%;
|
|
box-shadow: var(--shadow-lg);
|
|
animation: successSlideIn 0.4s ease-out;
|
|
}
|
|
|
|
@keyframes successSlideIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-20px) scale(0.95);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0) scale(1);
|
|
}
|
|
}
|
|
|
|
.success-icon {
|
|
margin-bottom: var(--spacing-lg);
|
|
}
|
|
|
|
.success-icon.accept svg {
|
|
color: #16a34a;
|
|
}
|
|
|
|
.success-icon.reject svg {
|
|
color: #f59e0b;
|
|
}
|
|
|
|
.success-box h2 {
|
|
margin: 0 0 var(--spacing-sm) 0;
|
|
font-size: var(--font-size-xl);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.success-box > p {
|
|
margin: 0 0 var(--spacing-2xl) 0;
|
|
color: var(--text-secondary);
|
|
}
|
|
|
|
.success-progress {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: var(--spacing-2xl);
|
|
padding: var(--spacing-lg);
|
|
background: var(--background);
|
|
border-radius: var(--radius);
|
|
}
|
|
|
|
.progress-step {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
}
|
|
|
|
.step-icon {
|
|
width: 32px;
|
|
height: 32px;
|
|
border-radius: 50%;
|
|
background: var(--border);
|
|
color: var(--text-secondary);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: 600;
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
.progress-step.completed .step-icon {
|
|
background: #16a34a;
|
|
color: white;
|
|
}
|
|
|
|
.progress-step.current .step-icon {
|
|
background: #0ea5e9;
|
|
color: white;
|
|
box-shadow: 0 0 0 4px rgba(14, 165, 233, 0.2);
|
|
}
|
|
|
|
.step-label {
|
|
font-size: var(--font-size-xs);
|
|
color: var(--text-secondary);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.progress-step.completed .step-label,
|
|
.progress-step.current .step-label {
|
|
color: var(--text-primary);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.progress-line {
|
|
width: 40px;
|
|
height: 3px;
|
|
background: var(--border);
|
|
margin: 0 var(--spacing-xs);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.progress-line.completed {
|
|
background: #16a34a;
|
|
}
|
|
|
|
/* Sub-workflow (propozycja zmian) */
|
|
.progress-sub-flow {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
margin: 0 var(--spacing-xs);
|
|
position: relative;
|
|
}
|
|
|
|
.sub-flow-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
background: rgba(14, 165, 233, 0.05);
|
|
border: 1px dashed rgba(14, 165, 233, 0.3);
|
|
border-radius: var(--radius);
|
|
padding: var(--spacing-sm) var(--spacing-md);
|
|
margin: var(--spacing-xs) 0;
|
|
}
|
|
|
|
.sub-flow-arrow {
|
|
color: #0ea5e9;
|
|
font-size: 12px;
|
|
margin: 2px 0;
|
|
}
|
|
|
|
.sub-flow-step {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-xs);
|
|
font-size: var(--font-size-xs);
|
|
color: var(--text-secondary);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.sub-flow-step.completed {
|
|
color: #16a34a;
|
|
}
|
|
|
|
.sub-flow-step svg {
|
|
width: 14px;
|
|
height: 14px;
|
|
}
|
|
|
|
.sub-flow-label {
|
|
font-size: 10px;
|
|
color: var(--text-secondary);
|
|
text-align: center;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.btn-success-action {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: var(--spacing-sm);
|
|
padding: var(--spacing-md) var(--spacing-xl);
|
|
background: var(--primary);
|
|
color: white;
|
|
text-decoration: none;
|
|
border-radius: var(--radius);
|
|
font-weight: 600;
|
|
transition: var(--transition);
|
|
}
|
|
|
|
.btn-success-action:hover {
|
|
opacity: 0.9;
|
|
}
|
|
|
|
.success-comment {
|
|
background: var(--background);
|
|
border-radius: var(--radius);
|
|
padding: var(--spacing-md) var(--spacing-lg);
|
|
margin-bottom: var(--spacing-xl);
|
|
text-align: left;
|
|
max-width: 400px;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
}
|
|
|
|
.success-comment-header {
|
|
font-size: var(--font-size-sm);
|
|
color: var(--text-secondary);
|
|
margin-bottom: var(--spacing-xs);
|
|
}
|
|
|
|
.success-comment p {
|
|
margin: 0;
|
|
color: var(--text-primary);
|
|
font-size: var(--font-size-sm);
|
|
}
|
|
|
|
@media (max-width: 600px) {
|
|
.success-progress {
|
|
flex-wrap: wrap;
|
|
gap: var(--spacing-sm);
|
|
}
|
|
|
|
.progress-line {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 600px) {
|
|
.actions-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.change-values {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.arrow-icon {
|
|
transform: rotate(90deg);
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="review-container">
|
|
<div class="review-header">
|
|
<h1>Przegląd proponowanych zmian</h1>
|
|
<p>Administrator zaproponował aktualizację danych Twojej deklaracji na podstawie rejestru KRS/CEIDG</p>
|
|
</div>
|
|
|
|
<div class="review-card">
|
|
<div class="review-card-header">
|
|
<h2>{{ application.company_name }}</h2>
|
|
<div class="company-info">
|
|
NIP: {{ application.nip }}
|
|
{% if application.krs_number %}| KRS: {{ application.krs_number }}{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="review-card-body">
|
|
<div class="info-box">
|
|
<p>
|
|
<strong>{{ reviewer.name if reviewer else 'Biuro Izby NORDA' }}</strong>
|
|
{% if reviewer and reviewer.can_access_admin_panel() %}<span class="reviewer-role">Biuro Izby NORDA</span>{% endif %}
|
|
zaproponował(a) aktualizację danych na podstawie oficjalnych danych z
|
|
{% if application.registry_source == 'KRS' %}
|
|
Krajowego Rejestru Sądowego (KRS).
|
|
{% elif application.registry_source == 'CEIDG' %}
|
|
Centralnej Ewidencji i Informacji o Działalności Gospodarczej (CEIDG).
|
|
{% else %}
|
|
rejestru publicznego.
|
|
{% endif %}
|
|
Przejrzyj poniższe zmiany i zdecyduj, czy chcesz je zaakceptować.
|
|
</p>
|
|
</div>
|
|
|
|
{% if application.proposed_changes %}
|
|
<div class="changes-list">
|
|
<h3 style="margin-bottom: var(--spacing-lg); font-size: var(--font-size-base);">Proponowane zmiany:</h3>
|
|
{% for field_name, change in application.proposed_changes.items() %}
|
|
<div class="change-item">
|
|
<div class="change-label">
|
|
<svg width="18" height="18" 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>
|
|
{{ change.label }}
|
|
</div>
|
|
<div class="change-values">
|
|
<div class="old-value">
|
|
{% if change.old %}{{ change.old }}{% else %}<span class="value-empty">(brak danych)</span>{% endif %}
|
|
</div>
|
|
<div class="arrow-icon">→</div>
|
|
<div class="new-value">
|
|
{{ change.new }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if application.proposed_changes_comment %}
|
|
<div class="admin-comment">
|
|
<div class="admin-comment-header">
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>
|
|
</svg>
|
|
Komentarz od: <strong>{{ reviewer.name if reviewer else 'Biuro Izby NORDA' }}</strong>
|
|
{% if reviewer and reviewer.can_access_admin_panel() %}<span class="reviewer-role">Biuro Izby NORDA</span>{% endif %}
|
|
</div>
|
|
<p>{{ application.proposed_changes_comment }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="actions-section">
|
|
<div class="actions-grid">
|
|
<div class="action-card accept">
|
|
<h3>Akceptuję zmiany</h3>
|
|
<p>Dane zostaną zaktualizowane zgodnie z rejestrem. Deklaracja wróci do rozpatrzenia.</p>
|
|
<button type="button" class="btn-action btn-accept" onclick="acceptChanges()">
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<polyline points="20 6 9 17 4 12"/>
|
|
</svg>
|
|
Zaakceptuj zmiany
|
|
</button>
|
|
</div>
|
|
|
|
<div class="action-card reject">
|
|
<h3>Odrzucam zmiany</h3>
|
|
<p>Dane pozostaną bez zmian. Deklaracja wróci do rozpatrzenia z oryginalnymi danymi.</p>
|
|
<button type="button" class="btn-action btn-reject" onclick="showRejectForm()">
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<line x1="18" y1="6" x2="6" y2="18"/>
|
|
<line x1="6" y1="6" x2="18" y2="18"/>
|
|
</svg>
|
|
Odrzuć zmiany
|
|
</button>
|
|
<div class="reject-comment" id="rejectComment">
|
|
<textarea id="rejectReason" placeholder="Opcjonalnie: podaj powód odrzucenia zmian..."></textarea>
|
|
<button type="button" class="btn-action btn-reject" style="margin-top: var(--spacing-sm);" onclick="rejectChanges()">
|
|
Potwierdź odrzucenie
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="loading-overlay" id="loadingOverlay">
|
|
<div class="loading-box">
|
|
<div class="loading-spinner"></div>
|
|
<p>Przetwarzanie...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Ekran sukcesu -->
|
|
<div class="success-overlay" id="successOverlay">
|
|
<div class="success-box">
|
|
<div class="success-icon" id="successIcon">
|
|
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<circle cx="12" cy="12" r="10"/>
|
|
<polyline points="9 12 12 15 16 10"/>
|
|
</svg>
|
|
</div>
|
|
<h2 id="successTitle">Zmiany zaakceptowane!</h2>
|
|
<p id="successMessage">Twoja deklaracja wróciła do rozpatrzenia przez administratora.</p>
|
|
<div class="success-progress" id="successProgress">
|
|
<div class="progress-step completed">
|
|
<div class="step-icon">1</div>
|
|
<div class="step-label">Złożono deklarację</div>
|
|
</div>
|
|
<div class="progress-line completed"></div>
|
|
<div class="progress-step completed">
|
|
<div class="step-icon">2</div>
|
|
<div class="step-label">Weryfikacja danych</div>
|
|
</div>
|
|
<!-- Sub-workflow: propozycja zmian -->
|
|
<div class="progress-sub-flow">
|
|
<div class="sub-flow-container">
|
|
<div class="sub-flow-step completed">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<polyline points="20 6 9 17 4 12"/>
|
|
</svg>
|
|
<span>Propozycja zmian</span>
|
|
</div>
|
|
<div class="sub-flow-arrow">↓</div>
|
|
<div class="sub-flow-step completed">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<polyline points="20 6 9 17 4 12"/>
|
|
</svg>
|
|
<span id="userActionLabel">Twoja akceptacja</span>
|
|
</div>
|
|
<div class="sub-flow-arrow">↑</div>
|
|
</div>
|
|
<div class="sub-flow-label">Powrót do rozpatrzenia</div>
|
|
</div>
|
|
<div class="progress-line completed"></div>
|
|
<div class="progress-step current">
|
|
<div class="step-icon">3</div>
|
|
<div class="step-label">Rozpatrzenie</div>
|
|
</div>
|
|
<div class="progress-line"></div>
|
|
<div class="progress-step">
|
|
<div class="step-icon">4</div>
|
|
<div class="step-label">Decyzja</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Komentarz w ekranie sukcesu -->
|
|
{% if application.proposed_changes_comment %}
|
|
<div class="success-comment" id="successComment">
|
|
<div class="success-comment-header">
|
|
Komentarz od: <strong>{{ reviewer.name if reviewer else 'Biuro Izby NORDA' }}</strong>
|
|
</div>
|
|
<p>{{ application.proposed_changes_comment }}</p>
|
|
</div>
|
|
{% endif %}
|
|
<a href="{{ url_for('membership.status') }}" class="btn-success-action">
|
|
Zobacz status deklaracji →
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal potwierdzenia -->
|
|
<div class="confirm-modal" id="confirmModal">
|
|
<div class="confirm-modal-content">
|
|
<div class="confirm-modal-icon" id="confirmModalIcon">
|
|
<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<circle cx="12" cy="12" r="10"/>
|
|
<path d="M12 8v4"/>
|
|
<path d="M12 16h.01"/>
|
|
</svg>
|
|
</div>
|
|
<h3 id="confirmModalTitle">Potwierdź akcję</h3>
|
|
<p id="confirmModalMessage">Czy na pewno chcesz kontynuować?</p>
|
|
<div class="confirm-modal-buttons">
|
|
<button type="button" class="btn-modal btn-modal-cancel" onclick="closeConfirmModal()">Anuluj</button>
|
|
<button type="button" class="btn-modal btn-modal-confirm" id="confirmModalButton" onclick="confirmModalAction()">Potwierdź</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content || '';
|
|
const appId = {{ application.id }};
|
|
let pendingAction = null;
|
|
|
|
function showLoading() {
|
|
document.getElementById('loadingOverlay').classList.add('show');
|
|
}
|
|
|
|
function hideLoading() {
|
|
document.getElementById('loadingOverlay').classList.remove('show');
|
|
}
|
|
|
|
function showRejectForm() {
|
|
document.getElementById('rejectComment').classList.toggle('show');
|
|
}
|
|
|
|
// Ładne powiadomienia zamiast alert()
|
|
function showNotification(message, type = 'info') {
|
|
let container = document.querySelector('.flash-messages');
|
|
if (!container) {
|
|
container = document.createElement('div');
|
|
container.className = 'flash-messages';
|
|
container.setAttribute('role', 'alert');
|
|
container.setAttribute('aria-live', 'polite');
|
|
document.body.appendChild(container);
|
|
}
|
|
|
|
const flash = document.createElement('div');
|
|
flash.className = `flash flash-${type}`;
|
|
flash.innerHTML = `
|
|
<span>${message}</span>
|
|
<button class="flash-close" onclick="this.parentElement.remove()" aria-label="Zamknij">×</button>
|
|
`;
|
|
container.appendChild(flash);
|
|
|
|
setTimeout(() => {
|
|
flash.style.animation = 'slideOut 0.3s ease-out';
|
|
setTimeout(() => flash.remove(), 300);
|
|
}, 5000);
|
|
}
|
|
|
|
// Modal potwierdzenia zamiast confirm()
|
|
function showConfirmModal(title, message, type, onConfirm) {
|
|
const modal = document.getElementById('confirmModal');
|
|
const icon = document.getElementById('confirmModalIcon');
|
|
const titleEl = document.getElementById('confirmModalTitle');
|
|
const messageEl = document.getElementById('confirmModalMessage');
|
|
const button = document.getElementById('confirmModalButton');
|
|
|
|
titleEl.textContent = title;
|
|
messageEl.textContent = message;
|
|
|
|
icon.className = 'confirm-modal-icon ' + type;
|
|
button.className = 'btn-modal btn-modal-confirm ' + type;
|
|
|
|
if (type === 'accept') {
|
|
button.textContent = 'Tak, akceptuję';
|
|
icon.innerHTML = '<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="9 12 12 15 16 10"/></svg>';
|
|
} else if (type === 'reject') {
|
|
button.textContent = 'Tak, odrzucam';
|
|
icon.innerHTML = '<svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>';
|
|
}
|
|
|
|
pendingAction = onConfirm;
|
|
modal.classList.add('show');
|
|
}
|
|
|
|
function closeConfirmModal() {
|
|
document.getElementById('confirmModal').classList.remove('show');
|
|
pendingAction = null;
|
|
}
|
|
|
|
function confirmModalAction() {
|
|
const action = pendingAction; // Zapisz przed zamknięciem (closeConfirmModal zeruje pendingAction)
|
|
closeConfirmModal();
|
|
if (action) {
|
|
action();
|
|
}
|
|
}
|
|
|
|
function acceptChanges() {
|
|
showConfirmModal(
|
|
'Akceptujesz zmiany?',
|
|
'Dane firmy zostaną zaktualizowane zgodnie z rejestrem. Deklaracja wróci do rozpatrzenia przez administratora.',
|
|
'accept',
|
|
doAcceptChanges
|
|
);
|
|
}
|
|
|
|
async function doAcceptChanges() {
|
|
showLoading();
|
|
|
|
try {
|
|
const response = await fetch(`/membership/review-changes/${appId}/accept`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': csrfToken
|
|
},
|
|
body: JSON.stringify({})
|
|
});
|
|
|
|
const data = await response.json();
|
|
hideLoading();
|
|
|
|
if (data.success) {
|
|
showSuccessScreen(
|
|
'accept',
|
|
'Zmiany zaakceptowane!',
|
|
'Twoja deklaracja wróciła do rozpatrzenia przez administratora. Otrzymasz powiadomienie o decyzji.'
|
|
);
|
|
} else {
|
|
showNotification(data.error || 'Wystąpił błąd', 'error');
|
|
}
|
|
} catch (error) {
|
|
hideLoading();
|
|
showNotification('Wystąpił błąd połączenia. Spróbuj ponownie.', 'error');
|
|
}
|
|
}
|
|
|
|
function rejectChanges() {
|
|
showConfirmModal(
|
|
'Odrzucasz zmiany?',
|
|
'Dane firmy pozostaną bez zmian. Deklaracja wróci do rozpatrzenia z oryginalnymi danymi.',
|
|
'reject',
|
|
doRejectChanges
|
|
);
|
|
}
|
|
|
|
async function doRejectChanges() {
|
|
showLoading();
|
|
|
|
const comment = document.getElementById('rejectReason').value.trim();
|
|
|
|
try {
|
|
const response = await fetch(`/membership/review-changes/${appId}/reject`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': csrfToken
|
|
},
|
|
body: JSON.stringify({ comment: comment })
|
|
});
|
|
|
|
const data = await response.json();
|
|
hideLoading();
|
|
|
|
if (data.success) {
|
|
showSuccessScreen(
|
|
'reject',
|
|
'Propozycja odrzucona',
|
|
'Twoja deklaracja zachowuje oryginalne dane i wróciła do rozpatrzenia przez administratora.'
|
|
);
|
|
} else {
|
|
showNotification(data.error || 'Wystąpił błąd', 'error');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
hideLoading();
|
|
showNotification('Wystąpił błąd połączenia. Spróbuj ponownie.', 'error');
|
|
}
|
|
}
|
|
|
|
function showSuccessScreen(type, title, message) {
|
|
const overlay = document.getElementById('successOverlay');
|
|
const icon = document.getElementById('successIcon');
|
|
const titleEl = document.getElementById('successTitle');
|
|
const messageEl = document.getElementById('successMessage');
|
|
const userActionLabel = document.getElementById('userActionLabel');
|
|
|
|
if (!overlay) {
|
|
// Fallback - jeśli element nie istnieje, pokaż powiadomienie i przekieruj
|
|
showNotification('Zmiany zapisane pomyślnie! Przekierowuję...', 'success');
|
|
setTimeout(() => {
|
|
window.location.href = '{{ url_for("membership.status") }}';
|
|
}, 2000);
|
|
return;
|
|
}
|
|
|
|
titleEl.textContent = title;
|
|
messageEl.textContent = message;
|
|
|
|
icon.className = 'success-icon ' + type;
|
|
|
|
if (type === 'accept') {
|
|
icon.innerHTML = '<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="9 12 12 15 16 10"/></svg>';
|
|
if (userActionLabel) userActionLabel.textContent = 'Twoja akceptacja';
|
|
} else {
|
|
icon.innerHTML = '<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 8v4"/><path d="M12 16h.01"/></svg>';
|
|
if (userActionLabel) userActionLabel.textContent = 'Twoje odrzucenie';
|
|
}
|
|
|
|
overlay.classList.add('show');
|
|
}
|
|
|
|
// Zamknij modal klikając poza nim
|
|
document.getElementById('confirmModal').addEventListener('click', function(e) {
|
|
if (e.target === this) {
|
|
closeConfirmModal();
|
|
}
|
|
});
|
|
|
|
// Zamknij modal klawiszem Escape
|
|
document.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Escape') {
|
|
closeConfirmModal();
|
|
}
|
|
});
|
|
{% endblock %}
|