158 lines
7.6 KiB
HTML
158 lines
7.6 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}The Shooter's Network — Track, analyze, share{% endblock %}
|
|
|
|
{% block body %}
|
|
<nav class="nav">
|
|
<a href="/" class="nav-brand">The Shooter's Network</a>
|
|
<div class="nav-links">
|
|
{% if current_user.is_authenticated %}
|
|
<a href="{{ url_for('analyze') }}">New Analysis</a>
|
|
<a href="{{ url_for('equipment.index') }}">Equipment</a>
|
|
<a href="{{ url_for('sessions.index') }}">Sessions</a>
|
|
<a href="{{ url_for('dashboard.index') }}">Dashboard</a>
|
|
{% endif %}
|
|
</div>
|
|
<div class="nav-right">
|
|
{% if current_user.is_authenticated %}
|
|
<div class="nav-dropdown" id="userDropdown">
|
|
<button class="nav-user-btn" onclick="toggleDropdown(event)">
|
|
{% set av = current_user.effective_avatar_url %}
|
|
{% if av %}<img src="{{ av }}" class="nav-avatar" alt="">
|
|
{% else %}<span style="font-size:1.1rem;line-height:1;">👤</span>{% endif %}
|
|
<span>{{ current_user.display_name or current_user.email.split('@')[0] }}</span>
|
|
<span class="caret">▼</span>
|
|
</button>
|
|
<div class="nav-dd-menu">
|
|
<a href="{{ url_for('auth.profile') }}">👤 Profile</a>
|
|
<hr>
|
|
<form method="post" action="{{ url_for('auth.logout') }}">
|
|
<button type="submit">→ Logout</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<a href="{{ url_for('auth.login') }}" style="color:#c8cfe0;font-size:0.9rem;text-decoration:none;">Login</a>
|
|
<a href="{{ url_for('auth.register') }}"
|
|
style="background:#1f77b4;color:#fff;padding:0.35rem 0.9rem;border-radius:4px;font-size:0.88rem;text-decoration:none;">
|
|
Join free
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</nav>
|
|
<script>
|
|
function toggleDropdown(e) {
|
|
e.stopPropagation();
|
|
document.getElementById('userDropdown').classList.toggle('open');
|
|
}
|
|
document.addEventListener('click', function() {
|
|
var d = document.getElementById('userDropdown');
|
|
if (d) d.classList.remove('open');
|
|
});
|
|
</script>
|
|
|
|
<!-- ── Hero ── -->
|
|
<section style="background:#1a1a2e;color:#fff;padding:4rem 1.5rem;text-align:center;">
|
|
<h1 style="font-size:2.4rem;font-weight:800;color:#fff;margin-bottom:0.75rem;letter-spacing:-0.02em;">
|
|
The Shooter's Network
|
|
</h1>
|
|
<p style="font-size:1.15rem;color:#a0aec0;max-width:560px;margin:0 auto 2rem;">
|
|
Analyze your ballistic data, track every session, manage your equipment,
|
|
and share your performance with the community.
|
|
</p>
|
|
<div style="display:flex;gap:1rem;justify-content:center;flex-wrap:wrap;">
|
|
{% if current_user.is_authenticated %}
|
|
<a href="{{ url_for('analyze') }}"
|
|
style="background:#1f77b4;color:#fff;padding:0.75rem 1.75rem;border-radius:6px;font-size:1rem;font-weight:600;text-decoration:none;">
|
|
New Analysis
|
|
</a>
|
|
<a href="{{ url_for('sessions.new') }}"
|
|
style="background:transparent;color:#fff;padding:0.75rem 1.75rem;border-radius:6px;font-size:1rem;font-weight:600;text-decoration:none;border:1px solid #4a5568;">
|
|
Log a Session
|
|
</a>
|
|
{% else %}
|
|
<a href="{{ url_for('auth.register') }}"
|
|
style="background:#1f77b4;color:#fff;padding:0.75rem 1.75rem;border-radius:6px;font-size:1rem;font-weight:600;text-decoration:none;">
|
|
Get started — free
|
|
</a>
|
|
<a href="{{ url_for('analyze') }}"
|
|
style="background:transparent;color:#fff;padding:0.75rem 1.75rem;border-radius:6px;font-size:1rem;font-weight:600;text-decoration:none;border:1px solid #4a5568;">
|
|
Try without account
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ── Features ── -->
|
|
<section style="background:#f8f9fb;padding:2.5rem 1.5rem;">
|
|
<div style="max-width:900px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1.25rem;">
|
|
<div style="background:#fff;padding:1.5rem;border-radius:8px;box-shadow:0 1px 4px rgba(0,0,0,.07);">
|
|
<div style="font-size:1.6rem;margin-bottom:0.5rem;">📊</div>
|
|
<h3 style="margin:0 0 .35rem;color:#1a1a2e;font-size:1rem;">Ballistic Analysis</h3>
|
|
<p style="color:#666;font-size:0.88rem;margin:0;">Upload CSV files from your chronograph and get instant shot-group statistics, velocity charts, and PDF reports.</p>
|
|
</div>
|
|
<div style="background:#fff;padding:1.5rem;border-radius:8px;box-shadow:0 1px 4px rgba(0,0,0,.07);">
|
|
<div style="font-size:1.6rem;margin-bottom:0.5rem;">🎯</div>
|
|
<h3 style="margin:0 0 .35rem;color:#1a1a2e;font-size:1rem;">Session Tracking</h3>
|
|
<p style="color:#666;font-size:0.88rem;margin:0;">Log every range visit with location, weather, rifle, ammo, and distance. All your data in one place.</p>
|
|
</div>
|
|
<div style="background:#fff;padding:1.5rem;border-radius:8px;box-shadow:0 1px 4px rgba(0,0,0,.07);">
|
|
<div style="font-size:1.6rem;margin-bottom:0.5rem;">🤝</div>
|
|
<h3 style="margin:0 0 .35rem;color:#1a1a2e;font-size:1rem;">Community Feed</h3>
|
|
<p style="color:#666;font-size:0.88rem;margin:0;">Share your public sessions and see what other shooters are achieving on the range.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ── Flash messages ── -->
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
<div style="max-width:960px;margin:1rem auto;padding:0 1.5rem;">
|
|
{% for category, message in messages %}
|
|
<div class="flash {{ category }}">{{ message }}</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
{% endwith %}
|
|
|
|
<!-- ── Public sessions feed ── -->
|
|
<section style="padding:2.5rem 1.5rem 3rem;">
|
|
<div style="max-width:960px;margin:0 auto;">
|
|
<h2 style="font-size:1.3rem;color:#1a1a2e;margin-bottom:1.25rem;border-bottom:2px solid #e0e0e0;padding-bottom:.4rem;">
|
|
Latest sessions
|
|
</h2>
|
|
|
|
{% if public_sessions %}
|
|
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:1.1rem;">
|
|
{% for s in public_sessions %}
|
|
<a href="{{ url_for('sessions.detail', session_id=s.id) }}"
|
|
style="display:block;background:#fff;border:1px solid #e8e8e8;border-radius:8px;padding:1.1rem 1.25rem;text-decoration:none;color:inherit;">
|
|
<div style="display:flex;align-items:center;gap:0.55rem;margin-bottom:0.65rem;">
|
|
{% if s.user.avatar_url %}
|
|
<img src="{{ s.user.avatar_url }}" style="width:26px;height:26px;border-radius:50%;object-fit:cover;" alt="">
|
|
{% else %}
|
|
<div style="width:26px;height:26px;border-radius:50%;background:#e0e4f0;display:flex;align-items:center;justify-content:center;font-size:0.72rem;color:#666;font-weight:700;">
|
|
{{ (s.user.display_name or s.user.email)[0].upper() }}
|
|
</div>
|
|
{% endif %}
|
|
<span style="font-size:0.83rem;color:#666;">{{ s.user.display_name or s.user.email.split('@')[0] }}</span>
|
|
</div>
|
|
<div style="font-weight:600;color:#1a1a2e;margin-bottom:0.35rem;font-size:0.95rem;">{{ s.label }}</div>
|
|
<div style="font-size:0.81rem;color:#888;display:flex;flex-wrap:wrap;gap:.3rem .65rem;">
|
|
<span>{{ s.session_date.strftime('%d %b %Y') }}</span>
|
|
{% if s.location_name %}<span>📍 {{ s.location_name }}</span>{% endif %}
|
|
{% if s.distance_m %}<span>{{ s.distance_m }} m</span>{% endif %}
|
|
{% if s.weather_cond %}<span>{{ s.weather_cond.replace('_', ' ').title() }}</span>{% endif %}
|
|
{% if s.weather_temp_c is not none %}<span>{{ s.weather_temp_c }}°C</span>{% endif %}
|
|
</div>
|
|
</a>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<p style="color:#aaa;text-align:center;padding:3rem 0;">
|
|
No public sessions yet. Be the first to share one!
|
|
</p>
|
|
{% endif %}
|
|
</div>
|
|
</section>
|
|
{% endblock %}
|