feat: add mobile PWA installation guide with smart banner
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
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
Mobile-only install instructions at /zainstaluj-aplikacje with auto-detected iPhone/Android tabs, CSS UI mockups, and step-by-step guide. Smart banner appears after 3s on mobile (dismissible via localStorage), hidden in standalone mode. Footer link and login page hint also mobile-only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
84169af76e
commit
caa6cc45be
@ -1557,6 +1557,12 @@ def release_notes():
|
|||||||
return render_template('release_notes.html', releases=releases, stats=stats)
|
return render_template('release_notes.html', releases=releases, stats=stats)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/zainstaluj-aplikacje')
|
||||||
|
def pwa_install():
|
||||||
|
"""Instrukcja instalacji PWA na telefonie."""
|
||||||
|
return render_template('pwa_install.html')
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/robots.txt')
|
@bp.route('/robots.txt')
|
||||||
def robots_txt():
|
def robots_txt():
|
||||||
"""Robots.txt for search engine crawlers."""
|
"""Robots.txt for search engine crawlers."""
|
||||||
@ -1591,5 +1597,11 @@ def sitemap_xml():
|
|||||||
<changefreq>weekly</changefreq>
|
<changefreq>weekly</changefreq>
|
||||||
<priority>0.5</priority>
|
<priority>0.5</priority>
|
||||||
</url>
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://nordabiznes.pl/zainstaluj-aplikacje</loc>
|
||||||
|
<lastmod>{today}</lastmod>
|
||||||
|
<changefreq>monthly</changefreq>
|
||||||
|
<priority>0.4</priority>
|
||||||
|
</url>
|
||||||
</urlset>"""
|
</urlset>"""
|
||||||
return Response(xml, mimetype='application/xml')
|
return Response(xml, mimetype='application/xml')
|
||||||
|
|||||||
@ -139,6 +139,35 @@
|
|||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* PWA login hint — mobile only */
|
||||||
|
.pwa-login-hint {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: var(--spacing-lg);
|
||||||
|
padding: var(--spacing-md);
|
||||||
|
background: #f0f4ff;
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-login-hint a {
|
||||||
|
color: var(--primary);
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-login-hint a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.pwa-login-hint { display: block; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (display-mode: standalone) {
|
||||||
|
.pwa-login-hint { display: none !important; }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -216,6 +245,13 @@
|
|||||||
<p style="margin-top: var(--spacing-sm);"><a href="{{ url_for('resend_verification') }}">Nie otrzymales emaila weryfikacyjnego?</a></p>
|
<p style="margin-top: var(--spacing-sm);"><a href="{{ url_for('resend_verification') }}">Nie otrzymales emaila weryfikacyjnego?</a></p>
|
||||||
<p style="margin-top: var(--spacing-sm);">Nie masz konta? <a href="{{ url_for('register') }}">Zarejestruj sie</a></p>
|
<p style="margin-top: var(--spacing-sm);">Nie masz konta? <a href="{{ url_for('register') }}">Zarejestruj sie</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- PWA hint (mobile-only) -->
|
||||||
|
<div class="pwa-login-hint">
|
||||||
|
<a href="{{ url_for('public.pwa_install') }}">
|
||||||
|
📱 Dodaj portal na ekran telefonu
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -1272,6 +1272,109 @@
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
* PWA INSTALL BANNER (mobile-only)
|
||||||
|
* ============================================================ */
|
||||||
|
.pwa-smart-banner {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: var(--surface);
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
padding: 12px 16px;
|
||||||
|
z-index: 9999;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
transform: translateY(100%);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-smart-banner.visible {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-smart-banner-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-smart-banner-icon img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-smart-banner-text {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-smart-banner-text strong {
|
||||||
|
display: block;
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-smart-banner-text span {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-smart-banner-action {
|
||||||
|
background: var(--primary);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
font-weight: 600;
|
||||||
|
font-family: var(--font-family);
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-smart-banner-close {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer PWA link — mobile only */
|
||||||
|
.footer-pwa-link {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.pwa-smart-banner {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.footer-pwa-link {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide banner in standalone (already installed) */
|
||||||
|
@media (display-mode: standalone) {
|
||||||
|
.pwa-smart-banner {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
.footer-pwa-link {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{% block extra_css %}{% endblock %}
|
{% block extra_css %}{% endblock %}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@ -1791,6 +1894,7 @@
|
|||||||
<a href="{{ url_for('classifieds.classifieds_index') }}">Tablica B2B</a>
|
<a href="{{ url_for('classifieds.classifieds_index') }}">Tablica B2B</a>
|
||||||
<a href="{{ url_for('chat') }}">NordaGPT</a>
|
<a href="{{ url_for('chat') }}">NordaGPT</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<a href="{{ url_for('public.pwa_install') }}" class="footer-pwa-link">📱 Zainstaluj aplikację</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-section">
|
<div class="footer-section">
|
||||||
<h3>Kontakt</h3>
|
<h3>Kontakt</h3>
|
||||||
@ -1813,6 +1917,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<!-- PWA Smart Banner (mobile-only) -->
|
||||||
|
<div class="pwa-smart-banner" id="pwaSmartBanner">
|
||||||
|
<div class="pwa-smart-banner-icon">
|
||||||
|
<img src="{{ url_for('static', filename='img/favicon-192.png') }}" alt="Norda Biznes">
|
||||||
|
</div>
|
||||||
|
<div class="pwa-smart-banner-text">
|
||||||
|
<strong>Norda Biznes Partner</strong>
|
||||||
|
<span>Dodaj do ekranu głównego</span>
|
||||||
|
</div>
|
||||||
|
<a href="{{ url_for('public.pwa_install') }}" class="pwa-smart-banner-action">Zainstaluj</a>
|
||||||
|
<button class="pwa-smart-banner-close" onclick="dismissPwaBanner()" aria-label="Zamknij">
|
||||||
|
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
<script>
|
<script>
|
||||||
// User menu toggle
|
// User menu toggle
|
||||||
@ -2135,6 +2254,31 @@
|
|||||||
setInterval(updateNotificationBadgeFromAPI, 60000);
|
setInterval(updateNotificationBadgeFromAPI, 60000);
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
// PWA Smart Banner logic
|
||||||
|
(function() {
|
||||||
|
var banner = document.getElementById('pwaSmartBanner');
|
||||||
|
if (!banner) return;
|
||||||
|
|
||||||
|
// Don't show if: already dismissed, or running in standalone mode
|
||||||
|
var isStandalone = window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone;
|
||||||
|
var isDismissed = localStorage.getItem('pwa_banner_dismissed');
|
||||||
|
|
||||||
|
if (isStandalone || isDismissed) return;
|
||||||
|
|
||||||
|
// Show after 3 seconds
|
||||||
|
setTimeout(function() {
|
||||||
|
banner.classList.add('visible');
|
||||||
|
}, 3000);
|
||||||
|
})();
|
||||||
|
|
||||||
|
function dismissPwaBanner() {
|
||||||
|
var banner = document.getElementById('pwaSmartBanner');
|
||||||
|
if (banner) {
|
||||||
|
banner.classList.remove('visible');
|
||||||
|
localStorage.setItem('pwa_banner_dismissed', '1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{% block extra_js %}{% endblock %}
|
{% block extra_js %}{% endblock %}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
529
templates/pwa_install.html
Normal file
529
templates/pwa_install.html
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Zainstaluj aplikację - Norda Biznes Partner{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
<style>
|
||||||
|
.pwa-page {
|
||||||
|
max-width: 540px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: var(--spacing-xl) var(--spacing-md) var(--spacing-2xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: var(--spacing-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-header h1 {
|
||||||
|
font-size: var(--font-size-2xl);
|
||||||
|
color: var(--text-primary);
|
||||||
|
margin-bottom: var(--spacing-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-header p {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktop fallback message */
|
||||||
|
.pwa-desktop-msg {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
padding: var(--spacing-2xl) var(--spacing-lg);
|
||||||
|
background: var(--surface);
|
||||||
|
border-radius: var(--radius-xl);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-desktop-msg .phone-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: var(--spacing-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-desktop-msg h2 {
|
||||||
|
font-size: var(--font-size-xl);
|
||||||
|
margin-bottom: var(--spacing-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-desktop-msg p {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab switcher */
|
||||||
|
.pwa-tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--spacing-sm);
|
||||||
|
margin-bottom: var(--spacing-xl);
|
||||||
|
background: var(--surface);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: 4px;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-tab {
|
||||||
|
flex: 1;
|
||||||
|
padding: var(--spacing-md);
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: var(--radius);
|
||||||
|
font-family: var(--font-family);
|
||||||
|
font-size: var(--font-size-base);
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: var(--spacing-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-tab.active {
|
||||||
|
background: var(--primary);
|
||||||
|
color: white;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-tab:not(.active):hover {
|
||||||
|
background: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-tab-icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step cards */
|
||||||
|
.pwa-steps {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-steps.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-step {
|
||||||
|
background: var(--surface);
|
||||||
|
border-radius: var(--radius-xl);
|
||||||
|
padding: var(--spacing-lg);
|
||||||
|
margin-bottom: var(--spacing-md);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
display: flex;
|
||||||
|
gap: var(--spacing-lg);
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-step-number {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
min-width: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--primary);
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: var(--font-size-xl);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-step-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-step-content h3 {
|
||||||
|
font-size: var(--font-size-base);
|
||||||
|
margin-bottom: var(--spacing-xs);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-step-content p {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
margin-bottom: var(--spacing-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CSS mockups */
|
||||||
|
.mockup-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: var(--spacing-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iOS Share icon mockup */
|
||||||
|
.mockup-share-ios {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mockup-share-ios::before {
|
||||||
|
content: '';
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border: 2.5px solid #007AFF;
|
||||||
|
border-top: none;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mockup-share-ios::after {
|
||||||
|
content: '';
|
||||||
|
width: 2.5px;
|
||||||
|
height: 16px;
|
||||||
|
background: #007AFF;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mockup-share-ios .arrow-head {
|
||||||
|
position: absolute;
|
||||||
|
top: -1px;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-left: 2.5px solid #007AFF;
|
||||||
|
border-top: 2.5px solid #007AFF;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Android 3-dot menu mockup */
|
||||||
|
.mockup-dots-android {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mockup-dots-android span {
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #5f6368;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mockup button pill */
|
||||||
|
.mockup-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--spacing-sm);
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
font-weight: 600;
|
||||||
|
font-family: var(--font-family);
|
||||||
|
border: none;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mockup-btn-ios {
|
||||||
|
background: #007AFF;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mockup-btn-android {
|
||||||
|
background: #1a73e8;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pulse animation on key elements */
|
||||||
|
.pulse-highlight {
|
||||||
|
animation: pulseGlow 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulseGlow {
|
||||||
|
0%, 100% { box-shadow: 0 0 0 0 rgba(46, 72, 114, 0.4); }
|
||||||
|
50% { box-shadow: 0 0 0 8px rgba(46, 72, 114, 0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mockup menu item highlight */
|
||||||
|
.mockup-menu-item {
|
||||||
|
background: var(--background);
|
||||||
|
border-radius: var(--radius);
|
||||||
|
padding: 8px 14px;
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
color: var(--text-primary);
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--spacing-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mockup-menu-item.highlight {
|
||||||
|
background: #e8f0fe;
|
||||||
|
color: #1a73e8;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Success section */
|
||||||
|
.pwa-success {
|
||||||
|
background: var(--surface);
|
||||||
|
border-radius: var(--radius-xl);
|
||||||
|
padding: var(--spacing-xl);
|
||||||
|
text-align: center;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
border: 2px solid var(--success);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-success h3 {
|
||||||
|
color: var(--success);
|
||||||
|
margin-bottom: var(--spacing-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-success p {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-success-icon-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: var(--spacing-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-app-icon-mockup {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
border-radius: 14px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-app-icon-mockup img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Safari warning for iOS */
|
||||||
|
.pwa-warning {
|
||||||
|
background: #FFF7ED;
|
||||||
|
border: 1px solid #FDBA74;
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
padding: var(--spacing-md);
|
||||||
|
margin-bottom: var(--spacing-lg);
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
color: #9A3412;
|
||||||
|
display: flex;
|
||||||
|
gap: var(--spacing-sm);
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pwa-warning-icon {
|
||||||
|
font-size: var(--font-size-xl);
|
||||||
|
line-height: 1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile-only: show steps, hide desktop msg */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.pwa-desktop-msg { display: none !important; }
|
||||||
|
.pwa-mobile-content { display: block !important; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Desktop: show desktop msg, hide steps */
|
||||||
|
@media (min-width: 769px) {
|
||||||
|
.pwa-desktop-msg { display: block !important; }
|
||||||
|
.pwa-mobile-content { display: none !important; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="pwa-page">
|
||||||
|
<div class="pwa-header">
|
||||||
|
<h1>Zainstaluj aplikację</h1>
|
||||||
|
<p>Norda Biznes Partner na ekranie Twojego telefonu</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Desktop fallback -->
|
||||||
|
<div class="pwa-desktop-msg">
|
||||||
|
<div class="phone-icon">📱</div>
|
||||||
|
<h2>Otwórz tę stronę na telefonie</h2>
|
||||||
|
<p>Instrukcja instalacji jest przeznaczona dla urządzeń mobilnych. Wejdź na <strong>nordabiznes.pl/zainstaluj-aplikacje</strong> w przeglądarce na swoim telefonie.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mobile content -->
|
||||||
|
<div class="pwa-mobile-content" style="display: none;">
|
||||||
|
|
||||||
|
<!-- Tab switcher -->
|
||||||
|
<div class="pwa-tabs">
|
||||||
|
<button class="pwa-tab active" data-target="ios" onclick="switchPwaTab('ios')">
|
||||||
|
<svg class="pwa-tab-icon" viewBox="0 0 24 24" fill="currentColor"><path d="M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.8-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"/></svg>
|
||||||
|
iPhone
|
||||||
|
</button>
|
||||||
|
<button class="pwa-tab" data-target="android" onclick="switchPwaTab('android')">
|
||||||
|
<svg class="pwa-tab-icon" viewBox="0 0 24 24" fill="currentColor"><path d="M6 18c0 .55.45 1 1 1h1v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h2v3.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5V19h1c.55 0 1-.45 1-1V8H6v10zM3.5 8C2.67 8 2 8.67 2 9.5v7c0 .83.67 1.5 1.5 1.5S5 17.33 5 16.5v-7C5 8.67 4.33 8 3.5 8zm17 0c-.83 0-1.5.67-1.5 1.5v7c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-7c0-.83-.67-1.5-1.5-1.5zm-4.97-5.84l1.3-1.3c.2-.2.2-.51 0-.71-.2-.2-.51-.2-.71 0l-1.48 1.48C13.85 1.23 12.95 1 12 1c-.96 0-1.86.23-2.66.63L7.85.15c-.2-.2-.51-.2-.71 0-.2.2-.2.51 0 .71l1.31 1.31C6.97 3.26 6 5.01 6 7h12c0-1.99-.97-3.75-2.47-4.84zM10 5H9V4h1v1zm5 0h-1V4h1v1z"/></svg>
|
||||||
|
Android
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- iOS steps -->
|
||||||
|
<div class="pwa-steps active" id="pwa-ios">
|
||||||
|
<div class="pwa-warning">
|
||||||
|
<span class="pwa-warning-icon">⚠️</span>
|
||||||
|
<div><strong>Ważne:</strong> Na iPhonie instalacja działa <strong>tylko w Safari</strong>. Jeśli używasz Chrome lub innej przeglądarki, otwórz najpierw Safari.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number">1</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Otwórz Safari</h3>
|
||||||
|
<p>Wejdź na <strong>nordabiznes.pl</strong> w przeglądarce Safari na swoim iPhonie.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number pulse-highlight">2</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Stuknij przycisk „Udostępnij"</h3>
|
||||||
|
<p>Na dole ekranu znajdziesz ikonkę kwadratu ze strzałką w górę.</p>
|
||||||
|
<div class="mockup-container">
|
||||||
|
<div class="mockup-share-ios pulse-highlight" style="border-radius: 8px; padding: 8px; background: #f0f0f0;">
|
||||||
|
<span class="arrow-head"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number">3</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Przewiń menu w dół</h3>
|
||||||
|
<p>Znajdź opcję:</p>
|
||||||
|
<div class="mockup-container">
|
||||||
|
<span class="mockup-menu-item highlight">
|
||||||
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#1a73e8" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>
|
||||||
|
Dodaj do ekranu początkowego
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number">4</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Potwierdź „Dodaj"</h3>
|
||||||
|
<p>Stuknij przycisk <strong>Dodaj</strong> w prawym górnym rogu.</p>
|
||||||
|
<div class="mockup-container">
|
||||||
|
<span class="mockup-btn mockup-btn-ios">Dodaj</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number" style="background: var(--success);">✓</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Gotowe!</h3>
|
||||||
|
<p>Ikona Norda Biznes pojawi się na Twoim ekranie głównym.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-success">
|
||||||
|
<div class="pwa-success-icon-wrapper">
|
||||||
|
<div class="pwa-app-icon-mockup">
|
||||||
|
<img src="{{ url_for('static', filename='img/favicon-192.png') }}" alt="Ikona Norda Biznes">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3>Norda Biznes Partner</h3>
|
||||||
|
<p>Aplikacja otworzy się w trybie pełnoekranowym — tak jak prawdziwa aplikacja ze sklepu!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Android steps -->
|
||||||
|
<div class="pwa-steps" id="pwa-android">
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number">1</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Otwórz Chrome</h3>
|
||||||
|
<p>Wejdź na <strong>nordabiznes.pl</strong> w przeglądarce Chrome na swoim telefonie.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number pulse-highlight">2</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Stuknij menu (trzy kropki)</h3>
|
||||||
|
<p>W prawym górnym rogu ekranu znajdziesz ikonkę trzech kropek.</p>
|
||||||
|
<div class="mockup-container">
|
||||||
|
<div class="mockup-dots-android pulse-highlight" style="border-radius: 8px; padding: 10px 8px; background: #f0f0f0;">
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number">3</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Wybierz „Zainstaluj aplikację"</h3>
|
||||||
|
<p>Na niektórych telefonach opcja może nazywać się „Dodaj do ekranu głównego".</p>
|
||||||
|
<div class="mockup-container">
|
||||||
|
<span class="mockup-menu-item highlight">
|
||||||
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#1a73e8" stroke-width="2"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||||
|
Zainstaluj aplikację
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number">4</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Potwierdź „Zainstaluj"</h3>
|
||||||
|
<p>Stuknij przycisk <strong>Zainstaluj</strong> w okienku potwierdzenia.</p>
|
||||||
|
<div class="mockup-container">
|
||||||
|
<span class="mockup-btn mockup-btn-android">Zainstaluj</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-step">
|
||||||
|
<div class="pwa-step-number" style="background: var(--success);">✓</div>
|
||||||
|
<div class="pwa-step-content">
|
||||||
|
<h3>Gotowe!</h3>
|
||||||
|
<p>Ikona Norda Biznes pojawi się na Twoim ekranie głównym.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pwa-success">
|
||||||
|
<div class="pwa-success-icon-wrapper">
|
||||||
|
<div class="pwa-app-icon-mockup">
|
||||||
|
<img src="{{ url_for('static', filename='img/favicon-192.png') }}" alt="Ikona Norda Biznes">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3>Norda Biznes Partner</h3>
|
||||||
|
<p>Aplikacja otworzy się w trybie pełnoekranowym — tak jak prawdziwa aplikacja ze sklepu!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_js %}
|
||||||
|
// Auto-detect platform
|
||||||
|
(function() {
|
||||||
|
var ua = navigator.userAgent || '';
|
||||||
|
var isIOS = /iPad|iPhone|iPod/.test(ua) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
|
||||||
|
if (!isIOS && /Android/i.test(ua)) {
|
||||||
|
switchPwaTab('android');
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
function switchPwaTab(platform) {
|
||||||
|
// Update tabs
|
||||||
|
document.querySelectorAll('.pwa-tab').forEach(function(tab) {
|
||||||
|
tab.classList.toggle('active', tab.getAttribute('data-target') === platform);
|
||||||
|
});
|
||||||
|
// Update step panels
|
||||||
|
document.querySelectorAll('.pwa-steps').forEach(function(panel) {
|
||||||
|
panel.classList.toggle('active', panel.id === 'pwa-' + platform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{% endblock %}
|
||||||
Loading…
Reference in New Issue
Block a user