2ccb018bdf
Players can create tours with selected courses/layouts and a date range. Others join via a 6-character tour code, play the courses, and report their total strokes. Live leaderboard with points and +/- par display. Includes: database schema, model, service, routes, views, and styling.
91 lines
3.4 KiB
Plaintext
91 lines
3.4 KiB
Plaintext
<% if (!tour) { %>
|
|
<% var body = `
|
|
<div class="card-section">
|
|
<h3>Tour Not Found</h3>
|
|
<p>The tour code is invalid or the tour has been removed.</p>
|
|
<a href="/tours" class="btn"><i class="fas fa-arrow-left"></i> Back to Tours</a>
|
|
</div>
|
|
`; %>
|
|
<%- include('../partials/layout', {
|
|
title: 'Tour Not Found',
|
|
heading: 'Tour Not Found',
|
|
activePage: 'tours',
|
|
cssFiles: ['tours.css'],
|
|
body: body
|
|
}) %>
|
|
<% } else { %>
|
|
<%
|
|
var statusBadge = isActive
|
|
? '<span class="badge badge-active">Active</span>'
|
|
: isFinished
|
|
? '<span class="badge badge-finished">Finished</span>'
|
|
: '<span class="badge badge-upcoming">Upcoming</span>';
|
|
|
|
var courseOptionsHtml = '';
|
|
courses.forEach(function(c) {
|
|
courseOptionsHtml += '<option value="' + c.tour_course_id + '">'
|
|
+ c.course_name.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
|
|
+ ' - '
|
|
+ c.layout_name.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
|
|
+ ' (Par ' + c.par + ')'
|
|
+ '</option>';
|
|
});
|
|
|
|
var escapedCode = tour.code.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
var escapedStartDate = tour.start_date.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
var escapedEndDate = tour.end_date.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
%>
|
|
|
|
<% var body = `
|
|
<div class="tour-header">
|
|
<div class="tour-info">
|
|
<div class="tour-meta">
|
|
${statusBadge}
|
|
<span class="tour-dates"><i class="fas fa-calendar"></i> ${escapedStartDate} — ${escapedEndDate}</span>
|
|
<span class="tour-code-label"><i class="fas fa-key"></i> ${escapedCode}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-section" id="join-section">
|
|
<h3>Join This Tour</h3>
|
|
<div class="card-section-form">
|
|
<input type="text" class="input" id="pdga-number" placeholder="PDGA Number" style="width: 160px;" />
|
|
<input type="text" class="input" id="player-name" placeholder="Your Name" style="width: 200px;" />
|
|
<button class="btn" onclick="joinTour()">
|
|
<i class="fas fa-user-plus"></i> Join
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card-section" id="result-section" style="display: none;">
|
|
<h3>Record Result</h3>
|
|
<div class="card-section-form">
|
|
<select class="input" id="result-course" style="width: 280px;">
|
|
<option value="">Select course...</option>
|
|
${courseOptionsHtml}
|
|
</select>
|
|
<input type="number" class="input" id="result-strokes" placeholder="Total strokes" style="width: 140px;" min="1" />
|
|
<button class="btn" onclick="recordResult('${escapedCode}')">
|
|
<i class="fas fa-save"></i> Save
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="leaderboard-container"
|
|
hx-get="/partials/tour-leaderboard/${escapedCode}"
|
|
hx-trigger="load">
|
|
<div class="loading">Loading leaderboard...</div>
|
|
</div>
|
|
`; %>
|
|
|
|
<%- include('../partials/layout', {
|
|
title: tour.name + ' - PDGA Tours',
|
|
heading: tour.name,
|
|
activePage: 'tours',
|
|
cssFiles: ['tours.css'],
|
|
jsFiles: ['tour.js'],
|
|
initScript: 'initTour("' + escapedCode + '");',
|
|
body: body
|
|
}) %>
|
|
<% } %> |