Business & Operations

Padel Nation

Source code included

Complete padel court booking, tournament and venue management system for operators and players

Built by Chow Studio Updated 5 Oct 2026 23,739 lines of code

Open live demo Built withClaude Code

Why Padel Nation

What makes it better
than the alternatives

  1. 01

    Four surfaces from one solution

    Four surfaces from one solution

  2. 02

    Split-payment invitations

    Split-payment invitations

  3. 03

    Interactive calendar booking

    Interactive calendar booking

  4. 04

    Server-side price calculation

    Server-side price calculation

  5. 05

    Comprehensive audit and ownership enforcement

    Comprehensive audit and ownership enforcement

Venue & Court Management

  • Padel entity (venue) with name
  • description
  • logo
  • banner
  • address
  • city
  • country
  • status
  • PadelBranch entity (location) with branch name
  • address
  • coordinates
  • gallery images
  • facilities
  • opening hours
  • Court entity with name
  • type
  • surface
  • pricing (30/60/90/120 min rates)
  • status
  • branch assignment
  • BookingSchedule entity defining time slots per branch with start/end times
  • active flag
  • day-of-week support
  • Image upload for venue logos
  • branch galleries and court photos (ImageUploader
  • UploadFolders.Branches
  • max 5MB)
  • Admin screens: Padel/Index (venue list)
  • Padel/Edit (venue form)
  • PadelBranch/Index (branch list with venue filter)
  • PadelBranch/Edit (branch form with gallery)
  • Court/Index (court list)
  • Court/Edit (court form with pricing)

Booking & Availability

  • Invoice entity (booking record) with readable ID
  • member
  • court
  • date
  • time
  • duration
  • status (Pending/Confirmed/Completed/Cancelled)
  • grand total
  • due payment
  • deposit percentage
  • InvoiceTimeSchedule join table linking invoices to court/schedule/date combinations for multi-slot bookings
  • BookingService.CreateBookingAsync recalculates price from court rates and duration
  • applies coupon discounts
  • creates pending-payment shares for invited players
  • BookingService.GetAvailabilityAsync queries booked slots per court/date and returns free time windows
  • BookingService.CancelBookingAsync (member-scoped) and CancelBookingAsAdminAsync (staff) soft-delete invoices and log cancellation comments
  • API endpoints: POST /api/v1/bookings (create)
  • GET /api/v1/bookings (list owner's bookings)
  • POST /api/v1/bookings/{id}/cancel (member cancellation)
  • Admin screens: Booking/Index (list with status tabs: pending/confirmed/completed/cancelled)
  • Booking/Details (invoice detail with players)
  • Calendar/Index (interactive day-view grid)

Member Authentication & Sessions

  • Member entity with phone (unique)
  • full name
  • email
  • password hash
  • security stamp
  • IsRegistered flag
  • status (Active/Inactive/Suspended)
  • city
  • country
  • picture
  • OTP code/expiry
  • AuthService.MemberRegisterAsync validates phone format and password policy
  • creates member with hashed password
  • issues JWT token
  • AuthService.MemberLoginAsync verifies phone/password
  • checks account status
  • returns MemberSessionDto with token and expiry
  • JwtTokenService issues bearer tokens with member ID
  • phone
  • security stamp claims; tokens expire after 720 hours (configurable Jwt:ExpiryHours)
  • ApiControllerBase.CurrentMemberId extracts member ID from JWT claims; every API action inherits Member policy (bearer token required)
  • gp-auth.js client session manager stores token in localStorage
  • auto-attaches Authorization header to /api/v1 calls
  • clears session on 401 and fires padelnation:signed-out event
  • API endpoints: POST /api/v1/members/register
  • POST /api/v1/members/login
  • GET /api/v1/members/me (token validation)

Split Payments & Invitations

  • PendingPayment entity with invoice
  • member
  • amount
  • status
  • payment date
  • created/updated timestamps
  • BookingService.CreateBookingAsync accepts invitedPlayerIds array
  • calculates per-player share (grand total ÷ player count)
  • creates PendingPayment records for each invited player
  • AuthService.ResolveMemberByPhoneAsync creates unregistered member stub (no password
  • IsRegistered=false) if phone not found
  • so invitations work before invitee registers
  • AuthService.SuggestContactsAsync returns type-ahead results limited to requester's shared bookings/tournaments plus exact phone match (prevents directory browsing)
  • API rate limit: member-resolve endpoint limited to 10 calls per member per hour (RateLimitPolicies.MemberResolve
  • partitioned by member ID)
  • Member/Details admin screen shows PendingShares list (payments owed by this member as invited player)

Coupons & Discounts

  • Coupon entity with code (unique)
  • title
  • description
  • discount type (Percentage/FixedAmount)
  • discount value
  • start/end dates
  • usage limit
  • used count
  • status
  • CouponService.ValidateCouponAsync checks code existence
  • active status
  • date range
  • usage limit
  • returns discount amount
  • BookingService.CreateBookingAsync applies coupon discount to subtotal before calculating grand total and deposit
  • Admin screens: Coupon/Index (list with tabs: active/scheduled/expired/inactive)
  • Coupon/Edit (form with date pickers and discount type selector)
  • API endpoint: GET /api/v1/coupons/validate?code=X returns discount details or error message

Tournaments

  • Tournament entity with name
  • description
  • image
  • start/end dates
  • registration deadline
  • max teams
  • entry fee
  • prize pool
  • status
  • branch assignment
  • TournamentTeam entity with tournament
  • team name
  • captain member
  • status
  • registration date
  • TournamentTeamMember join table linking teams to member rosters
  • TournamentStage entity (groups
  • knockout rounds) with stage name
  • type
  • order
  • TournamentFixture entity with stage
  • home/away teams
  • match date/time
  • court
  • score
  • status (Scheduled/InProgress/Completed/Cancelled)
  • TournamentService.RegisterTeamAsync validates registration deadline
  • team limit
  • creates team and roster entries
  • TournamentService.GetTournamentDetailsAsync returns tournament with stages
  • fixtures
  • teams and results
  • Admin screens: Tournament/Index (list)
  • Tournament/Edit (form with image upload)
  • Tournament/Details (stages/fixtures/teams)
  • API endpoints: GET /api/v1/tournaments (list)
  • GET /api/v1/tournaments/{id} (detail)
  • POST /api/v1/tournaments/{id}/register (team registration)

Admin Console & Roles

  • User entity with username
  • full name
  • email
  • password hash
  • role
  • IsAdminUser flag
  • status
  • Role entity with name
  • permissions JSON (not enforced in code
  • placeholder for future granular permissions)
  • AdminArea policy requires Admin or Staff role (cookie authentication
  • CookieAuthenticationDefaults.AuthenticationScheme)
  • AdminOnly policy requires Admin role; applied to User/Role/Setting controllers and every Delete action
  • AdminMutationAuditFilter logs every POST/PUT/DELETE in Admin area to AuditLog table (user ID
  • action
  • controller
  • timestamp
  • IP address)
  • Admin screens: Dashboard/Index (stats cards
  • recent bookings
  • revenue trend
  • status breakdown)
  • User/Index (user list)
  • User/Edit (user form)
  • Role/Index (role list)
  • Role/Edit (role form)
  • AuthController.Login (POST with rate limit)
  • AuthController.Logout (POST with anti-forgery token)

Reports & Analytics

  • DashboardService.GetStatsAsync returns total bookings
  • revenue
  • active members
  • active courts for current month
  • DashboardService.GetRevenueTrendAsync returns daily revenue for last N days
  • ReportService.GetSalesReportAsync (date range
  • branch filter) returns bookings with invoice details
  • member names
  • payment status
  • ReportService.GetCommissionReportAsync calculates venue/branch commission from GrandTotal and CommissionPercentage
  • ReportService.GetPadelCalendarReportAsync returns bookings per court/date for calendar heatmap
  • ReportService.GetProductReportAsync groups bookings by court and sums revenue
  • ReportService.GetTrainerReportAsync groups bookings by trainer (if assigned) and sums sessions/revenue
  • ReportService.GetPaymentMethodReportAsync groups invoices by payment method and sums totals
  • Admin screens: Report/Sales
  • Report/Commission
  • Report/PadelCalendar
  • Report/Products
  • Report/Trainers
  • Report/PaymentMethods (all with date/branch filters and export buttons)

Password Reset & Email

  • PasswordResetService.RequestAsync generates single-use token (HMACSHA256 of account kind
  • ID
  • password hash
  • expiry)
  • sends email with reset link
  • PasswordResetService.ResetConfirmedAsync validates token
  • checks expiry (default 60 minutes)
  • hashes new password
  • updates account
  • invalidates token by changing security stamp
  • SmtpEmailSender sends emails via configured SMTP (host
  • port
  • secure flag
  • user
  • password
  • from address in appsettings.json or environment variables)
  • Three surfaces: Admin/Auth/ForgotPassword (admin users)
  • Website/MemberPassword (website members)
  • App password-reset screen (PWA members)
  • PasswordResetAccountKind enum (Admin/Member) and PasswordResetSurface enum (Admin/Website/App) determine link destination
  • Rate limit: password-reset endpoints limited to 5 requests per IP per 15 minutes (RateLimitPolicies.PasswordReset)
  • API endpoints: POST /api/v1/members/forgot-password
  • GET /api/v1/members/reset-password/validate?token=X
  • POST /api/v1/members/reset-password

Progressive Web App

  • manifest.webmanifest with app name
  • icons (192×192
  • 512×512)
  • start_url=/app
  • display=standalone
  • theme/background colors
  • Service worker (sw.js) caches app shell (HTML
  • CSS
  • JS
  • icons) for offline access
  • serves cached shell on network failure
  • offline.html fallback page shown when network unavailable and requested page not cached
  • App/Index.cshtml renders mobile-first booking interface with venue search
  • availability grid
  • booking form
  • gp-auth.js session manager works identically in website and PWA (same localStorage key
  • same JWT token)
  • Installable on iOS (Add to Home Screen) and Android (install prompt)

Quality report

Manually reviewed

93/ 100

Automated audit score

◷ 1 open warning

Passed the audit and a manual review.
Audit run: 5 Oct 2026
Reviewed by Vibe96 staff, Dubai.

Security95
Code structure82
Docs & completeness100
Dependency health95
Build & deploy92

What to know before you buy

1 non-blocking finding shown publicly: weak default jwt key and sql password in example files; no real credentials found; strong authentication and role guards; missing ownership checks on member reads; moderate code duplication and some oversized files; structure generally sound; multiple unindexed foreign keys, missing where clauses, and schema gaps. The seller has been notified; fixes ship in the next version.

Versions & updates

1.0.0
First release5 Oct 2026✓ Reviewed & audited

No updates yet. New versions appear here with a changelog.
Buyers receive updates free for 1 year.

Quality report

What you get

  • </>Full source codeThe complete audited source, delivered as a download from your account. No obfuscation.
  • ▤DocumentationSetup guide, architecture notes, CLAUDE.md and AGENTS.md.
  • ↻One year of updatesEvery new version the builder publishes, free for 12 months.
  • ♧30 days of supportInstallation and defect support through Vibe96 tickets.
$98Single-site licence Details