refactor(i18n): Batch 5 — eliminate {% if lang %} blocks in planner templates

53 new keys added to en/de locale files (1095 → 1148). All {% if lang %}
blocks replaced with {{ t.key }} in planner.html, 4 tab partials,
export.html, and export_waitlist.html. Feature lists converted to
key-loop pattern, large waitlist block collapsed to single-language
structure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Deeman
2026-02-21 00:13:32 +01:00
parent 43905b343b
commit 798ade2bc3
9 changed files with 156 additions and 174 deletions

View File

@@ -1093,5 +1093,58 @@
"markets_search_label": "Suche", "markets_search_label": "Suche",
"markets_country_label": "Land", "markets_country_label": "Land",
"article_detail_published_label": "Veröffentlicht", "article_detail_published_label": "Veröffentlicht",
"article_detail_research_label": "Padelnomics Forschung" "article_detail_research_label": "Padelnomics Forschung",
"planner_page_title": "Padel-Platz Finanzrechner",
"planner_meta_desc": "Plane deine Padel-Platz-Investition mit unserem Finanzrechner mit 60+ Variablen. CAPEX, Cashflow und ROI berechnen.",
"planner_step1_title": "Dein Padel-Platz",
"planner_step1_sub": "Definiere den Typ des Padel-Platzes, den du planst.",
"planner_label_environment": "Umgebung",
"planner_label_ownership": "Eigentumsmodell",
"planner_section_court_config": "Platzkonfiguration",
"planner_section_space_req": "Platzbedarf",
"planner_step2_title": "Preise & Auslastung",
"planner_step2_sub": "Lege Deine Platztarife, Betriebszeiten und Nebeneinnahmen fest.",
"planner_section_pricing": "Preise",
"planner_hint_per_court": "Pro Platz und Stunde",
"planner_section_util": "Auslastung & Betrieb",
"planner_step3_title": "Investition & Baukosten",
"planner_step3_sub": "Konfiguriere Baukosten, Glas- und Beleuchtungsoptionen sowie Dein Budgetziel.",
"planner_section_capex": "Bau & CAPEX",
"planner_hint_adjust": "Nach Szenario anpassen",
"planner_step4_title": "Betrieb & Finanzierung",
"planner_step4_sub": "Monatliche Betriebskosten, Kreditkonditionen und Exit-Annahmen.",
"planner_section_opex": "Monatliche Betriebskosten",
"planner_section_financing": "Finanzierung",
"planner_section_exit": "Exit-Annahmen",
"planner_chart_capex": "CAPEX-Aufschlüsselung",
"planner_chart_cf": "Monatlicher Netto-Cashflow (60 Monate)",
"planner_chart_cum": "Kumulierter Cashflow",
"planner_section_annual": "Jahresübersicht",
"planner_chart_rev_ramp": "Monatlicher Umsatzaufbau (Anlaufphase)",
"planner_chart_pl": "Stabilisierte monatliche GuV",
"planner_section_revenue": "Einnahmequellen (stabilisierter Monat)",
"planner_section_opex_breakdown": "Monatliche OPEX-Aufschlüsselung",
"planner_section_seasonality": "Outdoor-Saisonalität",
"planner_chart_exit_waterfall": "Exit-Bewertungs-Wasserfall",
"planner_chart_dscr": "DSCR nach Jahr",
"planner_section_util_sensitivity": "Auslastungs-Sensitivität",
"planner_section_price_sensitivity": "Preis-Sensitivität (bei Ziel-Auslastung)",
"planner_export_f1": "Zusammenfassung",
"planner_export_f2": "CAPEX-Aufschlüsselung",
"planner_export_f3": "5-Jahres GuV-Projektion",
"planner_export_f4": "12-Monats-Cashflow",
"planner_export_f5": "Finanzierungsstruktur",
"planner_export_f6": "Kennzahlen (IRR, MOIC, DSCR)",
"planner_export_f7": "Sensitivitätsanalyse",
"planner_export_f8": "Englisch oder Deutsch",
"planner_ewl_intro": "Wir bereiten den Start unseres professionellen Businessplan-PDF-Exports vor. Du stehst bereits auf der Warteliste und wirst benachrichtigt, sobald es verfügbar ist.",
"planner_ewl_included_h3": "Was enthalten ist",
"planner_ewl_f1": "Professioneller Businessplan (20+ Seiten als PDF)",
"planner_ewl_f2": "Finanzprojektionen mit Diagrammen",
"planner_ewl_f3": "Marktanalyse und Strategie",
"planner_ewl_f4": "Mehrsprachige Optionen",
"planner_ewl_notify_p": "Du erhältst bei unserem Launch eine E-Mail mit:",
"planner_ewl_email_item1": "Frühem Zugang mit Sonderpreis",
"planner_ewl_email_item2": "Launch-Rabatt",
"planner_ewl_email_item3": "Vorrangiger Generierungswarteschlange"
} }

View File

@@ -1093,5 +1093,58 @@
"markets_search_label": "Search", "markets_search_label": "Search",
"markets_country_label": "Country", "markets_country_label": "Country",
"article_detail_published_label": "Published", "article_detail_published_label": "Published",
"article_detail_research_label": "Padelnomics Research" "article_detail_research_label": "Padelnomics Research",
"planner_page_title": "Padel Court Financial Planner",
"planner_meta_desc": "Plan your padel court investment with our 60+ variable financial planner. Calculate ROI, CAPEX, cash flow, and more.",
"planner_step1_title": "Your Venue",
"planner_step1_sub": "Define the type of facility you're planning to build.",
"planner_label_environment": "Environment",
"planner_label_ownership": "Ownership Model",
"planner_section_court_config": "Court Configuration",
"planner_section_space_req": "Space Requirements",
"planner_step2_title": "Pricing & Utilization",
"planner_step2_sub": "Set your court rates, operating schedule, and ancillary revenue streams.",
"planner_section_pricing": "Pricing",
"planner_hint_per_court": "Per court per hour",
"planner_section_util": "Utilization & Operations",
"planner_step3_title": "Investment & Build Costs",
"planner_step3_sub": "Configure construction costs, glass and lighting options, and your budget target.",
"planner_section_capex": "Construction & CAPEX",
"planner_hint_adjust": "Adjust per scenario",
"planner_step4_title": "Operations & Financing",
"planner_step4_sub": "Monthly operating costs, loan terms, and exit assumptions.",
"planner_section_opex": "Monthly Operating Costs",
"planner_section_financing": "Financing",
"planner_section_exit": "Exit Assumptions",
"planner_chart_capex": "CAPEX Breakdown",
"planner_chart_cf": "Monthly Net Cash Flow (60 Months)",
"planner_chart_cum": "Cumulative Cash Flow",
"planner_section_annual": "Annual Summary",
"planner_chart_rev_ramp": "Monthly Revenue Build-Up (Ramp Period)",
"planner_chart_pl": "Stabilized Monthly P&L",
"planner_section_revenue": "Revenue Streams (Stabilized Month)",
"planner_section_opex_breakdown": "Monthly OpEx Breakdown",
"planner_section_seasonality": "Outdoor Seasonality",
"planner_chart_exit_waterfall": "Exit Valuation Waterfall",
"planner_chart_dscr": "DSCR by Year",
"planner_section_util_sensitivity": "Utilization Sensitivity",
"planner_section_price_sensitivity": "Pricing Sensitivity (at target utilization)",
"planner_export_f1": "Executive summary",
"planner_export_f2": "CAPEX breakdown",
"planner_export_f3": "5-year P&L projection",
"planner_export_f4": "12-month cash flow",
"planner_export_f5": "Financing structure",
"planner_export_f6": "Key metrics (IRR, MOIC, DSCR)",
"planner_export_f7": "Sensitivity analysis",
"planner_export_f8": "English or German",
"planner_ewl_intro": "We're preparing to launch our professional business plan PDF export feature. You're already on the waitlist and will be notified as soon as it's ready.",
"planner_ewl_included_h3": "What's Included",
"planner_ewl_f1": "Professional 20+ page business plan PDF",
"planner_ewl_f2": "Financial projections with charts",
"planner_ewl_f3": "Market analysis and strategy",
"planner_ewl_f4": "Multiple language options",
"planner_ewl_notify_p": "You'll receive an email when we launch with:",
"planner_ewl_email_item1": "Early access pricing",
"planner_ewl_email_item2": "Launch day discount",
"planner_ewl_email_item3": "Priority generation queue"
} }

View File

@@ -46,25 +46,9 @@
<div class="exp-price">&euro;99 <span>one-time</span></div> <div class="exp-price">&euro;99 <span>one-time</span></div>
<ul class="exp-features"> <ul class="exp-features">
{% if lang == 'de' %} {% for key in ['planner_export_f1','planner_export_f2','planner_export_f3','planner_export_f4','planner_export_f5','planner_export_f6','planner_export_f7','planner_export_f8'] %}
<li>Zusammenfassung</li> <li>{{ t[key] }}</li>
<li>CAPEX-Aufschlüsselung</li> {% endfor %}
<li>5-Jahres GuV-Projektion</li>
<li>12-Monats-Cashflow</li>
<li>Finanzierungsstruktur</li>
<li>Kennzahlen (IRR, MOIC, DSCR)</li>
<li>Sensitivitätsanalyse</li>
<li>Englisch oder Deutsch</li>
{% else %}
<li>Executive summary</li>
<li>CAPEX breakdown</li>
<li>5-year P&L projection</li>
<li>12-month cash flow</li>
<li>Financing structure</li>
<li>Key metrics (IRR, MOIC, DSCR)</li>
<li>Sensitivity analysis</li>
<li>English or German</li>
{% endif %}
</ul> </ul>
<div class="exp-form"> <div class="exp-form">

View File

@@ -7,89 +7,30 @@
<div class="card max-w-md mx-auto mt-8 text-center"> <div class="card max-w-md mx-auto mt-8 text-center">
<h1 class="text-2xl mb-4">{{ t.export_waitlist_title }}</h1> <h1 class="text-2xl mb-4">{{ t.export_waitlist_title }}</h1>
{% if lang == 'de' %} <p class="text-slate-dark mb-6">{{ t.planner_ewl_intro }}</p>
<p class="text-slate-dark mb-6">Wir bereiten den Start unseres professionellen Businessplan-PDF-Exports vor. Du stehst bereits auf der Warteliste und wirst benachrichtigt, sobald es verfügbar ist.</p>
<div class="bg-slate-50 border border-slate-200 rounded-lg p-4 mb-6 text-left"> <div class="bg-slate-50 border border-slate-200 rounded-lg p-4 mb-6 text-left">
<h3 class="font-semibold text-navy text-sm mb-2">Was enthalten ist</h3> <h3 class="font-semibold text-navy text-sm mb-2">{{ t.planner_ewl_included_h3 }}</h3>
<ul class="text-sm text-slate-dark space-y-1"> <ul class="text-sm text-slate-dark space-y-1">
{% for key in ['planner_ewl_f1','planner_ewl_f2','planner_ewl_f3','planner_ewl_f4'] %}
<li class="flex items-start gap-2"> <li class="flex items-start gap-2">
<svg class="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20"> <svg class="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path> <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg> </svg>
<span>Professioneller Businessplan (20+ Seiten als PDF)</span> <span>{{ t[key] }}</span>
</li>
<li class="flex items-start gap-2">
<svg class="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
<span>Finanzprojektionen mit Diagrammen</span>
</li>
<li class="flex items-start gap-2">
<svg class="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
<span>Marktanalyse und Strategie</span>
</li>
<li class="flex items-start gap-2">
<svg class="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
<span>Mehrsprachige Optionen</span>
</li> </li>
{% endfor %}
</ul> </ul>
</div> </div>
<div class="text-sm text-slate mb-6"> <div class="text-sm text-slate mb-6">
<p>Du erhältst bei unserem Launch eine E-Mail mit:</p> <p>{{ t.planner_ewl_notify_p }}</p>
<ul class="mt-2 text-slate-dark"> <ul class="mt-2 text-slate-dark">
<li>Frühem Zugang mit Sonderpreis</li> <li>{{ t.planner_ewl_email_item1 }}</li>
<li>Launch-Rabatt</li> <li>{{ t.planner_ewl_email_item2 }}</li>
<li>Vorrangiger Generierungswarteschlange</li> <li>{{ t.planner_ewl_email_item3 }}</li>
</ul> </ul>
</div> </div>
{% else %}
<p class="text-slate-dark mb-6">We're preparing to launch our professional business plan PDF export feature. You're already on the waitlist and will be notified as soon as it's ready.</p>
<div class="bg-slate-50 border border-slate-200 rounded-lg p-4 mb-6 text-left">
<h3 class="font-semibold text-navy text-sm mb-2">What's Included</h3>
<ul class="text-sm text-slate-dark space-y-1">
<li class="flex items-start gap-2">
<svg class="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
<span>Professional 20+ page business plan PDF</span>
</li>
<li class="flex items-start gap-2">
<svg class="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
<span>Financial projections with charts</span>
</li>
<li class="flex items-start gap-2">
<svg class="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
<span>Market analysis and strategy</span>
</li>
<li class="flex items-start gap-2">
<svg class="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
</svg>
<span>Multiple language options</span>
</li>
</ul>
</div>
<div class="text-sm text-slate mb-6">
<p>You'll receive an email when we launch with:</p>
<ul class="mt-2 text-slate-dark">
<li>• Early access pricing</li>
<li>• Launch day discount</li>
<li>• Priority generation queue</li>
</ul>
</div>
{% endif %}
<a href="{{ url_for('planner.index') }}" class="btn w-full">{{ t.export_waitlist_btn }}</a> <a href="{{ url_for('planner.index') }}" class="btn w-full">{{ t.export_waitlist_btn }}</a>
</div> </div>

View File

@@ -41,7 +41,7 @@
</table> </table>
<div class="chart-container mt-4"> <div class="chart-container mt-4">
<div class="chart-container__label">{% if lang == 'de' %}CAPEX-Aufschlüsselung{% else %}CAPEX Breakdown{% endif %}</div> <div class="chart-container__label">{{ t.planner_chart_capex }}</div>
<div class="chart-h-56 chart-container__canvas"> <div class="chart-h-56 chart-container__canvas">
<canvas id="chartCapex"></canvas> <canvas id="chartCapex"></canvas>
</div> </div>

View File

@@ -25,19 +25,19 @@
</div> </div>
<div class="chart-container mb-4"> <div class="chart-container mb-4">
<div class="chart-container__label">{% if lang == 'de' %}Monatlicher Netto-Cashflow (60 Monate){% else %}Monthly Net Cash Flow (60 Months){% endif %}</div> <div class="chart-container__label">{{ t.planner_chart_cf }}</div>
<div class="chart-h-56 chart-container__canvas"><canvas id="chartCF"></canvas></div> <div class="chart-h-56 chart-container__canvas"><canvas id="chartCF"></canvas></div>
</div> </div>
<script type="application/json" id="chartCF-data">{{ d.cf_chart | tojson }}</script> <script type="application/json" id="chartCF-data">{{ d.cf_chart | tojson }}</script>
<div class="chart-container mb-4"> <div class="chart-container mb-4">
<div class="chart-container__label">{% if lang == 'de' %}Kumulierter Cashflow{% else %}Cumulative Cash Flow{% endif %}</div> <div class="chart-container__label">{{ t.planner_chart_cum }}</div>
<div class="chart-h-48 chart-container__canvas"><canvas id="chartCum"></canvas></div> <div class="chart-h-48 chart-container__canvas"><canvas id="chartCum"></canvas></div>
</div> </div>
<script type="application/json" id="chartCum-data">{{ d.cum_chart | tojson }}</script> <script type="application/json" id="chartCum-data">{{ d.cum_chart | tojson }}</script>
<div class="mb-section"> <div class="mb-section">
<div class="section-header"><h3>{% if lang == 'de' %}Jahresübersicht{% else %}Annual Summary{% endif %}</h3></div> <div class="section-header"><h3>{{ t.planner_section_annual }}</h3></div>
<table class="data-table"> <table class="data-table">
<thead> <thead>
<tr> <tr>

View File

@@ -25,11 +25,11 @@
<div class="grid-2 mb-4"> <div class="grid-2 mb-4">
<div class="chart-container"> <div class="chart-container">
<div class="chart-container__label">{% if lang == 'de' %}Monatlicher Umsatzaufbau (Anlaufphase){% else %}Monthly Revenue Build-Up (Ramp Period){% endif %}</div> <div class="chart-container__label">{{ t.planner_chart_rev_ramp }}</div>
<div class="chart-h-48 chart-container__canvas"><canvas id="chartRevRamp"></canvas></div> <div class="chart-h-48 chart-container__canvas"><canvas id="chartRevRamp"></canvas></div>
</div> </div>
<div class="chart-container"> <div class="chart-container">
<div class="chart-container__label">{% if lang == 'de' %}Stabilisierte monatliche GuV{% else %}Stabilized Monthly P&amp;L{% endif %}</div> <div class="chart-container__label">{{ t.planner_chart_pl }}</div>
<div class="chart-h-48 chart-container__canvas"><canvas id="chartPL"></canvas></div> <div class="chart-h-48 chart-container__canvas"><canvas id="chartPL"></canvas></div>
</div> </div>
</div> </div>
@@ -37,7 +37,7 @@
<script type="application/json" id="chartPL-data">{{ d.pl_chart | tojson }}</script> <script type="application/json" id="chartPL-data">{{ d.pl_chart | tojson }}</script>
<div class="mb-section"> <div class="mb-section">
<div class="section-header"><h3>{% if lang == 'de' %}Einnahmequellen (stabilisierter Monat){% else %}Revenue Streams (Stabilized Month){% endif %}</h3></div> <div class="section-header"><h3>{{ t.planner_section_revenue }}</h3></div>
{% set streams = [ {% set streams = [
(t.stream_court_rental, d.courtRevMonth - d.feeDeduction), (t.stream_court_rental, d.courtRevMonth - d.feeDeduction),
(t.stream_equipment, d.racketRev + d.ballMargin), (t.stream_equipment, d.racketRev + d.ballMargin),
@@ -68,7 +68,7 @@
</div> </div>
<div class="mb-section"> <div class="mb-section">
<div class="section-header"><h3>{% if lang == 'de' %}Monatliche OPEX-Aufschlüsselung{% else %}Monthly OpEx Breakdown{% endif %}</h3></div> <div class="section-header"><h3>{{ t.planner_section_opex_breakdown }}</h3></div>
<table class="data-table"> <table class="data-table">
<thead><tr><th>{{ t.th_item }}</th><th class="right">{{ t.th_monthly }}</th></tr></thead> <thead><tr><th>{{ t.th_item }}</th><th class="right">{{ t.th_monthly }}</th></tr></thead>
<tbody> <tbody>
@@ -88,7 +88,7 @@
{% if s.venue == 'outdoor' %} {% if s.venue == 'outdoor' %}
<div class="mb-section season-section visible"> <div class="mb-section season-section visible">
<div class="section-header"><h3>{% if lang == 'de' %}Outdoor-Saisonalität{% else %}Outdoor Seasonality{% endif %}</h3></div> <div class="section-header"><h3>{{ t.planner_section_seasonality }}</h3></div>
<div class="chart-container"><div class="chart-h-40 chart-container__canvas"><canvas id="chartSeason"></canvas></div></div> <div class="chart-container"><div class="chart-h-40 chart-container__canvas"><canvas id="chartSeason"></canvas></div></div>
</div> </div>
<script type="application/json" id="chartSeason-data">{{ d.season_chart | tojson }}</script> <script type="application/json" id="chartSeason-data">{{ d.season_chart | tojson }}</script>

View File

@@ -23,7 +23,7 @@
<div class="grid-2 mb-4"> <div class="grid-2 mb-4">
<div class="chart-container"> <div class="chart-container">
<div class="chart-container__label" style="font-size:10px">{% if lang == 'de' %}Exit-Bewertungs-Wasserfall{% else %}Exit Valuation Waterfall{% endif %}</div> <div class="chart-container__label" style="font-size:10px">{{ t.planner_chart_exit_waterfall }}</div>
<div id="exitWaterfall" style="margin-top:10px"> <div id="exitWaterfall" style="margin-top:10px">
{% set wf_rows = [ {% set wf_rows = [
(t.wf_stab_ebitda, d.stabEbitda | int | fmt_currency, 'c-head'), (t.wf_stab_ebitda, d.stabEbitda | int | fmt_currency, 'c-head'),
@@ -45,14 +45,14 @@
</div> </div>
</div> </div>
<div class="chart-container"> <div class="chart-container">
<div class="chart-container__label">{% if lang == 'de' %}DSCR nach Jahr{% else %}DSCR by Year{% endif %}</div> <div class="chart-container__label">{{ t.planner_chart_dscr }}</div>
<div class="chart-h-44 chart-container__canvas"><canvas id="chartDSCR"></canvas></div> <div class="chart-h-44 chart-container__canvas"><canvas id="chartDSCR"></canvas></div>
</div> </div>
</div> </div>
<script type="application/json" id="chartDSCR-data">{{ d.dscr_chart | tojson }}</script> <script type="application/json" id="chartDSCR-data">{{ d.dscr_chart | tojson }}</script>
<div class="mb-section"> <div class="mb-section">
<div class="section-header"><h3>{% if lang == 'de' %}Auslastungs-Sensitivität{% else %}Utilization Sensitivity{% endif %}</h3></div> <div class="section-header"><h3>{{ t.planner_section_util_sensitivity }}</h3></div>
<table class="data-table"> <table class="data-table">
<thead> <thead>
<tr> <tr>
@@ -78,7 +78,7 @@
</div> </div>
<div class="mb-section"> <div class="mb-section">
<div class="section-header"><h3>{% if lang == 'de' %}Preis-Sensitivität (bei Ziel-Auslastung){% else %}Pricing Sensitivity (at target utilization){% endif %}</h3></div> <div class="section-header"><h3>{{ t.planner_section_price_sensitivity }}</h3></div>
<table class="data-table"> <table class="data-table">
<thead> <thead>
<tr> <tr>

View File

@@ -1,16 +1,10 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}{% if lang == 'de' %}Padel-Platz Finanzrechner - {{ config.APP_NAME }}{% else %}Padel Court Financial Planner - {{ config.APP_NAME }}{% endif %}{% endblock %} {% block title %}{{ t.planner_page_title }} - {{ config.APP_NAME }}{% endblock %}
{% block head %} {% block head %}
{% if lang == 'de' %} <meta name="description" content="{{ t.planner_meta_desc }}">
<meta name="description" content="Plane deine Padel-Platz-Investition mit unserem Finanzrechner mit 60+ Variablen. CAPEX, Cashflow und ROI berechnen."> <meta property="og:title" content="{{ t.planner_page_title }} - {{ config.APP_NAME }}">
<meta property="og:title" content="Padel-Platz Finanzrechner - {{ config.APP_NAME }}"> <meta property="og:description" content="{{ t.planner_meta_desc }}">
<meta property="og:description" content="Plane deine Padel-Platz-Investition mit unserem Finanzrechner mit 60+ Variablen. CAPEX, Cashflow und ROI berechnen.">
{% else %}
<meta name="description" content="Plan your padel court investment with our 60+ variable financial planner. Calculate ROI, CAPEX, cash flow, and more.">
<meta property="og:title" content="Padel Court Financial Planner - {{ config.APP_NAME }}">
<meta property="og:description" content="Plan your padel court investment with our 60+ variable financial planner. Calculate ROI, CAPEX, cash flow, and more.">
{% endif %}
<meta property="og:type" content="website"> <meta property="og:type" content="website">
<meta property="og:image" content="{{ url_for('static', filename='images/planner-screenshot.png', _external=True) }}"> <meta property="og:image" content="{{ url_for('static', filename='images/planner-screenshot.png', _external=True) }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/planner.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/planner.css') }}">
@@ -45,7 +39,7 @@
{% block content %} {% block content %}
<div class="planner-app"> <div class="planner-app">
<header class="planner-header"> <header class="planner-header">
<h1>{% if lang == 'de' %}Padel-Platz Finanzrechner{% else %}Padel Court Financial Planner{% endif %}</h1> <h1>{{ t.planner_page_title }}</h1>
<span id="headerTag" class="planner-summary">{{ s.venue == 'indoor' and t.label_indoor or t.label_outdoor }} &middot; {{ s.own == 'buy' and t.label_build_buy or t.label_rent }} &middot; {{ d.totalCourts }} {{ t.label_courts }} &middot; {{ d.capex | fmt_k }}</span> <span id="headerTag" class="planner-summary">{{ s.venue == 'indoor' and t.label_indoor or t.label_outdoor }} &middot; {{ s.own == 'buy' and t.label_build_buy or t.label_rent }} &middot; {{ d.totalCourts }} {{ t.label_courts }} &middot; {{ d.capex | fmt_k }}</span>
{% if user %} {% if user %}
@@ -109,16 +103,11 @@
<!-- Step 1: Venue --> <!-- Step 1: Venue -->
<div class="wizard-step active" data-wiz="1"> <div class="wizard-step active" data-wiz="1">
{% if lang == 'de' %} <h2 class="wizard-step__title">{{ t.planner_step1_title }}</h2>
<h2 class="wizard-step__title">Dein Padel-Platz</h2> <p class="wizard-step__sub">{{ t.planner_step1_sub }}</p>
<p class="wizard-step__sub">Definiere den Typ des Padel-Platzes, den du planst.</p>
{% else %}
<h2 class="wizard-step__title">Your Venue</h2>
<p class="wizard-step__sub">Define the type of facility you're planning to build.</p>
{% endif %}
<div class="mb-section"> <div class="mb-section">
<label class="slider-group__label">{% if lang == 'de' %}Umgebung{% else %}Environment{% endif %}</label> <label class="slider-group__label">{{ t.planner_label_environment }}</label>
<div class="toggle-group"> <div class="toggle-group">
<button type="button" class="toggle-btn {{ 'toggle-btn--active' if s.venue == 'indoor' }}" <button type="button" class="toggle-btn {{ 'toggle-btn--active' if s.venue == 'indoor' }}"
data-toggle="venue" data-val="indoor" data-toggle="venue" data-val="indoor"
@@ -131,7 +120,7 @@
hx-target="#tab-content" hx-include="#planner-form" hx-target="#tab-content" hx-include="#planner-form"
onclick="setToggle(this,'venue','outdoor')">{{ t.toggle_outdoor }}</button> onclick="setToggle(this,'venue','outdoor')">{{ t.toggle_outdoor }}</button>
</div> </div>
<label class="slider-group__label">{% if lang == 'de' %}Eigentumsmodell{% else %}Ownership Model{% endif %}</label> <label class="slider-group__label">{{ t.planner_label_ownership }}</label>
<div class="toggle-group"> <div class="toggle-group">
<button type="button" class="toggle-btn {{ 'toggle-btn--active' if s.own == 'rent' }}" <button type="button" class="toggle-btn {{ 'toggle-btn--active' if s.own == 'rent' }}"
data-toggle="own" data-val="rent" data-toggle="own" data-val="rent"
@@ -163,19 +152,11 @@
</div> </div>
<div class="mb-section"> <div class="mb-section">
{% if lang == 'de' %} <div class="section-header"><h3>{{ t.planner_section_court_config }}</h3></div>
<div class="section-header"><h3>Platzkonfiguration</h3></div>
{% else %}
<div class="section-header"><h3>Court Configuration</h3></div>
{% endif %}
{{ slider('dblCourts', t.sl_dbl_courts, 0, 30, 1, s.dblCourts, t.tip_dbl_courts) }} {{ slider('dblCourts', t.sl_dbl_courts, 0, 30, 1, s.dblCourts, t.tip_dbl_courts) }}
{{ slider('sglCourts', t.sl_sgl_courts, 0, 30, 1, s.sglCourts, t.tip_sgl_courts) }} {{ slider('sglCourts', t.sl_sgl_courts, 0, 30, 1, s.sglCourts, t.tip_sgl_courts) }}
{% if lang == 'de' %} <div class="section-header" style="margin-top:1rem"><h3>{{ t.planner_section_space_req }}</h3></div>
<div class="section-header" style="margin-top:1rem"><h3>Platzbedarf</h3></div>
{% else %}
<div class="section-header" style="margin-top:1rem"><h3>Space Requirements</h3></div>
{% endif %}
<div data-show-venue="indoor"> <div data-show-venue="indoor">
{{ slider('sqmPerDblHall', t.sl_sqm_dbl_hall, 200, 600, 10, s.sqmPerDblHall, t.tip_sqm_dbl_hall) }} {{ slider('sqmPerDblHall', t.sl_sqm_dbl_hall, 200, 600, 10, s.sqmPerDblHall, t.tip_sqm_dbl_hall) }}
{{ slider('sqmPerSglHall', t.sl_sqm_sgl_hall, 120, 400, 10, s.sqmPerSglHall, t.tip_sqm_sgl_hall) }} {{ slider('sqmPerSglHall', t.sl_sqm_sgl_hall, 120, 400, 10, s.sqmPerSglHall, t.tip_sqm_sgl_hall) }}
@@ -190,20 +171,11 @@
<!-- Step 2: Pricing & Utilization --> <!-- Step 2: Pricing & Utilization -->
<div class="wizard-step" data-wiz="2"> <div class="wizard-step" data-wiz="2">
{% if lang == 'de' %} <h2 class="wizard-step__title">{{ t.planner_step2_title }}</h2>
<h2 class="wizard-step__title">Preise &amp; Auslastung</h2> <p class="wizard-step__sub">{{ t.planner_step2_sub }}</p>
<p class="wizard-step__sub">Lege Deine Platztarife, Betriebszeiten und Nebeneinnahmen fest.</p>
{% else %}
<h2 class="wizard-step__title">Pricing &amp; Utilization</h2>
<p class="wizard-step__sub">Set your court rates, operating schedule, and ancillary revenue streams.</p>
{% endif %}
<div class="mb-section"> <div class="mb-section">
{% if lang == 'de' %} <div class="section-header"><h3>{{ t.planner_section_pricing }}</h3><span class="hint">{{ t.planner_hint_per_court }}</span></div>
<div class="section-header"><h3>Preise</h3><span class="hint">Pro Platz und Stunde</span></div>
{% else %}
<div class="section-header"><h3>Pricing</h3><span class="hint">Per court per hour</span></div>
{% endif %}
{{ slider('ratePeak', t.sl_rate_peak, 0, 150, 1, s.ratePeak, t.tip_rate_peak) }} {{ slider('ratePeak', t.sl_rate_peak, 0, 150, 1, s.ratePeak, t.tip_rate_peak) }}
{{ slider('rateOffPeak', t.sl_rate_offpeak, 0, 150, 1, s.rateOffPeak, t.tip_rate_offpeak) }} {{ slider('rateOffPeak', t.sl_rate_offpeak, 0, 150, 1, s.rateOffPeak, t.tip_rate_offpeak) }}
{{ slider('rateSingle', t.sl_rate_single, 0, 150, 1, s.rateSingle, t.tip_rate_single) }} {{ slider('rateSingle', t.sl_rate_single, 0, 150, 1, s.rateSingle, t.tip_rate_single) }}
@@ -212,11 +184,7 @@
</div> </div>
<div class="mb-section"> <div class="mb-section">
{% if lang == 'de' %} <div class="section-header"><h3>{{ t.planner_section_util }}</h3></div>
<div class="section-header"><h3>Auslastung &amp; Betrieb</h3></div>
{% else %}
<div class="section-header"><h3>Utilization &amp; Operations</h3></div>
{% endif %}
{{ slider('utilTarget', t.sl_util_target, 0, 100, 1, s.utilTarget, t.tip_util_target) }} {{ slider('utilTarget', t.sl_util_target, 0, 100, 1, s.utilTarget, t.tip_util_target) }}
{{ slider('hoursPerDay', t.sl_hours_per_day, 0, 24, 1, s.hoursPerDay, t.tip_hours_per_day) }} {{ slider('hoursPerDay', t.sl_hours_per_day, 0, 24, 1, s.hoursPerDay, t.tip_hours_per_day) }}
{{ slider('daysPerMonthIndoor', t.sl_days_indoor, 0, 31, 1, s.daysPerMonthIndoor, t.tip_days_indoor) }} {{ slider('daysPerMonthIndoor', t.sl_days_indoor, 0, 31, 1, s.daysPerMonthIndoor, t.tip_days_indoor) }}
@@ -231,20 +199,11 @@
<!-- Step 3: Investment & Build Costs --> <!-- Step 3: Investment & Build Costs -->
<div class="wizard-step" data-wiz="3"> <div class="wizard-step" data-wiz="3">
{% if lang == 'de' %} <h2 class="wizard-step__title">{{ t.planner_step3_title }}</h2>
<h2 class="wizard-step__title">Investition &amp; Baukosten</h2> <p class="wizard-step__sub">{{ t.planner_step3_sub }}</p>
<p class="wizard-step__sub">Konfiguriere Baukosten, Glas- und Beleuchtungsoptionen sowie Dein Budgetziel.</p>
{% else %}
<h2 class="wizard-step__title">Investment &amp; Build Costs</h2>
<p class="wizard-step__sub">Configure construction costs, glass and lighting options, and your budget target.</p>
{% endif %}
<div class="mb-section"> <div class="mb-section">
{% if lang == 'de' %} <div class="section-header"><h3>{{ t.planner_section_capex }}</h3><span class="hint">{{ t.planner_hint_adjust }}</span></div>
<div class="section-header"><h3>Bau &amp; CAPEX</h3><span class="hint">Nach Szenario anpassen</span></div>
{% else %}
<div class="section-header"><h3>Construction &amp; CAPEX</h3><span class="hint">Adjust per scenario</span></div>
{% endif %}
<div class="pill-group"> <div class="pill-group">
<label><span class="slider-group__label">{{ t.pill_glass_type }}</span><span class="ti">i<span class="tp">{{ t.tip_glass_type }}</span></span></label> <label><span class="slider-group__label">{{ t.pill_glass_type }}</span><span class="ti">i<span class="tp">{{ t.tip_glass_type }}</span></span></label>
@@ -303,17 +262,11 @@
<!-- Step 4: Operations & Financing --> <!-- Step 4: Operations & Financing -->
<div class="wizard-step" data-wiz="4"> <div class="wizard-step" data-wiz="4">
{% if lang == 'de' %} <h2 class="wizard-step__title">{{ t.planner_step4_title }}</h2>
<h2 class="wizard-step__title">Betrieb &amp; Finanzierung</h2> <p class="wizard-step__sub">{{ t.planner_step4_sub }}</p>
<p class="wizard-step__sub">Monatliche Betriebskosten, Kreditkonditionen und Exit-Annahmen.</p>
{% else %}
<h2 class="wizard-step__title">Operations &amp; Financing</h2>
<p class="wizard-step__sub">Monthly operating costs, loan terms, and exit assumptions.</p>
{% endif %}
<div class="mb-section"> <div class="mb-section">
{% if lang == 'de' %}<div class="section-header"><h3>Monatliche Betriebskosten</h3></div> <div class="section-header"><h3>{{ t.planner_section_opex }}</h3></div>
{% else %}<div class="section-header"><h3>Monthly Operating Costs</h3></div>{% endif %}
<div data-show-opex="indoor-rent">{{ slider('rentSqm', t.sl_rent_sqm, 0, 25, 0.5, s.rentSqm, t.tip_rent_sqm) }}</div> <div data-show-opex="indoor-rent">{{ slider('rentSqm', t.sl_rent_sqm, 0, 25, 0.5, s.rentSqm, t.tip_rent_sqm) }}</div>
<div data-show-opex="outdoor-rent">{{ slider('outdoorRent', t.sl_outdoor_rent, 0, 5000, 50, s.outdoorRent, t.tip_outdoor_rent) }}</div> <div data-show-opex="outdoor-rent">{{ slider('outdoorRent', t.sl_outdoor_rent, 0, 5000, 50, s.outdoorRent, t.tip_outdoor_rent) }}</div>
@@ -336,8 +289,7 @@
</div> </div>
<div class="mb-section"> <div class="mb-section">
{% if lang == 'de' %}<div class="section-header"><h3>Finanzierung</h3></div> <div class="section-header"><h3>{{ t.planner_section_financing }}</h3></div>
{% else %}<div class="section-header"><h3>Financing</h3></div>{% endif %}
{{ slider('loanPct', t.sl_loan_pct, 0, 100, 1, s.loanPct, t.tip_loan_pct) }} {{ slider('loanPct', t.sl_loan_pct, 0, 100, 1, s.loanPct, t.tip_loan_pct) }}
{{ slider('interestRate', t.sl_interest_rate, 0, 15, 0.1, s.interestRate, t.tip_interest_rate) }} {{ slider('interestRate', t.sl_interest_rate, 0, 15, 0.1, s.interestRate, t.tip_interest_rate) }}
{{ slider('loanTerm', t.sl_loan_term, 0, 30, 1, s.loanTerm, t.tip_loan_term) }} {{ slider('loanTerm', t.sl_loan_term, 0, 30, 1, s.loanTerm, t.tip_loan_term) }}
@@ -345,8 +297,7 @@
</div> </div>
<div class="mb-section"> <div class="mb-section">
{% if lang == 'de' %}<div class="section-header"><h3>Exit-Annahmen</h3></div> <div class="section-header"><h3>{{ t.planner_section_exit }}</h3></div>
{% else %}<div class="section-header"><h3>Exit Assumptions</h3></div>{% endif %}
{{ slider('holdYears', t.sl_hold_years, 1, 20, 1, s.holdYears, t.tip_hold_years) }} {{ slider('holdYears', t.sl_hold_years, 1, 20, 1, s.holdYears, t.tip_hold_years) }}
{{ slider('exitMultiple', t.sl_exit_multiple, 0, 20, 0.5, s.exitMultiple, t.tip_exit_multiple) }} {{ slider('exitMultiple', t.sl_exit_multiple, 0, 20, 0.5, s.exitMultiple, t.tip_exit_multiple) }}
{{ slider('annualRevGrowth', t.sl_annual_rev_growth, 0, 15, 0.5, s.annualRevGrowth, t.tip_annual_rev_growth) }} {{ slider('annualRevGrowth', t.sl_annual_rev_growth, 0, 15, 0.5, s.annualRevGrowth, t.tip_annual_rev_growth) }}