Remove admin pricing stack and prepare v1.0.4 release

This commit is contained in:
2026-02-07 21:23:23 +03:00
parent 95b5f8bf65
commit 7523a7d887
28 changed files with 611 additions and 7584 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@
<a href="/" class="text-xl font-bold text-blue-600">QuoteForge</a>
<div class="hidden md:flex space-x-4">
<a href="/projects" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm">Мои проекты</a>
<a id="admin-pricing-link" href="/admin/pricing" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm">Администратор цен</a>
<a href="/pricelists" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm">Прайслисты</a>
<a href="/setup" class="text-gray-600 hover:text-gray-900 px-3 py-2 text-sm">Настройки</a>
</div>
</div>
@@ -81,6 +81,14 @@
</div>
</div>
<div id="modal-readiness-section" class="hidden">
<h4 class="font-medium text-red-700 mb-2">Почему синхронизация недоступна</h4>
<div class="bg-red-50 border border-red-200 rounded px-3 py-2 text-sm">
<div id="modal-readiness-reason" class="text-red-700"></div>
<div id="modal-readiness-min-version" class="text-red-600 text-xs mt-1 hidden"></div>
</div>
</div>
<!-- Section 2: Statistics -->
<div>
<h4 class="font-medium text-gray-900 mb-2">Статистика</h4>
@@ -176,6 +184,26 @@
document.getElementById('modal-last-sync').textContent = '—';
}
const readinessSection = document.getElementById('modal-readiness-section');
const readinessReason = document.getElementById('modal-readiness-reason');
const readinessMinVersion = document.getElementById('modal-readiness-min-version');
if (data.readiness && data.readiness.blocked) {
readinessSection.classList.remove('hidden');
readinessReason.textContent = data.readiness.reason_text || 'Синхронизация заблокирована preflight-проверкой.';
if (data.readiness.required_min_app_version) {
readinessMinVersion.classList.remove('hidden');
readinessMinVersion.textContent = 'Требуется обновление до версии ' + data.readiness.required_min_app_version;
} else {
readinessMinVersion.classList.add('hidden');
readinessMinVersion.textContent = '';
}
} else {
readinessSection.classList.add('hidden');
readinessReason.textContent = '';
readinessMinVersion.classList.add('hidden');
readinessMinVersion.textContent = '';
}
// Section 2: Statistics
document.getElementById('modal-lot-count').textContent = data.is_online ? data.lot_count.toLocaleString() : '—';
document.getElementById('modal-lotlog-count').textContent = data.is_online ? data.lot_log_count.toLocaleString() : '—';
@@ -257,6 +285,11 @@
showToast(successMessage, 'success');
// Update last sync time - removed since dropdown is gone
// loadLastSyncTime();
} else if (resp.status === 423) {
const reason = data.reason_text || data.error || 'Синхронизация заблокирована.';
showToast(reason, 'error');
openSyncModal();
loadSyncInfo();
} else {
showToast('Ошибка: ' + (data.error || 'неизвестная ошибка'), 'error');
}

View File

@@ -14,7 +14,14 @@
</span>
{{end}}
{{if gt .PendingCount 0}}
{{if .IsBlocked}}
<span class="bg-red-100 text-red-800 px-2 py-0.5 rounded-full text-xs font-medium flex items-center gap-1 cursor-pointer" title="{{.BlockedReason}}" onclick="openSyncModal()">
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-7.938 4h15.876c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L2.33 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
!
</span>
{{else if gt .PendingCount 0}}
<span class="bg-yellow-100 text-yellow-800 px-2 py-0.5 rounded-full text-xs font-medium flex items-center gap-1 cursor-pointer" onclick="openSyncModal()">
<svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>