Please wait...
{{ slide.caption }}

{{ settings.page_tagline || 'Dominance Starts On The Court.' }}

Select a branch, pick your court and time, choose your payment option, and secure your slot — all on this page.

Find Your Booking

Enter your reference number to view booking details and payment QR codes.

{{ verifierError }}
{{ verifierBookings[0].booking_ref || verifierBookings[0].id }}
{{ verifierBookings[0].court_name }} · {{ formatDateMDY(verifierBookings[0].booking_date) }} · {{ formatTime12(verifierBookings[0].start_time) }} – {{ formatTime12(verifierBookings[0].end_time) }}
{{ verifierBookings.length }} Reservations
{{ verifierBookings[0].status }}
{{ b.court_name }} · {{ formatDateMDY(b.booking_date) }} {{ formatTime12(b.start_time) }} – {{ formatTime12(b.end_time) }} {{ b.status }}

How To Book

  1. Pick your branch, then select a date and click an open hour on the Court Availability grid below.
  2. Select a date and click an open hour on the Court Availability grid below.
  3. Click Book Now and enter your name and contact number.
  4. Choose a payment method, scan the QR code, and upload a screenshot of your payment receipt to confirm - you'll get a booking reference number to track your reservation anytime via Find Your Booking.
⚠️ No refund and cancellations once a booking is confirmed and paid.

Court Booking Form

Click any available hour on the grid below to book it. Want more time? Click a later hour to extend your booking to a consecutive block. You can also select more than one court and/or more than one date - just click another available hour anywhere else on the grid to add it to the same reservation.

Court Availability

Branch: {{ (auth.user.branch_id && branchNameById(auth.user.branch_id)) || 'Unassigned' }}
{{ publicGridCalendarMonthName }}
{{ d }}

Court Availability - {{ formatDateMDY(publicGridDate) }}

Selected Open Pending Payment Booked Past

⚠️ Within a single court/date, hours must be consecutive - non-consecutive hours on the same court and date must be separate bookings. Click one hour to book just that hour, or click a later hour afterward to extend the block. Click any hour in your selection again to remove it. Different courts and/or different dates (consecutive or not) can be combined into one reservation.

{{ publicGridLoading ? 'Loading court availability…' : 'No active courts to display for this branch yet.' }}
Time {{ court.name }} ₱{{ formatAmount(publicGridCourtRate(court.id)) }}/hr (+₱{{ formatAmount(settings.transaction_fee_per_hour) }} fee) ₱{{ formatAmount(publicGridCourtRateWithFee(court.id)) }}/hr
{{ formatHourRangeLabel(row.hour) }}
{{ cell.isPast ? 'Past' : publicGridCellLabel(cell) }}
{{ slot.court_name }} · {{ formatDateMDY(slot.date) }} · {{ formatTime12(slot.start_time) }} – {{ formatTime12(slot.end_time) }} {{ slot.hours }} {{ slot.hours === 1 ? 'Hour' : 'Hours' }}
{{ allSelectedDaySlots().length }} reservations selected · {{ calculatedHours }} {{ calculatedHours === 1 ? 'Hour' : 'Hours' }} total
No time selected yet. Click an available hour on the grid above to begin. To book more courts and/or more dates in the same reservation, just click another available hour on a different court and/or a different date - it will be added alongside what you've already selected (dates don't need to be consecutive).
Total Calculated Fee:
₱{{ formatAmount(calculatedGrandTotal) }} PHP
Court Fee: ₱{{ formatAmount(bookingForm.amount) }} + Transaction Fee: ₱{{ formatAmount(calculatedTransactionFee) }}

Step 1 of 2 — Your Details

Tell us who's booking. Payment is the next step.

Selected:
{{ slot.court_name }} · {{ formatDateMDY(slot.date) }} · {{ formatTime12(slot.start_time) }} – {{ formatTime12(slot.end_time) }}
Total ₱{{ formatAmount(calculatedGrandTotal) }}
Court Fee: ₱{{ formatAmount(bookingForm.amount) }} + Transaction Fee: ₱{{ formatAmount(calculatedTransactionFee) }}

Please enter a valid email address.

Step 2 of 2 — Payment

4. Payment (GCASH/BANK)

🚶 Walk-in / Pay Later — no receipt required. The booking will be saved as approved right away and the slot is locked in; the customer simply pays at the counter.
Total to Pay ₱{{ formatAmount(calculatedGrandTotal) }} PHP

Frequently Asked Questions

{{ faq.a }}

Find Us

{{ selectedBranch.name }}
{{ [selectedBranch.address, selectedBranch.city].filter(Boolean).join(', ') }}
{{ selectedBranch.contact_number }}
Open 24 hrs Daily

Portal Login

Staff/Admin Only

🔒

Dashboard Temporarily Locked

Temporarily locked due to not paying the transaction fee. Please settle the outstanding balance to restore access.

Please contact your primary administrator to resolve this.

Developer Dashboard

Platform-wide transaction fee revenue and payment approvals.

Total Collected
₱{{ formatAmount(developerDashboard.total_collected) }}
From approved/completed bookings, all-time.
Remitted (Paid)
₱{{ formatAmount(developerDashboard.total_remitted) }}
Sum of periods marked Paid.
Outstanding
₱{{ formatAmount(developerDashboard.total_outstanding) }}
Collected but not yet remitted.

{{ isDashboardLocked ? '🔒 Staff/Admin Dashboard is LOCKED' : 'Staff/Admin Dashboard is Unlocked' }}

Temporarily lock every admin/staff out of their dashboard if the transaction fee has gone unpaid. The nav bar and System page stay reachable so they can still pay.

My Account

Transaction Fee Settings

Charged on top of the customer's court fee, shown in the booking's price breakdown.

Your Payment QR (shown to admins on the "Pay" screen)

Required - upload a QR code before saving.

Current QR

OCR.space API Key

Used to extract text from uploaded payment receipts (via the free OCR.space API) so only the text is saved - never the receipt image. "Test Connection" checks the currently saved key (save first if you just pasted a new one).

Payment Approvals

Period Amount Submitted By Receipt (OCR) Status Action
No payment submissions yet.
{{ p.period_start }} – {{ p.period_end }} ₱{{ formatAmount(p.amount) }} {{ p.submitted_by_name || '—' }} {{ p.payment_receipt_text || 'No receipt text extracted.' }} {{ p.status === 'pending_approval' ? 'Pending' : p.status }}
{{ receiptModalBooking && receiptModalBooking.payment_ref === 'WALK_IN_PAY_LATER' ? 'Booking Confirmed!' : 'Booking Pending Payment!' }}
{{ receiptModalBooking && receiptModalBooking.payment_ref === 'WALK_IN_PAY_LATER' ? 'This reservation is approved and the slot is locked in - the customer can settle payment at the counter. You can look this booking up anytime in the FIND YOUR BOOKING section.' : 'Once we receive your payment, the status will be updated to paid. You can check your booking status anytime in the FIND YOUR BOOKING section.' }}

Booking Ticket

{{ settings.page_title || 'HARD COURTS RESERVATION SYSTEM' }} Confirmation

📌 Notice: You need to take a screenshot of this ticket to present at the court.
Booking Reference: {{ receiptModalBooking.booking_ref || receiptModalBooking.id }}
Court {{ receiptModalBooking.court_name }}
Status {{ receiptModalBooking.status }}
Booking Date {{ formatDateMDY(receiptModalBooking.booking_date) }}
Time Slot {{ formatTime12(receiptModalBooking.start_time) }} - {{ formatTime12(receiptModalBooking.end_time) }}
{{ receiptModalBooking.dates.length }} Reservations
{{ d.court_name ? d.court_name + ' · ' : '' }}{{ formatDateMDY(d.booking_date) }} {{ formatTime12(d.start_time) }} - {{ formatTime12(d.end_time) }} · ₱{{ formatAmount((parseFloat(d.amount) || 0) + (parseFloat(d.transaction_fee_amount) || 0)) }}
Player Name: {{ receiptModalBooking.customer_name }}
Email: {{ receiptModalBooking.customer_email }}
Phone: {{ receiptModalBooking.customer_phone }}
Payment Receipt (Extracted Details)
{{ receiptModalBooking.payment_receipt_text }}
No text could be extracted from this receipt (OCR found nothing, or OCR isn't configured - check Settings for the OCR.space API Key).
Court Fee ₱{{ formatAmount(receiptModalBooking.amount) }}
Transaction Fee ₱{{ formatAmount(receiptModalBooking.transaction_fee_amount) }}
{{ receiptModalBooking.status === 'completed' ? 'Total Amount Paid:' : ((receiptModalBooking.payment_ref === 'PAY_AFTER_GAME' || receiptModalBooking.payment_ref === 'WALK_IN_PAY_LATER') ? 'Total Amount Due:' : 'Total Amount Paid:') }} ₱{{ formatAmount((parseFloat(receiptModalBooking.amount) || 0) + (parseFloat(receiptModalBooking.transaction_fee_amount) || 0)) }} PHP

Edit End Time

Booking Ref: {{ editEndTimeModal.booking_ref || editEndTimeModal.id }}

Court: {{ editEndTimeModal.court_name }}
Date: {{ formatDateMDY(editEndTimeModal.booking_date) }}
Start Time: {{ formatTime12(editEndTimeModal.start_time) }}
Current End Time: {{ formatTime12(editEndTimeModal.end_time) }}
New Total Amount: ₱{{ formatAmount(editEndTimeCalculatedAmount + editEndTimeCalculatedFee) }} PHP

System Activity & Audit Logs

Tracks all administrative user actions.

ID User Role Branch Action Details Timestamp
No activity logs recorded yet.
#{{ log.id }} {{ log.user_name }} {{ log.user_role }} {{ log.branch_name || 'All Branches' }} {{ log.action }} {{ log.details || '—' }} {{ formatDateMDY(log.created_at) }}

System — Transaction Fee Billing

One combined statement covering every branch, billed twice a month (due the 5th and 20th).

Period Due Date Amount Status Paid On Action
No billing periods yet.
{{ formatDateMDY(p.period_start) }} – {{ formatDateMDY(p.period_end) }} {{ formatDateMDY(p.due_date) }} ₱{{ formatAmount(p.amount) }} {{ p.status === 'unpaid' && p.is_overdue ? 'Overdue' : (p.status === 'pending_approval' ? 'Pending Approval' : p.status) }}
Rejected: {{ p.rejection_reason }}
{{ p.paid_at ? formatDateTime12(p.paid_at) : '—' }} Opens {{ formatDateMDY(p.payable_from) }} Awaiting developer review ✓ Settled

Pay Transaction Fee

Period: {{ payFeePeriodModal.period_start }} – {{ payFeePeriodModal.period_end }}
Due: {{ payFeePeriodModal.due_date }}
Amount: ₱{{ formatAmount(payFeePeriodModal.amount) }}
Scan to Pay
Developer Payment QR Code
{{ settings.developer_gcash_name }} — Acct #: {{ settings.developer_gcash_number }}
⚠️ The system developer hasn't configured a payment QR yet. Contact them directly to arrange payment.

Extracted via OCR so the system developer can verify it against your payment.

{{ auth.user.role === 'staff' ? 'My Account Details' : 'Staff & Admin Account Management' }}

{{ userForm.id ? 'Edit User Account' : 'Add New Staff / Admin' }}

Which branch this account is scoped to in the Court Availability grid.
ℹ️ Select your own individual account record row below to update your authentic credential properties.

{{ auth.user.role === 'staff' ? 'Your Personal Account Record' : 'Existing System Users' }}

{{ u.name }}
{{ u.email }}
{{ u.role }} {{ u.branch_id ? (branchNameById(u.branch_id) || 'Unknown Branch') : 'All Branches' }}

Court Management & Settings

📌 Reserve Court Form Time Settings and Peak Hours Pricing are now configured per branch — see Manage Branches.

{{ courtForm.id ? 'Edit Court Facility' : 'Add New Court Facility' }}

⚠️ Staff cannot edit hourly rate
Charged instead of the hourly rate during this court's branch's Peak Hours window (set in Manage Branches). Leave blank to always charge the normal rate.
{{ (auth.user.branch_id && branchNameById(auth.user.branch_id)) || 'Unassigned' }}
New/edited courts are automatically assigned to your branch.

Existing Courts

Court item picture
No Image
{{ c.name }}
₱{{ formatAmount(c.hourly_rate) }}/hr (+₱{{ formatAmount(settings.transaction_fee_per_hour) }} fee)
⚡ Peak ₱{{ formatAmount(c.peak_hour_price) }}/hr (+₱{{ formatAmount(settings.transaction_fee_per_hour) }} fee)
{{ getCourtImageArray(c.image_url).length }} photo(s)
{{ c.branch_name || branchNameById(c.branch_id) || 'Unassigned' }}

Branch Management

{{ branchForm.id ? 'Edit Branch' : 'Add New Branch' }}

Hour range shown on this branch's booking form and Court Availability grid.

When peak hours are for this branch. The peak rate itself is set per court in Manage Courts - leave both blank to disable peak hours for this branch.

Branch preview

Existing Branches

Branch picture
No Image
{{ b.name }}
{{ b.city || b.address || 'No location set' }}
{{ b.status }} Main Branch
🕐 {{ formatHour12(b.court_start_hour) }}–{{ formatHour12(b.court_end_hour) }}
⚡ Peak Hours {{ formatHour12(b.peak_hour_start) }}–{{ formatHour12(b.peak_hour_end) }}

Payment Methods

Branch:
ℹ️ No branch selected, so there's no payment methods list to manage.

🚧 Block A Court

Branch: {{ branchNameById(auth.user.branch_id) || 'Unassigned' }}
Duration: {{ blockCalculatedHours }} hour{{ blockCalculatedHours === 1 ? '' : 's' }} selected

Bookings on {{ formatDateMDY(selectedDayModal.dateStr) }}

No active bookings on this date.
{{ b.court_name }} {{ b.status }}
{{ formatTime12(b.start_time) }} - {{ formatTime12(b.end_time) }} {{ b.timesSummary }}
Player: {{ b.customer_name }} ({{ b.customer_phone }})
Booking Ref #: {{ b.booking_ref || b.id }}
₱{{ formatAmount((parseFloat(b.amount) || 0) + (parseFloat(b.transaction_fee_amount) || 0)) }}
⚠️ Past dates cannot be reserved.

System Settings & Carousel

General System Settings

Adjusts readability text scaling across system screens.
System logo preview

Dynamic Landing Carousel Slides

Slide preview
Slide preview
{{ slide.caption || 'No Caption' }}
ID: #{{ slide.id }} • {{ branchNameById(slide.branch_id) || 'All Branches' }}