From b108a53ef3d2895f3d3d033d5aba1aba5d230a5f Mon Sep 17 00:00:00 2001 From: Deeman Date: Thu, 19 Feb 2026 19:16:23 +0100 Subject: [PATCH] updates --- .copier-answers.yml | 2 +- CHANGELOG.md | 32 + PadelDirectory.md | 575 ------------------ padelnomics/.env.example | 4 +- .../admin/templates/admin/article_form.html | 7 +- .../admin/templates/admin/articles.html | 7 +- .../admin/templates/admin/feedback.html | 7 +- .../admin/templates/admin/generate_form.html | 7 +- .../admin/templates/admin/index.html | 48 +- .../admin/templates/admin/lead_detail.html | 9 +- .../admin/templates/admin/lead_form.html | 9 +- .../admin/templates/admin/leads.html | 7 +- .../admin/templates/admin/login.html | 29 - .../admin/templates/admin/scenario_form.html | 7 +- .../templates/admin/scenario_preview.html | 7 +- .../admin/templates/admin/scenarios.html | 7 +- .../admin/templates/admin/suppliers.html | 7 +- .../admin/templates/admin/tasks.html | 7 +- .../admin/templates/admin/template_data.html | 7 +- .../admin/templates/admin/template_form.html | 7 +- .../admin/templates/admin/templates.html | 7 +- .../admin/templates/admin/user_detail.html | 11 +- .../admin/templates/admin/users.html | 7 +- padelnomics/src/padelnomics/app.py | 34 +- padelnomics/src/padelnomics/auth/routes.py | 80 ++- .../billing/templates/pricing.html | 8 +- .../content/templates/article_detail.html | 23 +- .../content/templates/markets.html | 1 - padelnomics/src/padelnomics/core.py | 3 + .../src/padelnomics/dashboard/routes.py | 8 + .../src/padelnomics/directory/routes.py | 6 +- .../directory/templates/directory.html | 2 + .../directory/templates/supplier_detail.html | 24 + padelnomics/src/padelnomics/leads/routes.py | 4 +- .../templates/partials/quote_step_9.html | 5 +- .../versions/0001_rename_ls_to_paddle.py | 11 +- .../versions/0004_create_suppliers.py | 34 -- .../planner/templates/planner.html | 4 +- padelnomics/src/padelnomics/public/routes.py | 62 +- .../padelnomics/public/templates/about.html | 8 +- .../public/templates/features.html | 3 + .../padelnomics/public/templates/landing.html | 368 ++++++++--- .../padelnomics/public/templates/privacy.html | 4 + .../public/templates/suppliers.html | 378 +++++++++--- .../padelnomics/public/templates/terms.html | 4 + .../src/padelnomics/scripts/seed_dev_data.py | 21 +- .../src/padelnomics/static/css/input.css | 11 +- .../src/padelnomics/static/css/planner.css | 40 +- .../suppliers/partials/dashboard_boosts.html | 4 +- .../suppliers/partials/dashboard_leads.html | 30 +- .../partials/lead_card_unlocked.html | 107 +++- .../src/padelnomics/templates/base.html | 80 ++- padelnomics/tests/test_billing_helpers.py | 26 +- padelnomics/tests/test_billing_routes.py | 6 +- padelnomics/tests/test_billing_webhooks.py | 8 +- padelnomics/tests/test_content.py | 18 +- padelnomics/tests/test_phase0.py | 9 +- 57 files changed, 1203 insertions(+), 1048 deletions(-) delete mode 100644 PadelDirectory.md delete mode 100644 padelnomics/src/padelnomics/admin/templates/admin/login.html diff --git a/.copier-answers.yml b/.copier-answers.yml index 32fe71f..fc9a1d2 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Changes here will be overwritten by Copier; NEVER EDIT MANUALLY -_commit: v0.2.0 +_commit: 29ac25b _src_path: /home/Deeman/Projects/quart_saas_boilerplate author_email: '' author_name: '' diff --git a/CHANGELOG.md b/CHANGELOG.md index e757320..0752e54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,38 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +### Added +- SEO defaults in `base.html`: canonical, og:url, og:type, og:image (logo fallback), og:title, og:description, twitter:card — every page gets these automatically, child templates override as needed +- `robots.txt` route: disallows `/admin/`, `/auth/`, `/dashboard/`, `/billing/`, `/directory/results`; includes Sitemap reference +- Meta descriptions and OG tags on all public pages: about, terms, privacy, pricing, features, suppliers, directory, supplier detail +- `og:image` on landing and features pages pointing to planner screenshot +- JSON-LD Organization schema on homepage and supplier detail pages +- JSON-LD FAQPage schema on homepage (5 FAQ entries) +- JSON-LD Article schema on article detail pages +- Sitemap supplier slugs: all supplier detail pages now indexed +- Sitemap `` on all entries (static pages: today, articles: `COALESCE(updated_at, published_at)`, suppliers: `created_at`) +- `rel="preconnect"` for Google Fonts to reduce font-load latency +- `X-Robots-Tag: noindex` header on `/directory/results` HTMX partial + +### Fixed +- Render-blocking Paddle.js: added `defer` attribute and wrapped `Paddle.Initialize` in `DOMContentLoaded` listener +- Render-blocking Chart.js on planner page: added `defer` attribute +- Broken `og:image` on planner page (`og-planner.png` → `planner-screenshot.png`) +- Homepage meta description trimmed to under 155 characters +- Duplicate `og:url` and `canonical` tags removed from landing, markets, and article detail pages + +### Changed +- Rewrote supplier page hero: pain-first headline ("Stop Chasing Cold Leads"), differentiator copy, micro-proof under CTA +- Added "Problem With Finding Padel Clients Today" section with trade show / Google Ads / cold outreach pain points +- Tightened "How It Works" step titles: "Claim Your Listing", "Browse Pre-Qualified Leads", "Win Projects Faster" +- Added Basic tier (€39/mo / €29/mo yearly) to public pricing section on suppliers page +- Pricing section now shows 3-column grid (Basic / Growth / Pro) with CSS-only billing period toggle (monthly / yearly, no JS) +- Added "How We Compare" table: Padelnomics vs trade show / Google Ads / cold directory +- Upgraded social proof section: two testimonial cards with decorative quote mark, stat bar in subtitle +- Updated supplier FAQ: three tiers with correct prices (€39/€199/€499), two new entries (what makes leads different, pricing vs alternatives), removed stale €149/€399 figures +- Strengthened final CTA: "Your Next Client Is Already Building a Business Plan" +- Fixed stale prices in landing page FAQ: Basic €39/mo, Growth €199/mo, Pro €499/mo (was €149/€399) + ### Changed - Redesigned directory cards: image-first 16:9 layout with cover photos, frosted category badge, CSS court/grid placeholders, and logo avatar straddling the media/body border - 4-tier visual ladder: Free (62% opacity, grey placeholder, unverified chip) → Basic (full opacity, green placeholder, verified chip, description, "View Listing →") → Growth (green placeholder, Growth chip + stats, "Request Quote →") → Pro (green 2.5px top border, CSS court media, full stats, green hover glow) diff --git a/PadelDirectory.md b/PadelDirectory.md deleted file mode 100644 index 7219125..0000000 --- a/PadelDirectory.md +++ /dev/null @@ -1,575 +0,0 @@ -# Global Padel Court Suppliers & Builders Directory - -**200+ companies across 30+ countries** — court manufacturers, hall builders, turf suppliers, lighting specialists, booking software, and consultants. The padel court market reached ~$163M in 2023 and is projected to hit $592M by 2031. This directory is organized by region, with Germany as the priority market. - ---- - -## 1. GERMANY - -Germany's padel market is growing 60%+ annually, with 100+ facilities now operating. A wave of domestic manufacturers has emerged since 2020. - -### 1.1 German-Headquartered Court Manufacturers - -| Company | City/Region | Website | Contact | Description | -|---------|------------|---------|---------|-------------| -| **artec Sportgeräte GmbH** | Melle, Lower Saxony | artec-sportgeraete.de | Via contact form | 30+ years sports equipment. 12mm laminated safety glass, DIN-standard statics, customizable colors. Indoor & outdoor. | -| **PADELWERK Court GmbH** | Dortmund | padelwerk.de | +49 172 54 60 150 | "Germany's first padel court manufacturer" (est. 2021). All components made in Germany. Basic and luxury versions, LED lighting, roofing, financing consulting. | -| **Vindico Sport GmbH** | Germany | vindico-sport.de | Via website | Serie B and Pano models. Carbon-steel S235JRH, 10–12mm tempered glass, 9-stage corrosion coating, WPT-standard entrances, stainless steel A4 connectors. | -| **Kübler Sport GmbH** | Backnang, Baden-Württemberg (71522) | kuebler-sport.de | info@kuebler-sport.de | Major sports supplier. CLASSIC and PANORAMA courts with steel structure, tempered glass, wire mesh, artificial turf, 8 LED elements. In-house installation teams. | -| **Padello GmbH** | Troisdorf, NRW | padello.de | Via contact form | Full-service builder with own metalworking shop. Steel construction up to 5mm strength adapted to regional wind loads. DIN-compliant statics, DEKRA-certified noise assessment. | -| **LOB Sport (BECO Bermüller)** | Nuremberg, Bavaria (90451) | lobsport.de / beco-bermueller.de | +49 911 64200-0 | 40+ years in tennis equipment, now padel. "Edge" and "Infinity" models. Foundation-free option for converting sand courts. Part of BECO Bermüller group. | -| **Brako Padel GmbH** | Berlin | brakopadel.com | Via contact form | Padel specialist since 2013. 15-year corrosion warranty. Indoor, outdoor, panoramic, and portable courts. No-foundation portable options. | -| **Padel Concept** | Germany (DACH) | padelconcept.de | Via website | Production in Baltic states, serves DACH/Scandinavia/BeNeLux. Own assembly teams. Innovative mobile floor plate solution. Full statics and noise protection reports. | -| **Padelsportanlagenbau** | Germany | padelsportanlagenbau.de | Via contact form | Manufacturer & turnkey builder, active in 18+ countries. | - -### 1.2 Turnkey Solution Providers & Consultants (Germany) - -| Company | City/Region | Website | Contact | Description | -|---------|------------|---------|---------|-------------| -| **The Court Company** | Cologne, NRW | courtcompany.de | +49 2237 6034685 | "Germany's most experienced padel construction expert." 40+ courts in 2021. Licensed partner of AFP Courts, RedSport, adidas courts. Full service plus leasing and mobile courts. | -| **Real Padel GmbH** | Schönebeck, Saxony-Anhalt (39218) | realpadel.de / padel-court.de | Schornsteinfeger Str. 3, 39218 Schönebeck | Premium courts and full-service club consulting. Booking systems, automation, equipment, sponsor connections. Also brokers connecting DACH customers with top manufacturers. | -| **Padel4U (P4U)** | Germany | padel4u.de | Via website | German distributor for Manzasport. Full range including standard, panoramic, and custom courts. ~1,000 courts/year through partnership. | -| **Trendsport Rummenigge** | Germany | trendsport-rummenigge.de | Via website | Turnkey solutions from concept to completion. Guidance on German funding programs (Sportstättenförderung). | -| **PadelCity** | Multiple (21+ locations) | padelcity.de | Via contact form | Germany's largest padel operator (20 facilities, 100+ courts). DTB partner. Proprietary booking app. Franchise model. | -| **padelBOX** | Multiple locations | padelbox.de | r.stroehl@padelbox.de | Major German padel operator and consultant. | -| **Padel Solution** | Germany | padelsolution.de | Via website | Supplier, planner, autonomous club solutions. | -| **Best World Padel** | Denmark/Germany | Via website | Via website | Official MejorSet distributor for Germany and Denmark. | - -### 1.3 Padel Hall & Building Constructors (Germany) - -| Company | HQ | Website | Contact | Description | -|---------|------|---------|---------|-------------| -| **SMC2 Bau** | France/Germany | smc2-bau.de | Via website | Textile membrane sport halls — glass court walls serve as lower facade with membrane roof above. Meets German building norms. 10-year guarantee. | -| **Padberg Projektbau** | Germany | padberg-projektbau.de | Via website | Turnkey padel hall specialist. Expertise in minimum 6–7m ceiling height, glass wall statics, LED lighting. Assists with permits and grant funding. | -| **Planeco Building** | Germany | planecobuilding.de | Via website | Building permit consultancy for converting warehouses/halls into padel facilities. Fire safety, structural analysis, change-of-use permits. | -| **BORGA** | Sweden/Austria | borga.at | Via website | 45+ years building steel halls. 3 standardized padel hall solutions plus custom. Sandwich panels, mezzanine floors, court layout optimization. | - -### 1.4 International Manufacturers with Strong German Presence - -| Company | HQ | Website | Contact | Description | -|---------|------|---------|---------|-------------| -| **AFP Courts / adidas Padel Courts** | Barcelona, Spain | afpcourts.com | Via website | 18+ years, 4,000+ courts in 54+ countries. Official adidas licensee. German distribution via The Court Company. | -| **Portico Sport** | Spain | porticosport.com/germany | Via website | Leading European builder. Installed at TSG Augsburg, TC Degerloch Stuttgart, and more. Turnkey with canopies. | -| **Padelcreations** | Spain (DACH-active) | padelcreations.com | +34 965 049 221 / info@padelcreations.com | 24+ courts in DACH region. 10 court models. Certified Spanish assembly teams. | -| **MejorSet (LeDap Group)** | Alicante, Spain | mejorset.com | +34 966 374 289 / info@mejorset.com | Official court of Premier Padel and FIP. 20+ years, pioneer of panoramic design. Present in Germany via LeDap / Best World Padel. | -| **Manzasport** | Valencia, Spain | manzasport.com | +34 963 217 472 / info@manzasport.com | Top-4 global builder, 15+ years. German distribution through Padel4U. Multiple court models. | -| **Courtwall (The Padelcourt Biz)** | Vienna, Austria | padelcourt.biz | Via website | Building courts since 1984 (squash) and padel since 2007. 1,200+ courts worldwide. ISO-certified. | -| **UnixPadel** | Istanbul, Turkey | unixpadel.com | Via website | 7,800+ courts globally. FIP-standard, KIWA-tested. Up to 12 courts/day production. TÜV-tested components. | -| **The Padel Lab** | International | thepadellab.com | Via website | HD Vision courts, tournament-grade panoramic, modular steel frame technology. Claims 40% reduction in construction time. | - -### 1.5 Turf, Lighting, Software & Accessories (Germany) - -| Company | Type | Website | Contact | Description | -|---------|------|---------|---------|-------------| -| **Mondo S.p.A.** | Turf | mondoworldwide.com | Via website | World's leading padel turf manufacturer. Official FIP/Premier Padel turf partner. 13,000+ courts globally. | -| **BECO Bermüller** | Turf | beco-bermueller.de | +49 911 64200-0 | German synthetic turf and sports field materials. Parent of LOB Sport. | -| **Polytan GmbH** | Turf | polytan.com | Via website | Since 1969. Sports surfaces development and production. Active in padel turf across Europe. | -| **Primaflor** | Turf | primaflor.de | Via website | Artificial turf supplier for padel courts. | -| **Playtomic** | Booking software | playtomic.com | Via website | World's largest padel booking platform. 73+ locations in Germany. 6,700+ clubs, 52+ countries. €56M raised. | -| **bookaball** | Booking software | bookaball.com | Via website | Booking software for racket sport clubs. Used by German market leaders. €30M+ bookings processed. | -| **Ledkia** | Lighting | ledkia.com | Via website | LED padel court floodlight solutions, 50W–1,250W. | -| **Lumosa** | Lighting | lumosa.eu | Via website | Dutch LED sports lighting manufacturer. Custom lighting plans, up to 80% energy savings. | -| **AS LED Lighting** | Lighting | Via website | Via website | Upper Bavaria-based LED specialist for padel. | - -### 1.6 German Industry Organizations & Directories - -| Organization | Website | Description | -|-------------|---------|-------------| -| **Deutscher Padel Verband (DPV)** | dpv-padel.de | Germany's official padel federation. Provides quality criteria for court purchasing. | -| **mypadel.de (DTB)** | mypadel.de | German Tennis Federation's padel portal. Court finder, leagues, partners. | -| **padel-test.de** | padel-test.de | Comprehensive German directory with builder comparisons and filterable listings. | -| **Padelinsider.de** | padelinsider.de | German padel information platform with booking system overviews. | -| **Sportstättenrechner** | sportstaettenrechner.de | Cost calculators, supplier info, and funding guidance for padel projects. | -| **Padel Lands** | padellands.com | International directory listing 60+ German clubs. | - ---- - -## 2. SPAIN — World's Largest Padel Market (17,000+ courts) - -Spain dominates global padel court manufacturing. Its manufacturers have exported courts to 70+ countries. - -### 2.1 Court Manufacturers - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **MejorSet** | Crevillente, Alicante | mejorset.com | +34 966 374 289 / info@mejorset.com | Official court of Premier Padel & FIP. 10,000+ courts in 70+ countries. Part of LeDap group. Pioneer of panoramic design. | -| **Padel Galis** | Valencia | padelgalis.com | Via website | 10,000+ courts, 75+ countries. Partnership with Wilson and Fernando Belasteguín. Official WPT/Premier Padel supplier. | -| **Portico Sport** | Villafranca de los Barros, Badajoz | porticosport.com | Via website | 15+ years, 35+ countries, 4,000+ courts. Only manufacturer also building sports canopies. 110,000+ sqft factory. | -| **Padel10** | Rubí, Barcelona | padel10.com | Calle París 1-7, nave 18, Rubí 08191 | Exclusively padel since 2008. 4,500+ courts. Former WPT official supplier. 15-day production. Mondo and ACT turf systems. | -| **Manzasport** | Beniparrell, Valencia | manzasport.com | +34 963 217 472 / info@manzasport.com | Top-4 global builder since 2003, 4 factories in Valencia. 100% Spanish manufacturing, FIP and NIDE 2021 compliant. | -| **Maxpeed** | Viladecans, Barcelona | maxpeed.com | +34 936 593 961 / maxpeed@maxpeed.com | Manufacturer, builder, equipment supplier. | -| **AFP Courts / RedSport** | Portugal/Spain | afpcourts.com / redsportpadel.com | Via website | Official adidas licensee. 15+ years, 33+ exclusive distribution centers. Official PPL court. 2,150+ courts under RedSport brand. | -| **Jubo Padel** | Spain | jubopadel.com | Via website | Family-owned, 25+ years, 6,000+ courts. FIP official. Comprehensive alliance partner network. Court configurator. | -| **Padel Courts Deluxe (PCDLX)** | Alicante | padelcourtsdeluxe.es | info@padelcourtsdeluxe.com | 100% Spanish, premium courts. Robotic welding, carbon fibre courts. Partnership with Greenset for surfaces. | -| **SportBS** | Extremadura | sportbs.es | Via website | 100% Spanish materials. 360° service including courts, lighting, turf, software. | -| **Ingode Padel Courts** | Crevillente, Alicante | ingodepadel.com | Via website | ISO 14001 & 9001. Galvanized steel with epoxy paint. 20+ years. | -| **SkyPadel** | Spain (global) | skypadel.com | Via website | 1,500+ courts in 40+ countries. EUROCODE compliant. Featured at WPT events globally. Subsidiaries in India/Brazil/Mexico. | -| **PadelMagic** | Valladolid | padelmagic.es | Via website | 400+ courts/year, 80% exported. FIP-certified. | -| **Padel Hispania** | Spain/Portugal | padelhispania.com | Via website | Federation-approved specialist in Spain and Portugal. Ambassador: Catarina Santos. | -| **VerdePadel** | Spain | verdepadel.com | Via website | Building since 2004. 2,000+ courts, 40,000+ m² of artificial grass installed. | -| **J'hayber Padel** | Spain | jhayberinstalaciones.com | Via website | Manufacturer & lighting specialist since 1972. | -| **PadelFan Valencia** | Alaquàs, Valencia | padelfanvalencia.com | +34 661 320 398 | 10+ years, 800+ customers. Also provides turf replacement. | -| **TMPadel** | Valencia | tmpadel.com | Via website | Kiwa certified, exports to 6+ EU countries. | -| **Niberma** | Spain | niberma.es | Via website | 700+ courts. | -| **Grupo Pineda** | Griñón, Madrid | grupopineda.eu | Via website | Proprietary turf & pavement. | -| **MR Instalaciones** | Madrid | mrinstalaciones.es | Via website | 20+ years, turnkey. | -| **X-Treme Group** | Alcalá de Henares, Madrid | x-tremegroup.com | Via website | 18+ years, 6,000 m² facility. | -| **MTR Padel** | Spain | mtrpadel.com | Via website | Methacrylate glass, turnkey. | -| **GimPadel** | León | gimpadel.com | Via website | 800+ installations. Built in Netherlands, Belgium, Italy, Kuwait, Portugal, Kenya. | -| **EE Padel** | Spain/Sweden | eepadel.com | Via website | 2021 merger of Eljoi Padel, EcoNatura, Swedish investors. Aluminum courts. Ships to US/Canada/ME. | -| **Greencourt** | Spain | greencourt.es | Via website | Galvanized/aluminum/precast options. | -| **ExtremaAdel** | Extremadura | extremapadel-portugal8.webnode.pt | Via website | Aluminum model innovation. | -| **Padelgest** | Spain | Via website | Via website | Urban/sustainability focus. | -| **Iberopadel** | Spain | iberopadel.com | Via website | FEP approved, Joma/Maxpeed partner. | -| **Padel Alba** | Granja de Rocamora, Valencia | padelalba.com | Via website | 25+ years, FIP-compliant. | -| **Pistas-Padel.es** | Spain | pistas-padel.es | Via website | All court types. | - -### 2.2 Spanish Turf/Surface Specialists - -| Company | Website | Contact | Description | -|---------|---------|---------|-------------| -| **Mondo** | mondoworldwide.com | Via website | Official FIP/Premier Padel turf. 16,200 m² tufting factory in Borja, Spain. | -| **Realturf** | realturf.com | Via website | Official USPA sponsor. Drive Pro, Match Play, fibrillated lines. FEP-compliant. | -| **Act Sports** | act.sport | Via website | Global padel turf leader, 10,000+ fields. | -| **Eurocesped** | eurocesped.com | Via website | ITF parameters. | -| **Allgrass** | allgrass.es | Via website | FEP compliant. | -| **Albergrass** | albergrass.com | Via website | Pilar de la Horadada, Alicante. | - -### 2.3 Spanish Lighting Specialists - -| Company | Website | Description | -|---------|---------|-------------| -| **Led Projects** | ledprojects.es | World leader in padel lighting, 5,000+ courts, WPT/Premier Padel official. | -| **Óptima LED** | optimaled.es | ProTour padel spotlights, anti-glare. | -| **PlazaLED** | plazaled.es | Sports LED projectors & scoreboards, Madrid. | -| **Ellite LED Padel** | ledpadel.com | 30+ years R&D. 360° perimeter system. 10-year warranty. Integration with booking apps. | - -### 2.4 Spanish Industry Body - -The **International Padel Cluster (CIP)** in Madrid (clusterpadel.com) is the world's largest padel industry association with **132+ member companies**, 165 associated brands, 4,500+ employees, and **€2B+ combined turnover**. It encompasses 57 court construction companies, 38 racquet brands, 20 ball producers, 32 accessory makers, and 25 clothing/textile firms. - ---- - -## 3. ITALY - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **Mondo S.p.A.** | Alba (HQ) | mondoworldwide.com | Via website | World's leading padel turf. Official FIP/Premier Padel partner. | -| **Italgreen** | Italy | italgreen.org | Via website | 40+ years. Patented fiberglass structure. FIP sponsor. Iron, Full Panoramic, V-PRO courts. Own padel turf lines (Padel Pro, Padel Fib). | -| **Limonta Sport** | Italy | limontasport.com | Via website | Premium padel turf, FEP approved, CONI partner. | -| **Padel Factory SRL** | Near Rome | padelfactorysrl.com | Via website | 1,000+ courts. Innovative hybrid wood-steel design. 10+ European countries. | -| **Padel Corporation** | Italy | padelcorporation.com | +39 339 731 2152 | 10+ years, 20+ countries. 100% made in Italy, ITF compliant. Full turnkey. Zambrotta ambassador. | -| **Italian Padel** | Italy | italianpadel.it | info@italianpadel.it | 3,000+ courts in 28 countries. Up to 180 courts/month. CE certified. | -| **Italia Team Padel** | Pesaro-Urbino, Marche | italiateampadel.com | +39 0721 571 588 | Supplied first court at Foro Italico. Basic, Vision Pro, Full Vision models. | -| **Campidapadel.it (Madrid SRL)** | Lesmo (MB) | campidapadel.it | Via website | Design, supply, installation, plus financial and marketing consultancy. | -| **Favaretti Padel** | Bagnoli di Sopra (PD) | favarettipadel.it | Via website | Turnkey, official Dunlop partner. | -| **WIP Padel** | Southern Italy | wippadel.it | Via website | CE marked, 40+ years in sports. | -| **Merli Sport** | Ravenna | merlisport.com | Via website | 500+ courts, "The Wall" showroom. | -| **NXPadel** | Italy | nxpadel.com | Via website | Patented fiberglass technology. | -| **Edil Padel S.R.L.** | Italy | edilpadel.it | Via website | Construction/installation, wood/steel. | -| **Durocem Italia** | Italy | durocem.it/padel/ | Via website | Civil works & court installation, Padel Technologies distributor. | -| **Top Padel Italia** | Italy | toppadelitalia.it | Via website | Turnkey, from €15,800. | -| **Toro Padel** | Italy | toro-padel.it | Via website | 100+ courts since 2019, patented lighting. | - ---- - -## 4. FRANCE - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **EPS Concept** | Moutiers, Brittany | eps-concept.com | +33 2 99 96 42 61 / contact@eps-concept.com | French manufacturer, 2,000+ courts, FFT PQP certified. | -| **Padel 360** | Bischheim (67) | padel360.fr | +33 7 80 91 69 43 / direction@padel360.fr | FFT PQP® certified. Turnkey with 10-year warranty. Automated club solutions and video scoring. | -| **France Padel** | Paris/Bidart | france-padel.fr | +33 5 35 45 55 00 / contact@france-padel.fr | Only French company 100% padel-dedicated. Premium, innovation-focused. | -| **100% Padel** | France | centpourcentpadel.fr | +33 6 69 78 18 47 | Family company managed by pro player Jérémy Scatena. French-manufactured. | -| **Constructeur Padel** | France | constructeur-padel.fr | +33 1 59 30 28 24 / contact@constructeur-padel.fr | 10+ years, 100+ clubs. Turnkey FIP-compliant courts. French/ecological materials. | -| **Le Padel Français** | France | lepadelfrancais.fr | Via website | 100% made in France, eco-responsible. Qualisteelcoat C5 protection. Hydro'Way permeable flooring. | -| **Metal Padel (Groupe Metal Laser)** | Rousset (13) | padel.metal-laser.com | Via website | First French padel manufacturer. FFT approved. Installs in France, Sweden, UK, Mauritius. | -| **SMC2 Construction** | Mornant, near Lyon | smc2-construction.com | +33 4 78 67 60 56 / contact@smc2-construction.com | Covered halls specialist, wood & textile membrane. Largest athletics hall in Southern Europe. | -| **Univers Construction** | Bouc-Bel-Air | universconstruction.com | +33 6 69 02 08 09 | French manufacturer/installer. Showcase center with 9 courts. 20+ years. | -| **3S Sport Systems** | Montpellier | sportsystems.fr | Via website | 3mm steel, Saint-Gobain Securit glass. 20-year structure warranty. | -| **WeOui Padel** | Valence | terrain-padel.com | Via website | High-end courts, FFT compliant. Custom furniture, decoration, accessories, maintenance. | -| **KIP Sport** | France | kipsport.fr | Via website | FFT Qualisport, 30 years sports infra. | -| **Storkeo** | France | storkeo.com | Via website | Turnkey including real estate & financing. | -| **VW Sports Padel** | Noisy-le-Grand (93) | vwsports.fr | +33 1 48 45 04 29 / contact@vwsports.fr | Historic tennis company, now padel, French manufacturing. | -| **Lauralu Industrie** | South-West France | lauralu.com | Via website | Padel court covers/halls specialist, FFT certified, 20+ years. | -| **ACS Production** | Near Nantes | Via website | +33 2 40 45 94 94 / contact@acs-production.com | Court construction & coverage, 20+ years, 25-yr membrane warranty. | -| **Concasport** | France | Via website | Via website | French manufacturer, custom designs. | -| **FieldTurf (Tarkett)** | France/Global | fieldturf.com | Via website | 25+ years synthetic turf for tennis/padel. 1,000,000+ m² installed. FIFA Preferred Producer. | -| **Losberger De Boer** | International | losbergerdeboer.com | Via website | Semi-permanent modular padel structures. Aluminum/wood frames with canvas roofing. | -| **Infinite Padel Courts** | France/North Africa | infinitepadelcourts.com | infinitepadelcourts@gmail.com | Custom courts, height-adjustable, manufactured in Alicante. | - ---- - -## 5. PORTUGAL - -| Company | Location | Website | Description | -|---------|----------|---------|-------------| -| **inCourts Padel** | Lisbon | incourtspadel.com | Robotic manufacturing, factory in North Portugal. | -| **Greenpark** | Portugal | greenpark.com.pt | First Portuguese-made padel court manufacturer. | -| **Sports Evolution** | Portugal | sports-evolution.pt | Builder/installer, also manufactures covers. | -| **Sports Partner** | Portugal | sportspartner.pt | Equipment supplier, multi-sport. | - ---- - -## 6. UNITED KINGDOM - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **PRO Padel Courts** | UK | propadelcourts.com | Via website | Times 100 Ones to Watch 2025. Italian-engineered, patented anti-noise system. 50-year lifespan. MejorSet master distributor UK. | -| **Portico Sport UK** | Congleton, Manchester | porticosport.com/uk | Via website | From £15,000. Part of Portico Sport global network. | -| **Padel Tech** | UK | padeltech.co.uk | Via website | Leading UK supplier/installer. Exclusive AFP Courts/adidas UK distributor. 150+ courts. | -| **Hexa Padel** | Woodford Green, Essex | hexapadel.co.uk | Via website | One of UK's largest builders. Courts, canopies, booking software, maintenance, academy. | -| **iPadel Ltd** | UK | ipadel.co.uk | Via website | Independent consultancy. Free quotes from multiple suppliers. Planning and investment matchmaking. | -| **SG Padel** | UK | sgpadel.co.uk | Via website | Turnkey, MejorSet distributor, SAPCA approved. | -| **SIS Pitches / SISTurf** | UK | sispitches.com | Via website | 25+ years elite sports surfaces. UK-based turf manufacturer. Design, manufacture, install, maintain. 65 years. | -| **Padel Magic UK** | Nationwide | padelmagic.co.uk | Via website | Proprietary "Magic Base" for uneven terrain. Custom covers/canopies. Nationwide. | -| **Padel Build UK** | North Lincolnshire | padelbuilduk.com | Via website | UK manufacturer, hot-dip galvanizing. | -| **Padel Systems** | UK | padelsystems.co.uk | Via website | Bespoke builder, partners with Italian Padel. Sister company: CopriSystems. | -| **Red Raven Solutions** | UK | redravensolutions.co.uk | Via website | Exclusive PadelCreations UK distributor, 500+ courts. | -| **Padel Works** | Whitchurch, Shropshire | padelworks.co.uk | Via website | FIP-approved courts. 10-year warranty on court and surface. | -| **Padel Galis UK** | Coventry | padelgalis.uk | info@padelgalis.uk / +44 7494 045287 | Exclusive UK supplier of Padel Galis. | -| **S&C Slatter** | UK | slattersportsconstruction.com | Via website | 30+ years sports construction. Partners with FieldTurf. In-house civil engineering. | -| **Fordingbridge** | West Sussex | fordingbridge.co.uk | info@fordingbridge.co.uk / +44 1243 554455 | UK's leading padel canopy specialist, 60+ years, 25-yr guarantee. | -| **Collinson Tensile** | UK | collinsontensile.co.uk | Via website | 20+ years tensile buildings. Exclusive UK partner for Best-Hall Finland. ISO 9001/45001. | -| **Rubb UK** | Gateshead | rubbuk.com | Via website | Fabric building specialists. Thermohall® insulation. Modular, relocatable. | -| **J & J Carter** | UK | jjcarter.com | Via website | Tensile sports halls, inflatable halls, frame/fabric structures. | -| **Padel Consulting** | London | padelconsulting.co.uk | Via website | Advisory firm, SAPCA member. | - ---- - -## 7. NETHERLANDS - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **Allesvoorpadel (Padelbouw)** | Biddinghuizen | allesvoorpadel.nl | info@allesvoorpadel.nl / +31 320 331 588 | Leading Dutch builder, 10+ years, NK Padel official rink builder. AFP Courts partner. Philips lighting, Padelkiosk vending. | -| **Padel Nederland B.V.** | Monster | padelnederland.nl | info@padelnederland.nl / +31 6 83 67 51 47 | Durable aluminum courts, 15-year warranty. KIWA/KNLTB certified. Solar canopy options, acoustic solutions. | -| **I-Padel** | Netherlands | i-padel.nl | Via website | Dutch manufacturer, in-house production. KIWA ISA Sport / NOC*NSF certified. 15-year warranty. Also offers Ping-Pong Padel. | -| **SkyPadel NL** | Zuid-Holland | skypadel.nl | info@skypadel.nl / +31 638 448 409 | 1,800+ courts, Babolat official, since 2002. | -| **Padel.nl** | Netherlands | padel.nl | Via website | Since 2003, KNLTB/KIWA certified, proprietary foundations. | -| **Orange Padel International** | Netherlands | orangepadel.nl | Via website | Premium Dutch-designed courts. 30 years experience. FEMEPA certification. | -| **Padel Solution NL** | Netherlands | padelsolution.nl | Via website | 3,000+ installed courts in 30+ countries. Full project support. | -| **World Padel** | Netherlands | worldpadel.nl | Via website | Court supplier. | -| **Frisomat** | Belgium (NL-active) | frisomat.com | Via website | Nearly 50 years steel construction. Cold-formed galvanized padel canopies/roofs. Modular, demountable. | - ---- - -## 8. BELGIUM - -| Company | Location | Website | Description | -|---------|----------|---------|-------------| -| **Padel Projects** | Belgium (Benelux) | padelprojects.eu | Court construction, 10+ years, 3,000+ courts, patented lighting. | -| **JM Padel** | Province of Liège | jmpadel.be | Installer, consultant, club management, IT/video. | -| **YoPadel SPRL** | Belgium | yopadel.be | Belgian manufacturer, Belgian materials, Lano Sports turf partner. | -| **Domo Sports Grass** | Belgium | Via website | Global artificial grass expert. Certified by major sports federations. | - ---- - -## 9. SCANDINAVIA (Sweden, Denmark, Finland, Norway) - -| Company | Country | Website | Contact | Description | -|---------|---------|---------|---------|-------------| -| **Padeltotal** | Sweden | padeltotal.se | Via website | Largest Nordic supplier. 1,600+ courts since 2013. Galvanized for Nordic conditions, 12mm glass. Duruss partnership. | -| **Padel Global** | Sweden (Jönköping) | padel-global.com | Via website | Manufacturer, own factory. | -| **Scandinavian Padel AB** | Sweden (Malmö, factory in Lysekil) | scandinavianpadel.co | info@scandinavianpadel.co / +46 761 309080 | 25+ years in steel/glass for Nordic climate. C3 "oil rig grade" steel. Own ScanTurf turf. | -| **Sweden Padel Master** | Sweden | swedenpadelmaster.se | Via website | SPM Grass Court Cut technology. | -| **Acenta Group** | Sweden/Norway | acenta.group | Via website | Major Scandinavian company, courts/service/digital/equipment. Fiberglass courts expanding to AU/NZ. | -| **Instantpadel (Instant Courts)** | Sweden | instantcourts.com | Via website | World-unique mobile court, setup in <4 hours. 150+ courts, 17 countries. Installations at Gleneagles, Soho Club London. | -| **Hallgruppen** | Sweden/Nordic | hallgruppen.com | Via website | Padel hall structures. Self-supporting steel frames (50-year lifespan). Rental, leasing, purchase. CE approved. | -| **Best-Hall** | Finland | Via website | Via website | 5,500+ buildings worldwide. 40+ years. Fabric structures for sports halls. UK partner: Collinson Tensile. | -| **ViPadel** | Denmark (+ Finland) | vipadel.dk | Via website | Total supplier, official Mondo dealer DK/FI. | -| **A-Sport** | Denmark | a-sport.dk | Via website | Supplier/installer, 250+ courts. | -| **Tiebreak International / PadelTotal DK** | Glostrup, Denmark | padeltotal.dk | info@tiebreakinternational.com / +45 36889900 | PadelTotal concept for Denmark, 200+ courts. | -| **Unisport** | Finland/Denmark | unisport.com | Via website | Court manufacturer, Saltex Tempo turf. | - ---- - -## 10. OTHER EUROPEAN COUNTRIES - -| Company | Country | Website | Description | -|---------|---------|---------|-------------| -| **Courtwall (Padelcourt Biz)** | Austria | padelcourt.biz | Courts since 1984 (squash) and padel since 2007. 1,200+ courts. ISO certified. | -| **BORGA** | Sweden/Austria | borga.at | 45+ years building steel halls. Padel hall solutions. | -| **DUOL** | Slovenia | duol.eu | Air-supported and fabric sports buildings. Nearly 30 years. Online configurator. | -| **Losberger De Boer** | Germany/International | losbergerdeboer.com | Semi-permanent modular padel structures. | - ---- - -## 11. UNITED STATES - -The US padel market reached 688 courts across 180 facilities in 31 states by mid-2025, with 51.5% YoY club growth and a projected trajectory toward 6,800 courts by 2030. - -### 11.1 US-Based Manufacturers & Builders - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **Absolute Padel** | Mohnton, PA | absolutepadelusa.com | +1 717 445 5036 / info@absolutepadelusa.com | Only North America-based manufacturer. 100+ projects. 50%+ of US courts. Unique Pickleball & Padel combo court. Custom court generator. | -| **The Padel Box** | Multi-state (CA, FL, NY, NJ, etc.) | thepadelbox.com | info@padelbox.com | US pioneer since 2012, licensed in CA, NV, AZ, UT, NC, NJ. 15+ states. Official MejorSet US/Canada distributor. Hurricane-rated to 180 mph. | -| **Sportsfield Specialties** | Delhi, NY | sportsfield.com | +1 607 746 8911 / +1 888 975 3343 | USPA-endorsed manufacturer, 100% Made in USA, PaDelhi™ courts. | -| **USA Padel Center** | Houston, TX | usapadel.com | +1 713 539 3110 / info@usapadelcenter.com | Manufacturer/consultant since 2007. | -| **Padel One Courts** | Florida (nationwide) | padelonecourts.com | Via website | Premium American-made courts. C5 anti-rust coating. Trusted by Pro Padel League and SVB Mouratoglou Academy. | -| **Bounce Padel Courts** | Canada (NA-wide) | bouncepadelcourts.com | Via website | Premier North American provider. SGCC/ANSI-certified glass. Hurricane-class anchoring. Converts tennis courts and ice rinks. | -| **Northeast Padel** | Pocasset, MA | northeastpadel.com | +1 508 759 5636 / info@northeastpadel.com | Division of Cape & Island Tennis & Track, most-awarded US court builder. 50+ facility awards from ASBA. | -| **Sport Surfaces / Mondo Padel** | West Palm Beach, FL | sportsurfaces.com / mondopadel.com | +1 888 423 1120 / info@mondopadel.com | 150+ years combined team experience. FL licensed. Builds from ground up or converts tennis courts. | -| **Keystone Sports Construction** | USA | keystonesportsconstruction.com | Via website | Full-service turnkey padel from design to installation. Sportsfield Specialties partner. | -| **MTJ Sports** | Chicago area | mtjsports.com | Via website | 20+ years sports courts. Padel, pickleball, soccer, tennis. Turnkey for clubs, hotels, municipalities. | -| **Capas Padel** | USA/Puerto Rico | capaspadel.com | Via website | Builder/consultant, GreenSet surfaces, Smart Padel Club. | -| **All Racquet Sports** | Sandy, UT / Ft. Myers, FL | allracquetsports.com | info@allracquetsports.com | Official adidas/AFP US distributor, 700+ courts network. | - -### 11.2 European Manufacturers with US Operations - -| Company | HQ | Website | Contact | Description | -|---------|------|---------|---------|-------------| -| **MejorSet USA** | Spain | mejorset.com/us-eng | info@mejorset.com / d.polerecky@mejorset.com | Official FIP 2025–2026 court. Bilingual US team. X-Treme model resists 165 mph winds. FL Building Code certified. | -| **Portico Sport USA** | Spain | porticosport.com/padel-court-usa | Via website | US since 2021. Projects in NY, TX, FL, CA, IL, MA. AISC-360 and ASCE SEI 7-16 compliant. 10-year guarantee. | -| **AFP Courts** | Spain/Portugal | afpcourts.com | Via website | Official PPL court. adidas and RedSport manufacturer. | -| **Padel Galis** | Spain | padelgalis.com | Via website | 10,000+ courts globally. Wilson partnership. | -| **Italgreen** | Italy | italgreen.org | Via website | Patented fiberglass courts (zero rust). FIP technical sponsor. Up to 10-year warranty. | -| **SkyPadel** | Spain | skypadel.com | Via website | 1,500+ courts in 40+ countries. | - -### 11.3 US Padel Franchises & Operators - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **Conquer Padel Club** | Lehi, UT (expanding) | conquerpadel.com | Via website | First US padel franchise, $1.1M–$3M+ investment. | -| **Park Padel** | San Francisco area | parkpadel.com | hello@parkpadel.com | Franchise, pop-up courts, community-focused. | -| **Jungle Padel** | USA | junglepadel.com | Via website | Franchise, premium Mondo turf, academy. | - -### 11.4 Padel Turf Suppliers (North America) - -| Company | HQ | Website | Description | -|---------|------|---------|-------------| -| **Realturf** | Spain | realturf.com/us | Official USPA sponsor. Drive Pro, Match Play. FEP-compliant. | -| **CCGrass** | China | ccgrass.com | Three factories. FEP-compliant. FastPro and YEII products. Also complete court packages. | -| **FieldTurf (Tarkett)** | France/USA | fieldturf.com | 1,000,000+ m² tennis/padel installed. FIFA Preferred Producer. | -| **WinterGreen Synthetic Grass** | Dallas, TX | wintergreengrass.com | Pro-grade padel turf in DFW. "Padel Pro" surface (same as WPT). | -| **JCTurf** | China | jcturf.com | In-house fiber extrusion. FIP/FEP compliant. Also complete court solutions. | -| **MightyGrass** | China | mightygrass.com | Professional padel turf, FEP-level. Factory direct pricing. | -| **Laykold / Sport Group** | Global | laykold.com | Padel Turf Pro surface. US Open official surface brand. | - -### 11.5 Padel Lighting Specialists (North America) - -| Company | Location | Website | Description | -|---------|----------|---------|-------------| -| **LED Lighting Supply** | USA | ledlightingsupply.com | 15+ years, 25,000+ projects. 150W LED fixtures. Free photometric plans. 5-year warranty. | -| **Tweener USA** | USA (French-developed) | tweenerusa.com | Patented LED on existing fencing — no poles needed. Minimal light pollution. Dimmable. | -| **Brite Court** | USA | britecourt.com | 40+ years racquet sports lighting. 600+ facilities. 18+ fixture designs. Samsung LEDs. 10-year warranty. | -| **AEON LED Lighting** | USA | aeonledlighting.com | Patented luminaires. UGR below 19 (glare-free). 100,000-hour lifespan. DLC Premium listed. | -| **AGC Lighting** | China | agcled.com | SP11 linear sports light for padel. Smart controls (DALI 2, DMX). Supports 4K broadcasting. | - -### 11.6 US Industry Organizations - -The **USPA (United States Padel Association)** at padelusa.org endorses select manufacturers and partnered with the **American Sports Builders Association (ASBA)** on the Padel Courts Installation & Maintenance Manual 2025 — the first US construction standard. - ---- - -## 12. MEXICO - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **American Padel (TCDL)** | Mexico City | americanpadel.com.mx | +52 55 5891 3350 / info@americanpadel.com.mx | FIP-compliant, 25 yrs metalwork. | -| **Padel Center México** | Aguascalientes | padelcenter.mx | Via website | FIP-certified. Clásica, Semipanorámica, Pro models. 20-30 day delivery. | -| **MG Canchas** | Monterrey | mgcanchas.com | Via website | Pioneer manufacturer in Monterrey. Also supplies synthetic turf. | -| **SicaSport** | Mexico | sicasport.com | Via website | Manufacturer/builder/installer. | -| **Gott Padel** | Mexico | gottpadel.com | Via website | Design, installation, construction. Also sells rackets and balls. | -| **AFP Courts México** | Mexico | afpcourts.mx | Via website | Official adidas licensee for Mexico. | -| **CanchasdePadel.com** | Mexico | canchasdepadel.com | Via website | FIP-certified. WPT-certified curly turf. | -| **Padel Works MX** | Mexico | padelworks.com.mx | Via website | High-quality custom courts. Full support from civil works to club growth. | -| **PadelStore.mx** | Mexico | padelstore.mx | Via website | Court accessories: fencing, nets, posts, turf, sand, LED, protective pads. Ships nationwide. | - ---- - -## 13. MIDDLE EAST (UAE, Saudi Arabia, GCC) - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **Padel Factory (ME)** | Dubai, UAE | padelfactory.me | info@padelfactory.me / +971 56 536 9494 | Top manufacturer/supplier. Super Panoramic, Panoramic, Challenger, Portable. 400+ courts. UAE/KSA/Kuwait/Bahrain/Oman. | -| **RedLine Padel** | Dubai, UAE | redlinepadel.com | Via website | Spanish manufacturer based in Dubai. 48-hour delivery across ME. UNE EN 1090. Also operates clubs. | -| **Cypex Group** | UAE | cypex-group.com | Via website | Represents Padel Factory ME. Exclusive LANO GRASS Belgium distributor for GCC. Projects across ME, India, Maldives, South Africa. | -| **APW Pools** | Dubai | apw-pools.com | +971 50 852 1161 | Padel supplier/installer, smart lighting, advanced materials. | -| **Mister Shade ME** | Dubai | mistershademe.com | Via website | 20+ years in flooring. Artificial turf and acrylic padel courts. All UAE emirates. | -| **Gebal Group** | Dubai/Abu Dhabi/Riyadh/Jeddah | gebalgroup.com | Dubai: +971 44519691 / Riyadh: +966 55 977 7146 | Turnkey builder across GCC (6 countries). FIP-compliant. | -| **Empower Sport Services** | UAE | empowersportservices.com | Via website | 2,500+ installations, FEP certified. | -| **Shades Galaxy** | Dubai | shadesgalaxy.com | Via website | Manufacturer/supplier, all UAE emirates. | -| **Fab Floorings** | Dubai | fabfloorings.ae | Via website | Turnkey: flooring/glass/lighting/branding. | -| **Al Mustaqbal Alsarea** | UAE | almustaqbalalsarea.com | +971 50 247 5749 | Gulf countries leader. | -| **PFS Gulf** | Saudi Arabia | pfsgulf.com | Via website | Infrastructure company. Padel courts across KSA (Riyadh, Jeddah, Dammam, Mecca, Medina). | -| **Portico Sport ME** | Spain (Dubai/Saudi) | porticosport.com/middle-east | Via website | Active across Dubai, Abu Dhabi, Riyadh, Jeddah, Kuwait. 10-year guarantee. | - ---- - -## 14. TURKEY - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **Mediterra Padel** | Antalya | mediterrapadel.com | info@mediterrapadel.com / +90 554 678 51 40 | Turkey's largest, 35+ countries. Active in Kenya, SA, Sierra Leone, Morocco, Nigeria. | -| **Integral Grass / Integral Spor** | Istanbul | integralgrass.com | info@integralgrass.com / +90 212 678 13 13 | 11 models, 70+ countries. | -| **Unix Padel** | Istanbul | unixpadel.com | Via website | 7,800+ courts. Wind/impact tested by Istanbul Technical University. FIP-standard, KIWA-tested. | - ---- - -## 15. CHINA — Global Export Manufacturing Powerhouse - -Complete court packages from China typically cost $10,400–$12,700 including shipping and installation. - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **Legend Sports (Qifan)** | Yanshan, Hebei | legendsports.com | Via website | One of China's largest. 220+ employees, 32 engineers. 5,000+ courts in 60+ countries. 66,000 m² factory. | -| **Fortune Padel** | China (offices in Indonesia, Italy, Spain) | fortunepadel.com | Via website | ISO 9001:2015. 20+ models including electric roof. Ships to 50+ countries within 20 days. 99.99% quality pass rate. | -| **China Youngman Padel / Young Padel** | Hefei, Anhui | youngpadel.com / premierpadelchina.com | Via website | China's largest since 2010. SGS, CE, ISO9001. 8 models. Also produces roof covers. | -| **Wanhe Padel** | Huaian, Jiangsu | wanhesport.com | Via website | Follows FIP regulations. Courts, 12mm turf, LED lighting. Also padel rackets. | -| **Shengshi Sports Tech** | Tianjin | shengshitrade.en.made-in-china.com | Via website | 20+ years sports equipment. 10,000+ m² facility near Tianjin port. | -| **PadelCourt10** | Hebei | padelcourt10.com | Via website | 1,000 sets/year capacity. 25+ countries. 5-year warranty. DDU door-to-door service. | -| **Shanghai Super Power** | Shanghai | padelcourtfactory.cn | Via website | 200+ employees. 350 courts/month capacity. Aluminum frames for coastal regions. | -| **UNIPADEL** | Guangzhou | gzunipadel.com | Via website | 5,000+ courts worldwide. Panoramic, classic, portable, roofed, padbol. Active in Indonesia, ME, Africa, LATAM. | -| **ArtPadel** | China | artpadel.com | Via website | Panoramic/classic courts, patented technology. | -| **LDK China** | Shenzhen | ldkchina.com | info@ldkchina.com / +86 755 89896763 | Manufacturer/exporter. | -| **SANJING Group** | Linqu, Shandong | sanjingcourt.com | Via website | Glass specialist, 27 years, 300+ employees, 40+ countries. | -| **Luckin Padel** | China | luckinpadel.com | Via website | FIP-certified standards, educational focus. | -| **Saintyol Sports** | China | Alibaba | Via website | 15+ years. Specializes in padel turf and structures. 10,000+ m² facility. | -| **Nanjing Padelworker** | Nanjing | Alibaba | Via website | 67% client reorder rate. Courts, squash equipment, glass fittings, turf. | -| **Hebei Aohe Teaching Equipment** | Hebei | Made-in-China | Via website | Est. 2012. 80% repeat business. Also aluminum frame sports tents. | -| **Shandong Century Star** | Shandong | Alibaba | Via website | Large facility. Steel structure courts, panoramic models. | -| **CCGrass** | China (global) | ccgrass.com | Via website | Major turf manufacturer. FEP-compliant. FastPro and YEII. Also complete court packages. | -| **JCTurf** | China | jcturf.com | Via website | In-house fiber extrusion. FIP/FEP compliant. | -| **MightyGrass** | China | mightygrass.com | Via website | Professional padel turf, FEP-level. Factory direct. | - ---- - -## 16. INDIA - -India is projected to add 12,000 padel courts over the next 15 years. - -| Company | Location | Website | Description | -|---------|----------|---------|-------------| -| **Asian Flooring India (AFI Padel)** | Thane/Mumbai | asianflooring.in / afipadel.com | India's largest padel manufacturer. FIP-standard. Standard, Panoramic, Ultra Panoramic, Kids. 25-day delivery. | -| **Apex Sport Surfaces (SMI Padel)** | Mumbai | apexsportsurfaces.in | FIP-compliant manufacturer/exporter. | -| **Sky Padel India** | Mumbai | skypadel.in | Local manufacturing, subsidiary of Spanish Sky Padel. | -| **PFS Sport India** | India | pfs.sport | Turf & surface manufacturer. | -| **PadelHaus India** | India | padelhaus.in | Courts for every budget. | -| **Portico Sport India** | India | porticosport.com/ind | Targets Mumbai, Delhi, Bengaluru, Hyderabad, Pune. Turnkey. | - ---- - -## 17. ASIA (Non-China, Non-India) - -| Company | Country | Website | Description | -|---------|---------|---------|-------------| -| **SmartPadel / SEARA Sports** | Southeast Asia | smartpadel.asia | Regional leader in SE Asia. Video recording, automated scoring. | -| **Olympia Courts** | Asia Pacific | olympiacourts.com | Premium courts. European know-how, Asian manufacturing. Partners with Asia Pacific Padel Tour. | -| **Indo Padel** | Indonesia (Bali) | indopadel.com | Spanish-Indonesian team. Courts manufactured in Indonesia. Active in Thailand, India. | -| **Padel Asia** | Thailand | padelasia.org | Courts meeting international standards. Also sells rackets, clothing. Operates courts in Bangkok. | - ---- - -## 18. LATIN AMERICA - -### 18.1 Brazil - -| Company | Website | Contact | Description | -|---------|---------|---------|-------------| -| **Padel Master Brasil** | padelmaster.com.br | Via website | 1,500+ courts in 10+ countries. Official Pala Tour/WPT Americas court. 10-year warranty. One of Brazil's most modern plants. | -| **Sky Padel Brasil** | skypadel.com.br | Via website | 10+ years. FEP/FIP certified. VP PRO 2.0, SP PRO, Full View, rental, mobile. 15-day production. | -| **Smart Padel** | smart-padel.com | Via website | IoT-connected courts. Online monitoring, strategic management software. FIP/FEP certified. | -| **Flores Pádel** | florespadel.com.br | Via website | Community-based manufacturer. 10+ years. Turf certified by Spanish federation. Founded by national team athletes. | -| **FC Quadras** | fcquadras.com.br | Via website | São Paulo. Distributes Padelgest courts. Turnkey from terrain prep to finishing. | -| **Padel Prime** | padelprime.com.br | Via website | European-standard manufacturing. Co-founded by ex-footballer Edmílson. | -| **F4 Quadras** | Instagram: @f4quadras | +55 53 9 8447 8700 | Manufacturer/installer. | - -### 18.2 Argentina - -| Company | Website | Description | -|---------|---------|-------------| -| **Padel Courts Master** | padelcourtsmaster.ar | 1,500+ courts delivered worldwide, 8+ countries. Robotic welding. FIP-standard. 100+ padel experts. | -| **MS Pádel (Metalser)** | metalurgicametalser.com | +54 2314 407746. Professional panoramic courts. Full package: structure, glass, LED, turf. | -| **World Padel Court** | worldpadelcourt.com.ar | Led by Visión Deportiva (major event organizer). Top-quality courts. Portable court rental. | -| **Blue Court** | bluecourt.com.ar | 15+ years manufacturing. Established Argentine brand. | -| **Slavon Césped Sintético** | slavoncespedsintetico.com | Panoramic and full panoramic courts. Also provides synthetic turf. | - -### 18.3 Mexico - -| Company | Location | Website | Contact | Description | -|---------|----------|---------|---------|-------------| -| **American Padel (TCDL)** | Mexico City | americanpadel.com.mx | +52 55 5891 3350 / info@americanpadel.com.mx | FIP-compliant, 25 yrs metalwork. | -| **Padel Center México** | Aguascalientes | padelcenter.mx | Via website | FIP-certified. Clásica, Semipanorámica, Pro. | -| **MG Canchas** | Monterrey | mgcanchas.com | Via website | Pioneer manufacturer. Also synthetic turf. | -| **SicaSport** | Mexico | sicasport.com | Via website | Manufacturer/builder/installer. | -| **Gott Padel** | Mexico | gottpadel.com | Via website | Design, installation, construction. | -| **AFP Courts México** | Mexico | afpcourts.mx | Via website | Official adidas licensee for Mexico. | -| **CanchasdePadel.com** | Mexico | canchasdepadel.com | Via website | FIP-certified. WPT-certified turf. | -| **Padel Works MX** | Mexico | padelworks.com.mx | Via website | Custom courts, full civil works support. | -| **PadelStore.mx** | Mexico | padelstore.mx | Via website | Accessories: fencing, nets, turf, sand, LED, pads. | - ---- - -## 19. AFRICA — South Africa Leads the Continent - -South Africa has 150+ courts and multiple domestic manufacturers. - -| Company | Country | Website | Description | -|---------|---------|---------|-------------| -| **Padel Nation** | South Africa | padelnation.co.za | SA's leading manufacturer. 150+ courts. Local hot-dip galvanized manufacturing. 4-week lead times. Up to 10-year warranty. | -| **Padel Build** | South Africa | padelbuild.co.za | Premier turnkey builder. Partnered with Spain's Padel Galis. First FlexiPadel Base in Africa. | -| **Techno Padel** | South Africa | technopadel.co.za | Premier supplier/installer. 5–7 day installation. | -| **Padel Solutions** | South Africa | padelsolutions.co.za | Proudly SA. Design, manufacture, install. Turnkey. | -| **Padel Quip** | South Africa | padelquip.co.za | Local manufacturer. Basic to Premium Plus models. Partnership and financial assistance. | -| **Padel Projects SA** | South Africa | padelprojects.co.za | Designed for local conditions. | -| **Trompie Sport** | South Africa | trompiesport.co.za | Builder, imported & local courts. | -| **Belgotex Sport** | South Africa | belgotexsport.co.za | SA-based turf manufacturer (Pietermaritzburg factory). UNE 147301:2018 compliant. 220+ installations. | -| **Africa Padel** | South Africa | africapadel.com | Largest club group in Africa. 21+ clubs across SA. Founded 2021. Events, corporate leagues. | -| **Portico Sport SA** | South Africa | porticosport.com/za | Completed Virgin Active Padel Club and Atlantic Padel Cape Town. Force 80 hurricane-resistant courts. | -| **Padel Africa** | Sub-Saharan | padel.africa | Bringing padel to Ghana and Rwanda. Team has started 100+ companies and sold 2,000 courts. | -| **Technotrade Sports** | Egypt | technotradesports.com | Contractor, one of the best in Arab world. | -| **Turkan Company** | Egypt/Saudi Arabia | turkan-eg.com | Manufacturer, one of first in Egypt. | - ---- - -## 20. AUSTRALIA & OCEANIA - -| Company | Location | Website | Description | -|---------|----------|---------|-------------| -| **Laykold Padel / APT Asia Pacific** | Melbourne | aptasiapacific.com.au | Asia Pacific's largest sports surfaces company. Australian-made turf. Aluminium 6061-T6 frames. AS/NZS certified. Pop-up courts. | -| **Synthetic Padel Courts / Synthetic Sports Group** | Australia | syntheticpadelcourts.com.au / syntheticsportsgroup.com.au | Built the first padel court in Australia. Preferred installer for Indoor Padel Australia, Sydney Racquet Club. A$65K–$100K per court. | -| **Padel in One Australia** | Australia | padelinone.com.au | Turnkey specialist. 8+ years. Management, marketing, operations consulting. Mission to consolidate padel in Oceania. | -| **PadelVolt** | Australia/Pacific | padelvolt.com | End-to-end premium service. MejorSet distributor across Oceania and Pacific Islands. Extreme weather designs. | -| **NXPadel / Acenta Group** | Sweden → Australia | acenta.group | Swedish Acenta Group expanded fiberglass courts to Australia/NZ (Jan 2026). Positioned for Brisbane 2032 Olympics. | -| **Padel 360 Australia** | Australia | padel360.com.au | Developer/builder/manager, Gimpadel partner. | -| **AS Lodge Tennis Courts** | Melbourne, VIC | asltenniscourts.com.au | Builder, $90K–$130K per court. | -| **All Sport Projects** | QLD & NSW | allsportprojects.com.au | Non-rust aluminum courts, 7–15 yr warranties. | -| **SPORTENG** | Australia | sporteng.com.au | Consulting/design, developed official Padel Australia Guidelines. | - ---- - -## 21. PAN-EUROPEAN / GLOBAL BOOKING SOFTWARE & TECHNOLOGY - -| Company | HQ | Website | Description | -|---------|------|---------|-------------| -| **Playtomic** | Spain (Madrid) | playtomic.com | World's largest racket sports platform. 6,700+ clubs, 4M+ players, 52+ countries. €56M raised. Published Global Padel Report 2025. | -| **MATCHi / Matchpoint** | Sweden | tpcmatchpoint.com | 1,600+ venues. Multi-sport booking, memberships, leagues, coaching. | -| **Padel Mates** | Europe | Via website | All-in-one platform. Won Rocket Padel (Europe's largest indoor chain). Gamification features. | -| **SmashClub** | Europe | smashclub.cloud | Padel CRM and club management. Integrates with Playtomic, MATCHi, Padel Mates. | -| **Taykus** | Spain | Via website | Software specifically for padel clubs. Online booking, payment, communication automation. | -| **Playbypoint** | USA | playbypoint.com | Official tech partner of 2025 US Open Padel. Custom branded app per club. | -| **CourtReserve** | USA | Via website | Leading US platform alongside Playbypoint and Playtomic. | -| **360Player** | International | en-us.360player.com | Club management with website builder, video analysis, player development tools. | -| **Booklux** | International | booklux.com | Customizable booking system. Stripe payments. Google Analytics integration. | -| **SetTime** | International | settime.io | Free padel booking software. Google/Apple Calendar sync. Analytics for utilization. | -| **ProPadelKit** | International | propadelkit.com | Turnkey court solutions, Classic & Fusion models. | - ---- - -## 22. KEY CERTIFICATIONS & INDUSTRY BODIES - -| Body | Description | -|------|-------------| -| **FIP (International Padel Federation)** | Sets global court standards. Current official suppliers: MejorSet (courts), Mondo (turf). | -| **International Padel Cluster (CIP)** | Madrid. 132+ member companies, €2B+ combined turnover. clusterpadel.com | -| **FEP (Spanish Padel Federation)** | Approves manufacturers for world's largest domestic market. | -| **USPA (US Padel Association)** | Endorses US manufacturers. Partnered with ASBA on first US construction standard (2025). | -| **FFT PQP (French Tennis Federation)** | Quality certification for French market. | -| **KIWA / NOC*NSF** | Dutch quality standard for sports equipment. | -| **DPV (Deutscher Padel Verband)** | German federation quality criteria. | -| **SAPCA** | UK Sports and Play Construction Association. | - ---- - -*Directory compiled February 2025. The padel industry is evolving rapidly — new entrants appear monthly. The global court count is projected to reach ~84,000 by end of 2026. For the most current information, check the International Padel Cluster directory (clusterpadel.com) and regional federation websites.* diff --git a/padelnomics/.env.example b/padelnomics/.env.example index c7c299c..3398e78 100644 --- a/padelnomics/.env.example +++ b/padelnomics/.env.example @@ -3,7 +3,9 @@ APP_NAME=Padelnomics SECRET_KEY=change-me-generate-a-real-secret BASE_URL=http://localhost:5000 DEBUG=true -ADMIN_PASSWORD=admin + +# Admin access — comma-separated emails that get the admin role on login +ADMIN_EMAILS=dev@localhost # Database DATABASE_PATH=data/app.db diff --git a/padelnomics/src/padelnomics/admin/templates/admin/article_form.html b/padelnomics/src/padelnomics/admin/templates/admin/article_form.html index 03af73e..aed810c 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/article_form.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/article_form.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "articles" %} {% block title %}{% if editing %}Edit{% else %}New{% endif %} Article - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}
← Back to articles

{% if editing %}Edit{% else %}New{% endif %} Article

@@ -79,5 +79,4 @@
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/articles.html b/padelnomics/src/padelnomics/admin/templates/admin/articles.html index db6cee6..663dc81 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/articles.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/articles.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "articles" %} {% block title %}Articles - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

Articles

@@ -73,5 +73,4 @@

No articles yet. Create one or generate from a template.

{% endif %}
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/feedback.html b/padelnomics/src/padelnomics/admin/templates/admin/feedback.html index f2ac366..0fe0d9e 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/feedback.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/feedback.html @@ -1,8 +1,8 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "feedback" %} {% block title %}Feedback - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

Feedback

@@ -47,5 +47,4 @@

No feedback yet.

{% endif %} -
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/generate_form.html b/padelnomics/src/padelnomics/admin/templates/admin/generate_form.html index e076a39..4c85806 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/generate_form.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/generate_form.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "templates" %} {% block title %}Generate Articles - {{ template.name }} - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}
← Back to {{ template.name }}

Generate Articles

@@ -43,5 +43,4 @@ {% endif %}
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/index.html b/padelnomics/src/padelnomics/admin/templates/admin/index.html index 89dd2fd..8cd184c 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/index.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/index.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "dashboard" %} {% block title %}Admin Dashboard - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

Admin Dashboard

@@ -17,9 +17,9 @@
{% endif %} -
+ - +
@@ -46,68 +46,55 @@ +

Lead Funnel

-
+

Planner Users

{{ stats.planner_users }}

-
+

Total Leads

{{ stats.leads_total }}

-
+

New

{{ stats.leads_new }}

-
+

Verified

{{ stats.leads_verified }}

-
+

Unlocked

{{ stats.leads_unlocked }}

+

Supplier Funnel

-
+

Claimed Suppliers

{{ stats.suppliers_claimed }}

-
+

Growth Tier

{{ stats.suppliers_growth }}

-
+

Pro Tier

{{ stats.suppliers_pro }}

-
+

Credits Spent

{{ stats.total_credits_spent }}

-
+

Leads Forwarded

{{ stats.leads_unlocked_by_suppliers }}

- - - -
@@ -174,5 +161,4 @@
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/lead_detail.html b/padelnomics/src/padelnomics/admin/templates/admin/lead_detail.html index e1c4148..b376dff 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/lead_detail.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/lead_detail.html @@ -1,8 +1,8 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "leads" %} {% block title %}Lead #{{ lead.id }} - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}
← All Leads @@ -109,7 +109,7 @@ {% for f in lead.forwards %} - {{ f.supplier_name }} + {{ f.supplier_name }} {{ f.credit_cost }} {{ f.status }} {{ f.created_at[:16] if f.created_at else '-' }} @@ -120,5 +120,4 @@
{% endif %} -
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/lead_form.html b/padelnomics/src/padelnomics/admin/templates/admin/lead_form.html index 1dd8a55..857b965 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/lead_form.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/lead_form.html @@ -1,8 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "leads" %} {% block title %}New Lead - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %} +
← All Leads

Create Lead

@@ -113,5 +114,5 @@ -
+ {% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/leads.html b/padelnomics/src/padelnomics/admin/templates/admin/leads.html index ac861bc..2c958ab 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/leads.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/leads.html @@ -1,8 +1,8 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "leads" %} {% block title %}Lead Management - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

Lead Management

@@ -64,5 +64,4 @@
{% include "admin/partials/lead_results.html" %}
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/login.html b/padelnomics/src/padelnomics/admin/templates/admin/login.html deleted file mode 100644 index 06bdfdf..0000000 --- a/padelnomics/src/padelnomics/admin/templates/admin/login.html +++ /dev/null @@ -1,29 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Admin Login - {{ config.APP_NAME }}{% endblock %} - -{% block content %} -
-
-

Admin Login

- -
- - -
- - -
- - -
-
-
-{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/scenario_form.html b/padelnomics/src/padelnomics/admin/templates/admin/scenario_form.html index 51e3653..4dd84b1 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/scenario_form.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/scenario_form.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "scenarios" %} {% block title %}{% if editing %}Edit{% else %}New{% endif %} Scenario - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}
← Back to scenarios

{% if editing %}Edit{% else %}New{% endif %} Published Scenario

@@ -179,5 +179,4 @@
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/scenario_preview.html b/padelnomics/src/padelnomics/admin/templates/admin/scenario_preview.html index 5673810..6248931 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/scenario_preview.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/scenario_preview.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "scenarios" %} {% block title %}Preview: {{ scenario.title }} - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}
← Back to scenarios @@ -29,5 +29,4 @@

Returns & Financing

{% include "partials/scenario_returns.html" %}
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/scenarios.html b/padelnomics/src/padelnomics/admin/templates/admin/scenarios.html index 2d6c82d..4c51696 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/scenarios.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/scenarios.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "scenarios" %} {% block title %}Published Scenarios - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

Published Scenarios

@@ -52,5 +52,4 @@

No published scenarios yet.

{% endif %}
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/suppliers.html b/padelnomics/src/padelnomics/admin/templates/admin/suppliers.html index 2a66709..11905bf 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/suppliers.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/suppliers.html @@ -1,8 +1,8 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "suppliers" %} {% block title %}Supplier Management - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

Supplier Management

@@ -59,5 +59,4 @@
{% include "admin/partials/supplier_results.html" %}
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/tasks.html b/padelnomics/src/padelnomics/admin/templates/admin/tasks.html index 57406e1..ef70d41 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/tasks.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/tasks.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "tasks" %} {% block title %}Tasks - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

Task Queue

← Dashboard @@ -106,5 +106,4 @@ {% endif %} -
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/template_data.html b/padelnomics/src/padelnomics/admin/templates/admin/template_data.html index 65105df..a7bbbbb 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/template_data.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/template_data.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "templates" %} {% block title %}Data: {{ template.name }} - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}
← Back to templates @@ -100,5 +100,4 @@

No data rows yet. Add some above or upload a CSV.

{% endif %}
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/template_form.html b/padelnomics/src/padelnomics/admin/templates/admin/template_form.html index 53847b1..fbc174a 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/template_form.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/template_form.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "templates" %} {% block title %}{% if editing %}Edit{% else %}New{% endif %} Article Template - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}
← Back to templates

{% if editing %}Edit{% else %}New{% endif %} Article Template

@@ -67,5 +67,4 @@
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/templates.html b/padelnomics/src/padelnomics/admin/templates/admin/templates.html index a26808b..75561f1 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/templates.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/templates.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "templates" %} {% block title %}Article Templates - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

Article Templates

@@ -48,5 +48,4 @@

No templates yet. Create one to get started.

{% endif %}
-
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/user_detail.html b/padelnomics/src/padelnomics/admin/templates/admin/user_detail.html index 33fc187..e9a3dff 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/user_detail.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/user_detail.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "users" %} {% block title %}User: {{ user.email }} - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

{{ user.email }}

← Users @@ -55,10 +55,10 @@
Status
{{ user.sub_status or 'N/A' }}
- {% if user.paddle_customer_id %} + {% if user.provider_customer_id %}
Paddle Customer
-
{{ user.paddle_customer_id }}
+
{{ user.provider_customer_id }}
{% endif %} @@ -73,5 +73,4 @@ -
{% endblock %} diff --git a/padelnomics/src/padelnomics/admin/templates/admin/users.html b/padelnomics/src/padelnomics/admin/templates/admin/users.html index 3e2b562..f7d661d 100644 --- a/padelnomics/src/padelnomics/admin/templates/admin/users.html +++ b/padelnomics/src/padelnomics/admin/templates/admin/users.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "admin/base_admin.html" %} +{% set admin_page = "users" %} {% block title %}Users - Admin - {{ config.APP_NAME }}{% endblock %} -{% block content %} -
+{% block admin_content %}

Users

← Dashboard @@ -74,5 +74,4 @@

No users found.

{% endif %} -
{% endblock %} diff --git a/padelnomics/src/padelnomics/app.py b/padelnomics/src/padelnomics/app.py index c871ae1..9a55f7e 100644 --- a/padelnomics/src/padelnomics/app.py +++ b/padelnomics/src/padelnomics/app.py @@ -46,14 +46,40 @@ def create_app() -> Quart: response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains" return response - # Load current user before each request + # Load current user + subscription + roles before each request @app.before_request async def load_user(): g.user = None + g.subscription = None user_id = session.get("user_id") if user_id: - from .auth.routes import get_user_by_id - g.user = await get_user_by_id(user_id) + from .core import fetch_one as _fetch_one + row = await _fetch_one( + """SELECT u.*, + bc.provider_customer_id, + (SELECT GROUP_CONCAT(role) FROM user_roles WHERE user_id = u.id) AS roles_csv, + s.id AS sub_id, s.plan, s.status AS sub_status, + s.provider_subscription_id, s.current_period_end + FROM users u + LEFT JOIN billing_customers bc ON bc.user_id = u.id + LEFT JOIN subscriptions s ON s.id = ( + SELECT id FROM subscriptions + WHERE user_id = u.id + ORDER BY created_at DESC LIMIT 1 + ) + WHERE u.id = ? AND u.deleted_at IS NULL""", + (user_id,), + ) + if row: + g.user = dict(row) + g.user["roles"] = row["roles_csv"].split(",") if row["roles_csv"] else [] + if row["sub_id"]: + g.subscription = { + "id": row["sub_id"], "plan": row["plan"], + "status": row["sub_status"], + "provider_subscription_id": row["provider_subscription_id"], + "current_period_end": row["current_period_end"], + } # Template context globals @app.context_processor @@ -62,6 +88,8 @@ def create_app() -> Quart: return { "config": config, "user": g.get("user"), + "subscription": g.get("subscription"), + "is_admin": "admin" in (g.get("user") or {}).get("roles", []), "now": datetime.utcnow(), "csrf_token": get_csrf_token, } diff --git a/padelnomics/src/padelnomics/auth/routes.py b/padelnomics/src/padelnomics/auth/routes.py index c1d8501..a37dcf7 100644 --- a/padelnomics/src/padelnomics/auth/routes.py +++ b/padelnomics/src/padelnomics/auth/routes.py @@ -103,6 +103,74 @@ def login_required(f): return decorated +def role_required(*roles): + """Require user to have at least one of the given roles.""" + def decorator(f): + @wraps(f) + async def decorated(*args, **kwargs): + if not g.get("user"): + await flash("Please sign in to continue.", "warning") + return redirect(url_for("auth.login", next=request.path)) + user_roles = g.user.get("roles", []) + if not any(r in user_roles for r in roles): + await flash("You don't have permission to access that page.", "error") + return redirect(url_for("dashboard.index")) + return await f(*args, **kwargs) + return decorated + return decorator + + +async def grant_role(user_id: int, role: str) -> None: + """Grant a role to a user (idempotent).""" + await execute( + "INSERT OR IGNORE INTO user_roles (user_id, role) VALUES (?, ?)", + (user_id, role), + ) + + +async def revoke_role(user_id: int, role: str) -> None: + """Revoke a role from a user.""" + await execute( + "DELETE FROM user_roles WHERE user_id = ? AND role = ?", + (user_id, role), + ) + + +async def ensure_admin_role(user_id: int, email: str) -> None: + """Grant admin role if email is in ADMIN_EMAILS.""" + if email.lower() in config.ADMIN_EMAILS: + await grant_role(user_id, "admin") + + +def subscription_required( + plans: list[str] = None, + allowed: tuple[str, ...] = ("active", "on_trial", "cancelled"), +): + """Require active subscription, optionally of specific plan(s) and/or statuses. + + Reads from g.subscription (eager-loaded in load_user) — zero extra queries. + """ + def decorator(f): + @wraps(f) + async def decorated(*args, **kwargs): + if not g.get("user"): + await flash("Please sign in to continue.", "warning") + return redirect(url_for("auth.login")) + + sub = g.get("subscription") + if not sub or sub["status"] not in allowed: + await flash("Please subscribe to access this feature.", "warning") + return redirect(url_for("billing.pricing")) + + if plans and sub["plan"] not in plans: + await flash(f"This feature requires a {' or '.join(plans)} plan.", "warning") + return redirect(url_for("billing.pricing")) + + return await f(*args, **kwargs) + return decorated + return decorator + + # ============================================================================= # Routes # ============================================================================= @@ -209,9 +277,12 @@ async def verify(): # Set session session.permanent = True session["user_id"] = token_data["user_id"] - + + # Auto-grant admin role if email is in ADMIN_EMAILS + await ensure_admin_role(token_data["user_id"], token_data["email"]) + await flash("Successfully signed in!", "success") - + # Redirect to intended page or dashboard next_url = request.args.get("next", url_for("dashboard.index")) return redirect(next_url) @@ -249,7 +320,10 @@ async def dev_login(): session.permanent = True session["user_id"] = user_id - + + # Auto-grant admin role if email is in ADMIN_EMAILS + await ensure_admin_role(user_id, email) + await flash(f"Dev login as {email}", "success") return redirect(url_for("dashboard.index")) diff --git a/padelnomics/src/padelnomics/billing/templates/pricing.html b/padelnomics/src/padelnomics/billing/templates/pricing.html index 3ff8e07..7f9a5f1 100644 --- a/padelnomics/src/padelnomics/billing/templates/pricing.html +++ b/padelnomics/src/padelnomics/billing/templates/pricing.html @@ -1,5 +1,11 @@ {% extends "base.html" %} -{% block title %}Free Financial Planner - {{ config.APP_NAME }}{% endblock %} +{% block title %}Free Padel Court Financial Planner - {{ config.APP_NAME }}{% endblock %} + +{% block head %} + + + +{% endblock %} {% block content %}
diff --git a/padelnomics/src/padelnomics/content/templates/article_detail.html b/padelnomics/src/padelnomics/content/templates/article_detail.html index b886bf1..51f7e65 100644 --- a/padelnomics/src/padelnomics/content/templates/article_detail.html +++ b/padelnomics/src/padelnomics/content/templates/article_detail.html @@ -10,7 +10,28 @@ {% if article.og_image_url %} {% endif %} - + {% endblock %} {% block content %} diff --git a/padelnomics/src/padelnomics/content/templates/markets.html b/padelnomics/src/padelnomics/content/templates/markets.html index 8715a11..2e5ceab 100644 --- a/padelnomics/src/padelnomics/content/templates/markets.html +++ b/padelnomics/src/padelnomics/content/templates/markets.html @@ -6,7 +6,6 @@ - {% endblock %} {% block content %} diff --git a/padelnomics/src/padelnomics/core.py b/padelnomics/src/padelnomics/core.py index 7c87217..2fb21fd 100644 --- a/padelnomics/src/padelnomics/core.py +++ b/padelnomics/src/padelnomics/core.py @@ -54,6 +54,9 @@ class Config: RESEND_API_KEY: str = os.getenv("RESEND_API_KEY", "") EMAIL_FROM: str = _env("EMAIL_FROM", "hello@padelnomics.io") ADMIN_EMAIL: str = _env("ADMIN_EMAIL", "leads@padelnomics.io") + ADMIN_EMAILS: list[str] = [ + e.strip().lower() for e in os.getenv("ADMIN_EMAILS", "").split(",") if e.strip() + ] RESEND_AUDIENCE_PLANNER: str = os.getenv("RESEND_AUDIENCE_PLANNER", "") RATE_LIMIT_REQUESTS: int = int(os.getenv("RATE_LIMIT_REQUESTS", "100")) diff --git a/padelnomics/src/padelnomics/dashboard/routes.py b/padelnomics/src/padelnomics/dashboard/routes.py index 4a87884..bba5ec6 100644 --- a/padelnomics/src/padelnomics/dashboard/routes.py +++ b/padelnomics/src/padelnomics/dashboard/routes.py @@ -35,6 +35,14 @@ async def get_user_stats(user_id: int) -> dict: @bp.route("/") @login_required async def index(): + # Supplier users go straight to the supplier dashboard + supplier = await fetch_one( + "SELECT id FROM suppliers WHERE claimed_by = ? AND tier IN ('growth', 'pro')", + (g.user["id"],), + ) + if supplier: + return redirect(url_for("suppliers.dashboard")) + stats = await get_user_stats(g.user["id"]) return await render_template("index.html", stats=stats) diff --git a/padelnomics/src/padelnomics/directory/routes.py b/padelnomics/src/padelnomics/directory/routes.py index 6e53258..e045540 100644 --- a/padelnomics/src/padelnomics/directory/routes.py +++ b/padelnomics/src/padelnomics/directory/routes.py @@ -4,7 +4,7 @@ Supplier directory: public, searchable listing of padel court suppliers. from datetime import UTC, datetime from pathlib import Path -from quart import Blueprint, redirect, render_template, request, url_for +from quart import Blueprint, make_response, redirect, render_template, request, url_for from ..core import csrf_protect, execute, fetch_all, fetch_one @@ -322,4 +322,6 @@ async def results(): page = max(1, int(request.args.get("page", "1") or "1")) ctx = await _build_directory_query(q, country, category, region, page) - return await render_template("partials/results.html", **ctx) + resp = await make_response(await render_template("partials/results.html", **ctx)) + resp.headers["X-Robots-Tag"] = "noindex" + return resp diff --git a/padelnomics/src/padelnomics/directory/templates/directory.html b/padelnomics/src/padelnomics/directory/templates/directory.html index 7a12f50..496fc47 100644 --- a/padelnomics/src/padelnomics/directory/templates/directory.html +++ b/padelnomics/src/padelnomics/directory/templates/directory.html @@ -4,6 +4,8 @@ {% block head %} + + {% endblock %} {% block content %} -
- -
+ +
+
🎾 Padel court financial planner
-

Plan Your Padel
Business in Minutes,
Not Months

+

+ Plan Your Padel
+ Business in Minutes,
+ Not Months +

- Model your padel court investment with 60+ variables, sensitivity analysis, and professional-grade projections. Then get matched with verified suppliers. + Model your padel court investment with 60+ variables, sensitivity analysis, + and professional-grade projections. Then get matched with verified suppliers.

No signup required @@ -154,19 +283,19 @@
-
+
Investment
€330K
-
+
Monthly Cash Flow
€7K
-
+
Payback Period
3.9 yr
-
+
Annual ROI
26%
@@ -175,31 +304,38 @@ Plan Your Padel Business →
-
+ +
- -
-

Your Journey

-
-
-

🔍 Explore Coming Soon

-

Market demand analysis, whitespace mapping, location scoring. Is padel viable in your area?

+
+ +
+

Your Journey

+
+
+
01
+

Explore Soon

+

Market demand analysis, whitespace mapping, location scoring.

-
-

📊 Plan

-

Model your investment with our financial planner. CAPEX, operating costs, cash flow, returns, sensitivity analysis.

+
+
02
+

Plan

+

Model your investment with 60+ variables, charts, and sensitivity analysis.

-
-

💰 Finance Coming Soon

-

Connect with banks and investors experienced in sports facility loans. Your planner data becomes your business case.

+
+
03
+

Finance Soon

+

Connect with banks and investors. Your planner becomes your business case.

-
-

🏗️ Build

-

Browse {{ total_suppliers }}+ court suppliers across {{ total_countries }} countries. Get matched based on your project specs.

+
+
04
+

Build

+

Browse {{ total_suppliers }}+ court suppliers across {{ total_countries }} countries. Get matched to your specs.

-
-

📈 Grow Coming Soon

-

Launch playbook, performance benchmarking, operational KPIs, and expansion analytics for your venue.

+
+
05
+

Grow Soon

+

Launch playbook, performance benchmarks, and expansion analytics.

@@ -281,7 +417,7 @@
Is the supplier directory free? -

Browsing the directory is free for everyone. Suppliers have a basic listing by default. Paid plans (Growth at €149/mo, Pro at €399/mo) unlock full descriptions, logos, verified badges, and priority placement.

+

Browsing the directory is free for everyone. Suppliers have a basic listing by default. Paid plans (Basic at €39/mo, Growth at €199/mo, Pro at €499/mo) unlock enquiry forms, full descriptions, logos, verified badges, and priority placement.

How accurate are the financial projections? @@ -303,11 +439,13 @@
- -
-

Start Planning Today

-

Model your investment, then get matched with verified court suppliers across {{ total_countries }} countries.

- Plan Your Padel Business + +
+
+

Start Planning Today

+

Model your investment, then get matched with verified court suppliers across {{ total_countries }} countries.

+ Plan Your Padel Business → +
{% endblock %} @@ -379,4 +517,62 @@ update(); })(); + + {% endblock %} diff --git a/padelnomics/src/padelnomics/public/templates/privacy.html b/padelnomics/src/padelnomics/public/templates/privacy.html index 26a2653..4ce3d6e 100644 --- a/padelnomics/src/padelnomics/public/templates/privacy.html +++ b/padelnomics/src/padelnomics/public/templates/privacy.html @@ -2,6 +2,10 @@ {% block title %}Privacy Policy - {{ config.APP_NAME }}{% endblock %} +{% block head %} + +{% endblock %} + {% block content %}
diff --git a/padelnomics/src/padelnomics/public/templates/suppliers.html b/padelnomics/src/padelnomics/public/templates/suppliers.html index 9212234..d4cba2b 100644 --- a/padelnomics/src/padelnomics/public/templates/suppliers.html +++ b/padelnomics/src/padelnomics/public/templates/suppliers.html @@ -3,13 +3,16 @@ {% block title %}For Suppliers - Reach Padel Entrepreneurs | {{ config.APP_NAME }}{% endblock %} {% block head %} - + {% endblock %} {% block content %}
+ +
-

Reach Entrepreneurs
Actively Planning Padel Projects

-

Padelnomics connects you with qualified leads who've already modeled their investment. No cold outreach. No wasted time.

- See Plans +

Stop Chasing Cold Leads.
Meet Buyers Who Already Have a Business Plan.

+

Every lead on Padelnomics has modeled their CAPEX, projected revenue, and calculated ROI — before they contact you. No tire-kickers. No “just browsing.”

+ See Plans & Pricing +

Trusted by suppliers in {{ total_countries }} countries

@@ -207,6 +278,32 @@
+ +
+
+

The Problem With Finding Padel Clients Today

+

Most channels waste your time and budget before you talk to a single serious buyer.

+
+
+
€10K+
+

Trade Shows

+

Per event. You meet hundreds of people. Maybe 3 are serious about building a padel facility.

+
+
+
€20–80
+

Google Ads

+

Per click. Most visitors are researching padel, not ready to spend €300K+ on a construction project.

+
+
+
<2%
+

Cold Outreach

+

Response rate. Hours of emails and calls to reach entrepreneurs who aren’t ready to buy yet.

+
+
+

What if every lead came with a complete project brief and a financial model?

+
+
+

How It Works

@@ -214,18 +311,18 @@
1
-

Choose Your Plan

-

Your company is already in our directory. Pick a plan to upgrade your listing and start receiving leads.

+

Claim Your Listing

+

Your company is already in our directory. Pick a plan to upgrade your listing and unlock access to the lead feed.

2
-

Unlock Leads with Credits

-

Browse verified leads in your region. Spend credits to unlock full project details and contact info.

+

Browse Pre-Qualified Leads

+

Every lead includes project specs, budget, timeline, and a financial model they built themselves. Spend credits only on leads that match your services.

3
-

Close Deals

-

You receive pre-qualified leads with full project details: venue type, court count, budget, timeline, and more.

+

Win Projects Faster

+

Contact the entrepreneur directly. You already know their budget, timeline, and financing status — no discovery call needed.

@@ -328,7 +425,7 @@

Pre-Qualified

-

Leads come through our financial planner. They've modeled CAPEX, revenue, and ROI before contacting you.

+

Leads come through our financial planner. They’ve modeled CAPEX, revenue, and ROI before contacting you.

Full Project Brief

@@ -343,22 +440,60 @@
+ + + +

Plans & Pricing

Choose the plan that fits your growth goals.

+ +
+ + +
+
+ +
+

Basic

+
+
€39 /mo
+
+
+
€29 /mo
+ €349 billed yearly +
+
Directory listing
+
    +
  • Verified ✓ badge
  • +
  • Company logo
  • +
  • Full description & tagline
  • +
  • Website & contact details
  • +
  • Services offered checklist
  • +
  • Enquiry form on listing page
  • +
+ Get Listed +
+

Growth

-
€199 /mo
+
+
€199 /mo
+
+
+
€150 /mo
+ €1,799 billed yearly +
30 credits/mo included
    -
  • Company name & category badge
  • -
  • City & country shown
  • -
  • Description visible
  • -
  • "Growth" badge
  • -
  • Priority over free listings
  • +
  • Everything in Basic
  • Access to lead feed
  • +
  • “Growth” badge on listing
  • +
  • Priority over free listings
  • +
  • 30 lead credits per month
  • +
  • Buy additional credit packs
Get Started
@@ -366,15 +501,21 @@

Pro

-
€499 /mo
+
+
€499 /mo
+
+
+
€375 /mo
+ €4,499 billed yearly +
100 credits/mo included
  • Everything in Growth
  • -
  • Logo & cover photo
  • +
  • Cover photo on listing
  • Full stats (projects, years, area)
  • -
  • Verified ✓ badge
  • Featured card border & glow
  • -
  • Priority placement
  • +
  • Priority placement in directory
  • +
  • 100 lead credits per month
Get Started
@@ -407,13 +548,83 @@
+ +
+

How We Compare

+

Your prospects are already weighing these alternatives. Here’s the honest comparison.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Padelnomics GrowthTrade Show BoothGoogle AdsCold Directory
Annual cost€1,799/yr€10,000+/event€5,000+/yr*€600/yr
Lead qualityPre-qualified with business planMixed, mostly browsingCold, searchingNone (listing only)
Leads included30 credits/moPay per click
Project detailsFull specs + financial modelBusiness cards onlyNoneNone
Time to first leadSame dayMonths awayDaysNever
Matches your services✓ Filtered by category
+
+

*Google Ads estimate based on €20–80 CPC for padel construction keywords at 5–10 clicks/day.

+
+

Trusted by Padel Industry Leaders

-

Suppliers across {{ total_countries }} countries use Padelnomics to reach new customers.

-
-
"Padelnomics sends us leads that are already serious about building. The project briefs are more detailed than what we get from trade shows."
- — European padel court manufacturer +

{{ calc_requests }}+ business plans created · {{ total_suppliers }}+ suppliers · {{ total_countries }} countries

+
+
+
“Padelnomics sends us leads that are already serious about building. The project briefs are more detailed than what we get from trade shows.”
+ — European padel court manufacturer +
+
+
“Finally a platform that understands the padel construction market. We know the budget, the timeline, and the venue type before we even make first contact.”
+ — Padel court installation company, Scandinavia +
@@ -423,11 +634,19 @@
How do I claim my listing? -

Find your company in our directory and click "Is this your company?" We'll verify your identity and give you access to choose a plan and upgrade your profile.

+

Find your company in our directory and click “Is this your company?” We’ll verify your identity and give you access to choose a plan and upgrade your profile.

How much does it cost? -

We offer two plans: Growth (€149/mo, 30 credits) with description, badge, and priority placement; and Pro (€399/mo, 100 credits) with logo, website, verified badge, and maximum visibility. Optional boost add-ons are available on top.

+

We offer three plans: Basic (€39/mo) for a verified directory listing with enquiry form; Growth (€199/mo, 30 credits) with full lead access and priority placement; and Pro (€499/mo, 100 credits) for maximum visibility and lead volume. Yearly billing saves up to 26% — Basic at €349/yr, Growth at €1,799/yr, Pro at €4,499/yr. Optional boost add-ons are available on top.

+
+
+ What makes Padelnomics leads different from other platforms? +

Every lead on Padelnomics has used our financial planning tool to model their project — CAPEX, revenue projections, ROI, and debt service coverage — before reaching out. This means they’re serious, they have a realistic budget, and they’re ready to talk to suppliers. You’re not getting cold enquiries; you’re getting pre-qualified project briefs.

+
+
+ How does pricing compare to alternatives? +

A trade show booth costs €10,000+ per event and delivers mostly browsing contacts. Google Ads for padel construction keywords run €20–80 per click — that’s €5,000+/yr before you talk to a single prospect. A typical cold directory listing charges ~€600/yr with no leads at all. Padelnomics Growth at €1,799/yr includes 30 lead credits per month with full project briefs.

How do credits work? @@ -443,24 +662,25 @@
Which countries do you cover? -

Padelnomics has suppliers listed across {{ total_countries }} countries. Our strongest coverage is in Europe (Germany, Spain, Sweden, UK, Netherlands, Italy) but we're growing globally as padel expands.

+

Padelnomics has suppliers listed across {{ total_countries }} countries. Our strongest coverage is in Europe (Germany, Spain, Sweden, UK, Netherlands, Italy) but we’re growing globally as padel expands.

Can I cancel anytime?

Yes. You can cancel your subscription at any time from your dashboard. Your listing stays active until the end of the current billing period. Unused credits are forfeited upon cancellation.

- My company isn't listed. How do I get added? -

Email us at {{ config.ADMIN_EMAIL }} with your company details and we'll add you to the directory within 48 hours.

+ My company isn’t listed. How do I get added? +

Email us at {{ config.ADMIN_EMAIL }} with your company details and we’ll add you to the directory within 48 hours.

-

Ready to Receive Qualified Leads?

-

Choose a plan and start getting matched with padel entrepreneurs today.

- See Plans +

Your Next Client Is Already Building a Business Plan

+

They’ve modeled the ROI. They know their budget. They’re looking for a supplier like you.

+ See Plans & Pricing
+
{% endblock %} diff --git a/padelnomics/src/padelnomics/public/templates/terms.html b/padelnomics/src/padelnomics/public/templates/terms.html index c99d9dd..6269cc9 100644 --- a/padelnomics/src/padelnomics/public/templates/terms.html +++ b/padelnomics/src/padelnomics/public/templates/terms.html @@ -2,6 +2,10 @@ {% block title %}Terms of Service - {{ config.APP_NAME }}{% endblock %} +{% block head %} + +{% endblock %} + {% block content %}
diff --git a/padelnomics/src/padelnomics/scripts/seed_dev_data.py b/padelnomics/src/padelnomics/scripts/seed_dev_data.py index f63b708..462dbd6 100644 --- a/padelnomics/src/padelnomics/scripts/seed_dev_data.py +++ b/padelnomics/src/padelnomics/scripts/seed_dev_data.py @@ -368,6 +368,17 @@ def main(): (owner_id, now.isoformat(), sid), ) + # Create billing customer record + existing_bc = conn.execute( + "SELECT id FROM billing_customers WHERE user_id = ?", (owner_id,) + ).fetchone() + if not existing_bc: + conn.execute( + """INSERT INTO billing_customers (user_id, provider_customer_id, created_at) + VALUES (?, ?, ?)""", + (owner_id, f"ctm_dev_{slug}", now.isoformat()), + ) + # Create active subscription existing_sub = conn.execute( "SELECT id FROM subscriptions WHERE user_id = ?", (owner_id,) @@ -375,10 +386,10 @@ def main(): if not existing_sub: conn.execute( """INSERT INTO subscriptions - (user_id, plan, status, paddle_customer_id, paddle_subscription_id, + (user_id, plan, status, provider_subscription_id, current_period_end, created_at) - VALUES (?, ?, 'active', ?, ?, ?, ?)""", - (owner_id, plan, f"ctm_dev_{slug}", f"sub_dev_{slug}", + VALUES (?, ?, 'active', ?, ?, ?)""", + (owner_id, plan, f"sub_dev_{slug}", period_end, now.isoformat()), ) print(f" {slug} -> owner {email} ({plan})") @@ -465,8 +476,8 @@ def main(): conn.close() print(f"\nDone! Seed data written to {db_path}") - print(" Login: dev@localhost (use magic link or admin impersonation)") - print(" Admin: /admin with password 'admin'") + print(" Login: /auth/dev-login?email=dev@localhost") + print(" Admin: set ADMIN_EMAILS=dev@localhost in .env, then dev-login grants admin role") if __name__ == "__main__": diff --git a/padelnomics/src/padelnomics/static/css/input.css b/padelnomics/src/padelnomics/static/css/input.css index e140857..a2f72cc 100644 --- a/padelnomics/src/padelnomics/static/css/input.css +++ b/padelnomics/src/padelnomics/static/css/input.css @@ -18,7 +18,8 @@ /* ── Brand Theme ── */ @theme { - --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif; + --font-display: "Bricolage Grotesque", ui-sans-serif, system-ui, sans-serif; + --font-sans: "DM Sans", ui-sans-serif, system-ui, -apple-system, sans-serif; --font-mono: "Commit Mono", ui-monospace, monospace; --color-navy: #0F172A; @@ -26,6 +27,7 @@ --color-electric: #1D4ED8; --color-electric-hover: #1E40AF; --color-accent: #16A34A; + --color-forest: #064E3B; --color-soft-white: #F8FAFC; --color-light-gray: #E2E8F0; --color-mid-gray: #CBD5E1; @@ -42,6 +44,7 @@ @apply bg-soft-white text-slate-dark font-sans antialiased; } h1, h2, h3 { + font-family: var(--font-display); @apply text-navy font-bold tracking-tight; } h4, h5, h6 { @@ -62,8 +65,10 @@ position: sticky; top: 0; z-index: 50; - background: #ffffff; - border-bottom: 1px solid #E2E8F0; + background: rgba(255, 255, 255, 0.82); + backdrop-filter: blur(14px); + -webkit-backdrop-filter: blur(14px); + border-bottom: 1px solid rgba(226, 232, 240, 0.7); } .nav-inner { max-width: 72rem; diff --git a/padelnomics/src/padelnomics/static/css/planner.css b/padelnomics/src/padelnomics/static/css/planner.css index 4b7a57d..852a784 100644 --- a/padelnomics/src/padelnomics/static/css/planner.css +++ b/padelnomics/src/padelnomics/static/css/planner.css @@ -27,7 +27,7 @@ --cta-bg: #EFF6FF; --cta-glow: rgba(29,78,216,0.10); - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; font-size: 14px; color: var(--txt); background: var(--bg); @@ -51,6 +51,7 @@ gap: 1rem; } .planner-header h1 { + font-family: 'Bricolage Grotesque', sans-serif; font-size: 1.125rem; font-weight: 800; color: var(--head); @@ -71,7 +72,7 @@ font-size: 11px; color: var(--txt-2); margin-left: auto; - font-family: 'JetBrains Mono', monospace; + font-family: 'Commit Mono', ui-monospace, monospace; } /* ── Scenario controls ── */ @@ -88,7 +89,7 @@ background: transparent; color: var(--txt-2); cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; font-weight: 500; transition: all 0.15s; } @@ -118,7 +119,7 @@ color: var(--txt-3); cursor: pointer; white-space: nowrap; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; border-bottom: 2px solid transparent; transition: all 0.15s; } @@ -177,7 +178,7 @@ .metric-card__value { font-size: 22px; font-weight: 700; - font-family: 'JetBrains Mono', monospace; + font-family: 'Commit Mono', ui-monospace, monospace; line-height: 1.2; } .metric-card__sub { @@ -272,7 +273,7 @@ padding: 4px 8px; text-align: right; font-size: 12px; - font-family: 'JetBrains Mono', monospace; + font-family: 'Commit Mono', ui-monospace, monospace; color: var(--head); outline: none; } @@ -330,7 +331,7 @@ color: var(--txt-3); border-radius: 999px; cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; transition: all 0.15s; } .toggle-btn--active { @@ -376,7 +377,7 @@ color: var(--txt-3); border-radius: 999px; cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; transition: all 0.15s; } .pill-btn:hover { @@ -426,11 +427,11 @@ } .data-table td { padding: 6px 8px; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; color: var(--txt); } .data-table td.mono { - font-family: 'JetBrains Mono', monospace; + font-family: 'Commit Mono', ui-monospace, monospace; text-align: right; } .data-table tr:hover { @@ -485,7 +486,7 @@ margin-left: 4px; flex-shrink: 0; font-style: italic; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; vertical-align: middle; } .ti .tp { @@ -684,7 +685,7 @@ font-size: 14px; font-weight: 700; cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; box-shadow: 0 2px 10px rgba(29,78,216,0.25); transition: background 0.15s; } @@ -762,7 +763,7 @@ font-size: 14px; font-weight: 700; cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; box-shadow: 0 2px 10px rgba(29,78,216,0.25); transition: background 0.15s; text-align: center; @@ -788,7 +789,7 @@ font-size: 12px; } .waterfall-row__label { color: var(--txt-2); } -.waterfall-row__value { font-family: 'JetBrains Mono', monospace; font-weight: 600; } +.waterfall-row__value { font-family: 'Commit Mono', ui-monospace, monospace; font-weight: 600; } /* ── Court summary cards ── */ .court-summary { @@ -898,7 +899,7 @@ background: transparent; color: var(--txt-3); cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; transition: all 0.15s; white-space: nowrap; } @@ -946,6 +947,7 @@ display: block; } .wizard-step__title { + font-family: 'Bricolage Grotesque', sans-serif; font-size: 1.25rem; font-weight: 800; color: var(--head); @@ -991,7 +993,7 @@ .wiz-preview__value { font-size: 16px; font-weight: 700; - font-family: 'JetBrains Mono', monospace; + font-family: 'Commit Mono', ui-monospace, monospace; color: var(--head); line-height: 1.4; } @@ -1022,7 +1024,7 @@ color: var(--txt-2); border-radius: 10px; cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; transition: all 0.15s; } .wiz-btn--back:hover { @@ -1039,7 +1041,7 @@ color: #fff; border-radius: 10px; cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; transition: all 0.15s; box-shadow: 0 2px 10px var(--cta-shadow); } @@ -1054,7 +1056,7 @@ border: none; cursor: pointer; text-decoration: underline; - font-family: 'Inter', sans-serif; + font-family: 'DM Sans', sans-serif; padding: 4px; } .wiz-skip:hover { diff --git a/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/dashboard_boosts.html b/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/dashboard_boosts.html index 9b70560..f44482d 100644 --- a/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/dashboard_boosts.html +++ b/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/dashboard_boosts.html @@ -21,7 +21,7 @@ .bst-boost__price { font-size: 0.8125rem; font-weight: 700; color: #1D4ED8; } .bst-boost__status { font-size: 0.6875rem; font-weight: 700; color: #16A34A; } - .bst-credits-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem; } + .bst-credits-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 0.75rem; } .bst-credit-card { border: 1px solid #E2E8F0; border-radius: 10px; padding: 1rem; text-align: center; } @@ -53,7 +53,7 @@ {% set boost_monthly = 0 %}
-
+

Current Plan

diff --git a/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/dashboard_leads.html b/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/dashboard_leads.html index 844bd13..78ad38b 100644 --- a/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/dashboard_leads.html +++ b/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/dashboard_leads.html @@ -23,11 +23,17 @@ .dl-bidders { font-size: 0.6875rem; margin-top: 4px; } .dl-bidders--first { color: #16A34A; font-weight: 600; } .dl-bidders--many { color: #94A3B8; } + .dl-search { + width: 100%; padding: 8px 12px 8px 36px; border: 1px solid #E2E8F0; border-radius: 10px; + font-size: 0.8125rem; font-family: inherit; margin-bottom: 0.75rem; + background: white url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2394A3B8' stroke-width='2'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z'/%3E%3C/svg%3E") no-repeat 10px center; + background-size: 16px; + }

Lead Feed

-
+
{{ supplier.credit_balance }} credits
+ +
@@ -55,15 +68,15 @@ - - + +
@@ -130,7 +143,11 @@ .lf-card { background: white; border: 1px solid #E2E8F0; border-radius: 14px; padding: 1.25rem; transition: box-shadow 0.15s; + border-left: 3px solid #E2E8F0; } + .lf-card:has(.lf-card__heat--hot) { border-left-color: #DC2626; } + .lf-card:has(.lf-card__heat--warm) { border-left-color: #D97706; } + .lf-card:has(.lf-card__heat--cool) { border-left-color: #94A3B8; } .lf-card:hover { box-shadow: 0 4px 16px rgba(0,0,0,0.06); } .lf-card__heat { display: inline-block; font-size: 0.625rem; font-weight: 700; @@ -149,12 +166,15 @@ .lf-unlock-btn { padding: 8px 20px; font-size: 0.75rem; font-weight: 700; border: none; background: #1D4ED8; color: white; border-radius: 8px; cursor: pointer; - font-family: 'Inter', sans-serif; + font-family: inherit; } .lf-unlock-btn:hover { background: #1E40AF; } .lf-card--unlocked { border-color: #BBF7D0; background: #F0FDF4; } .lf-contact { background: #FFFFFF; border: 1px solid #E2E8F0; border-radius: 8px; padding: 0.75rem; margin-top: 0.75rem; } .lf-contact dt { color: #94A3B8; font-size: 0.6875rem; } .lf-contact dd { color: #1E293B; font-weight: 500; margin: 0 0 4px; font-size: 0.8125rem; } + .lf-section { margin-bottom: 0.75rem; padding-bottom: 0.5rem; border-bottom: 1px solid #F1F5F9; } + .lf-section:last-of-type { border-bottom: none; } + .lf-section__title { font-size: 0.625rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: #94A3B8; margin-bottom: 4px; } .lf-error { color: #DC2626; font-size: 0.8125rem; padding: 8px; background: #FEF2F2; border-radius: 8px; text-align: center; } diff --git a/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/lead_card_unlocked.html b/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/lead_card_unlocked.html index 4b74a2c..01620f0 100644 --- a/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/lead_card_unlocked.html +++ b/padelnomics/src/padelnomics/suppliers/templates/suppliers/partials/lead_card_unlocked.html @@ -1,33 +1,74 @@ +{# Human-readable labels for enum values #} +{% set timeline_labels = {'asap': 'ASAP', '3_6_months': '3-6 months', '6_12_months': '6-12 months', '12_plus': '12+ months', 'exploring': 'Exploring'} %} +{% set phase_labels = {'permit_granted': 'Permit granted', 'lease_signed': 'Lease signed', 'permit_pending': 'Permit pending', 'converting_existing': 'Converting existing', 'permit_not_filed': 'Permit not filed', 'location_found': 'Location found', 'searching': 'Searching'} %} +{% set financing_labels = {'self_funded': 'Self-funded', 'loan_approved': 'Loan approved', 'seeking': 'Seeking financing', 'not_started': 'Not started'} %} +{% set decision_labels = {'solo': 'Solo decision-maker', 'partners': 'With partners', 'board': 'Board/committee', 'investor': 'Investor-led'} %} +{% set contact_labels = {'received_quotes': 'Has received quotes', 'contacted': 'Has contacted suppliers', 'none': 'No prior contact'} %} +{% set stakeholder_labels = {'owner': 'Owner/Operator', 'investor': 'Investor', 'developer': 'Property Developer', 'club': 'Club/Association', 'other': 'Other'} %} +
-
+
{{ (lead.heat_score or 'cool') | upper }} ✓ Unlocked
-
-
Facility
-
{{ lead.facility_type or '-' }} ({{ lead.build_context or '-' }})
-
Courts
-
{{ lead.court_count or '-' }} | Glass: {{ lead.glass_type or '-' }} | Lighting: {{ lead.lighting_type or '-' }}
-
Location
-
{{ lead.location or '-' }}, {{ lead.country or '-' }}
-
Timeline
-
{{ lead.timeline or '-' }}
-
Budget
-
{% if lead.budget_estimate %}€{{ lead.budget_estimate }}{% else %}-{% endif %}
-
Phase
-
{{ lead.location_status or '-' }}
-
Financing
-
{{ lead.financing_status or '-' }}
-
Services
-
{{ lead.services_needed or '-' }}
-
+ {# --- Project --- #} +
+
Project
+
+
Facility
+
{{ lead.facility_type or '-' }}{% if lead.build_context %} ({{ lead.build_context }}){% endif %}
+
Courts
+
{{ lead.court_count or '-' }}
+
Glass
+
{{ lead.glass_type or '-' }}
+
Lighting
+
{{ lead.lighting_type or '-' }}
+
Budget
+
{% if lead.budget_estimate %}€{{ lead.budget_estimate }}{% else %}-{% endif %}
+
Services
+
{{ lead.services_needed or '-' }}
+
+
+ + {# --- Location & Timeline --- #} +
+
Location & Timeline
+
+
Location
+
{{ lead.location or '-' }}, {{ lead.country or '-' }}
+
Timeline
+
{{ timeline_labels.get(lead.timeline, lead.timeline) or '-' }}
+
Phase
+
{{ phase_labels.get(lead.location_status, lead.location_status) or '-' }}
+
+
+ + {# --- Readiness --- #} +
+
Readiness
+
+
Financing
+
{{ financing_labels.get(lead.financing_status, lead.financing_status) or '-' }}
+
Wants financing help
+
{{ 'Yes' if lead.wants_financing_help else 'No' }}
+
Decision process
+
{{ decision_labels.get(lead.decision_process, lead.decision_process) or '-' }}
+
Prior supplier contact
+
{{ contact_labels.get(lead.previous_supplier_contact, lead.previous_supplier_contact) or '-' }}
+
+
{% if lead.additional_info %} -

{{ lead.additional_info }}

+
+
Notes
+

{{ lead.additional_info }}

+
{% endif %} + {# --- Contact --- #}
+
Contact
Name
{{ lead.contact_name or '-' }}
@@ -38,11 +79,35 @@
Company
{{ lead.contact_company or '-' }}
Role
-
{{ lead.stakeholder_type or '-' }}
+
{{ stakeholder_labels.get(lead.stakeholder_type, lead.stakeholder_type) or '-' }}
+ {# --- Scenario link --- #} + {% set sid = scenario_id if scenario_id is defined else (scenario_ids.get(lead.user_id) if scenario_ids is defined else none) %} + {% if sid %} +
+ View their plan → + + {% endif %} + {% if credit_cost is defined %}

{{ credit_cost }} credits used · {{ supplier.credit_balance }} remaining

{% endif %}
+ +{% if credit_cost is defined %} +{# OOB: update sidebar credits #} + +{# OOB: update header credits #} +
+ {{ supplier.credit_balance }} credits + Buy More +
+{% endif %} diff --git a/padelnomics/src/padelnomics/templates/base.html b/padelnomics/src/padelnomics/templates/base.html index 82cb624..4c2bf56 100644 --- a/padelnomics/src/padelnomics/templates/base.html +++ b/padelnomics/src/padelnomics/templates/base.html @@ -11,7 +11,10 @@ - + + + + @@ -20,30 +23,41 @@ - + + + + + + + + + + {% block head %}{% endblock %} @@ -56,8 +70,16 @@
- @@ -86,7 +108,7 @@ {% if user %} Dashboard - {% if session.get('is_admin') %} + {% if is_admin %} Admin {% endif %}