m registration · HTML
Copy
Swim Lesson Registration
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background: #f5f5f3;
color: #1a1a1a;
font-size: 16px;
line-height: 1.5;
}
.page-wrap {
max-width: 760px;
margin: 0 auto;
padding: 2rem 1rem 4rem;
}
.page-header {
text-align: center;
margin-bottom: 2rem;
}
.page-header h1 {
font-size: 26px;
font-weight: 600;
margin-bottom: 6px;
color: #1a1a1a;
}
.page-header p {
font-size: 15px;
color: #666;
}
.section-card {
background: #fff;
border: 1px solid #e5e5e5;
border-radius: 12px;
padding: 1.5rem;
margin-bottom: 1.25rem;
}
.section-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 1rem;
color: #1a1a1a;
}
.field-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px;
margin-bottom: 14px;
}
.field-row.full { grid-template-columns: 1fr; }
.field {
display: flex;
flex-direction: column;
gap: 5px;
}
.field label {
font-size: 13px;
color: #555;
font-weight: 500;
}
.field input,
.field textarea {
width: 100%;
padding: 9px 12px;
font-size: 14px;
border: 1px solid #ddd;
border-radius: 8px;
background: #fff;
color: #1a1a1a;
transition: border-color 0.15s;
font-family: inherit;
}
.field input:focus,
.field textarea:focus {
outline: none;
border-color: #185FA5;
box-shadow: 0 0 0 3px rgba(24,95,165,0.1);
}
.field textarea {
resize: vertical;
min-height: 80px;
}
/* Level buttons */
.level-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
}
.level-btn {
padding: 12px 8px;
font-size: 14px;
font-weight: 600;
text-align: center;
cursor: pointer;
border: 1px solid #ddd;
border-radius: 8px;
background: #f9f9f9;
color: #1a1a1a;
transition: all 0.15s;
user-select: none;
}
.level-btn:hover { border-color: #aaa; background: #f0f0f0; }
.level-btn.selected { background: #deeaf7; border-color: #185FA5; color: #185FA5; }
/* Session buttons */
.session-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.session-btn {
padding: 10px 14px;
font-size: 13px;
text-align: left;
cursor: pointer;
border: 1px solid #ddd;
border-radius: 8px;
background: #f9f9f9;
color: #1a1a1a;
transition: all 0.15s;
user-select: none;
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
}
.session-btn:hover { border-color: #aaa; background: #f0f0f0; }
.session-btn.selected { background: #deeaf7; border-color: #185FA5; color: #185FA5; }
.session-btn .s-label { font-weight: 600; white-space: nowrap; }
.session-btn .s-dates { font-size: 11px; opacity: 0.8; text-align: right; }
/* Preference tables */
.pref-section-title {
font-size: 13px;
font-weight: 600;
color: #555;
margin: 1rem 0 6px;
}
.pref-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.pref-table th {
text-align: left;
padding: 6px 8px;
font-weight: 600;
font-size: 12px;
color: #777;
border-bottom: 1px solid #eee;
}
.pref-table td {
padding: 8px;
border-bottom: 1px solid #eee;
}
.pref-table tr:last-child td { border-bottom: none; }
.rank-btn {
width: 34px;
height: 30px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
border: 1px solid #ddd;
border-radius: 6px;
background: #f9f9f9;
color: #999;
transition: all 0.15s;
}
.rank-btn:hover { border-color: #aaa; background: #f0f0f0; }
.rank-btn.rank-1 { background: #185FA5; border-color: #185FA5; color: #fff; }
.rank-btn.rank-2 { background: #1D9E75; border-color: #1D9E75; color: #fff; }
.rank-btn.rank-3 { background: #9FE1CB; border-color: #5DCAA5; color: #085041; }
/* Badge */
.badge {
display: inline-block;
font-size: 11px;
font-weight: 500;
padding: 2px 8px;
border-radius: 99px;
margin-left: 8px;
background: #e1f5ee;
color: #085041;
border: 1px solid #5DCAA5;
}
/* Submit */
.submit-btn {
width: 100%;
padding: 14px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
background: #185FA5;
color: #fff;
border: none;
border-radius: 10px;
margin-top: 1.5rem;
transition: background 0.15s;
font-family: inherit;
}
.submit-btn:hover { background: #134e8a; }
.submit-btn:disabled { background: #aaa; cursor: not-allowed; }
/* Messages */
.error-msg {
display: none;
background: #fff0f0;
border: 1px solid #f5a5a5;
border-radius: 8px;
padding: 12px 16px;
margin-top: 1rem;
font-size: 14px;
color: #a32d2d;
}
.success-wrap {
display: none;
text-align: center;
background: #fff;
border: 1px solid #e5e5e5;
border-radius: 12px;
padding: 3rem 2rem;
margin-top: 2rem;
}
.success-wrap .checkmark {
width: 56px;
height: 56px;
background: #e1f5ee;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
font-size: 26px;
}
.success-wrap h2 {
font-size: 20px;
font-weight: 600;
margin-bottom: 8px;
color: #1a1a1a;
}
.success-wrap p {
font-size: 15px;
color: #666;
}
.hint {
font-size: 12px;
color: #999;
margin-top: 8px;
}
.required-note {
font-size: 12px;
color: #999;
margin-bottom: 1rem;
}
@media (max-width: 520px) {
.field-row { grid-template-columns: 1fr; }
.level-grid { grid-template-columns: repeat(2, 1fr); }
.session-grid { grid-template-columns: 1fr; }
.page-header h1 { font-size: 22px; }
}
Fields marked with * are required.
Parent / guardian information
Swim level preference *
Select the level that best describes your swimmer. Final class assignments are made after all registrations are reviewed.
Level 1
Level 2
Level 3
Level 4
Level 5
Level 6
Session selection *
Select all sessions you are available to attend. Each session runs Monday–Thursday.
You may register for multiple sessions.
Time preferences rank your choices
For each session selected, rank all three time slots as your 1st, 2nd, and 3rd choice.
Click a number in the row for each time slot to assign your ranking. Each rank can only be used once per session.
Select at least one session above to set time preferences.
Additional information
✓
Registration received!
Thank you! We'll be in touch once class assignments have been finalized.
const SCRIPT_URL = "https://script.google.com/macros/s/AKfycbyGMNy9Ugqog2nQK2o3WP6CObKy8zCLZRibPo25IDnEmWU2E5X4VO4JEIAC9RA73Q60/exec";
const sessions = [
{ n: 1, dates: 'Mon Jun 29 – Thu Jul 2' },
{ n: 2, dates: 'Mon Jul 6 – Thu Jul 9' },
{ n: 3, dates: 'Mon Jul 13 – Thu Jul 16' },
{ n: 4, dates: 'Mon Jul 20 – Thu Jul 23' },
{ n: 5, dates: 'Mon Jul 27 – Thu Jul 30' },
{ n: 6, dates: 'Mon Aug 3 – Thu Aug 6' },
{ n: 7, dates: 'Mon Aug 10 – Thu Aug 13' },
{ n: 8, dates: 'Mon Aug 17 – Thu Aug 20' },
];
const times = ['9:00 – 9:30 am', '9:30 – 10:00 am', '10:00 – 10:30 am'];
const selectedSessions = new Set();
const prefs = {};
function buildSessionGrid() {
const grid = document.getElementById('sessionGrid');
sessions.forEach(s => {
const btn = document.createElement('div');
btn.className = 'session-btn';
btn.innerHTML = '
Session ' + s.n + '' + s.dates + '';
btn.onclick = function() { toggleSession(btn, s.n); };
grid.appendChild(btn);
});
}
function selectLevel(el) {
document.querySelectorAll('.level-btn').forEach(function(b) { b.classList.remove('selected'); });
el.classList.add('selected');
}
function toggleSession(el, s) {
var key = String(s);
if (selectedSessions.has(key)) {
selectedSessions.delete(key);
el.classList.remove('selected');
delete prefs[key];
} else {
selectedSessions.add(key);
el.classList.add('selected');
prefs[key] = { 0: null, 1: null, 2: null };
}
renderPrefs();
}
function renderPrefs() {
var container = document.getElementById('prefContainer');
var sorted = Array.from(selectedSessions).sort(function(a, b) { return +a - +b; });
if (sorted.length === 0) {
container.innerHTML = '
Select at least one session above to set time preferences.
';
return;
}
var html = '';
sorted.forEach(function(s) {
var sess = sessions.find(function(x) { return x.n === +s; });
html += '
';
html += '
Session ' + s + ' ' + sess.dates + '
';
html += '
| Time slot | 1st | 2nd | 3rd |
';
times.forEach(function(t, ti) {
html += '| ' + t + ' | ';
[1, 2, 3].forEach(function(rank) {
var active = prefs[s][ti] === rank;
var cls = active ? 'rank-btn rank-' + rank : 'rank-btn';
html += ' | ';
});
html += '
';
});
html += '
';
});
container.innerHTML = html;
}
function setRank(session, timeIdx, rank) {
var p = prefs[session];
for (var k in p) { if (p[k] === rank) p[k] = null; }
p[timeIdx] = (p[timeIdx] === rank) ? null : rank;
renderPrefs();
}
function showError(msg) {
var el = document.getElementById('errorMsg');
el.textContent = msg;
el.style.display = 'block';
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
function hideError() {
document.getElementById('errorMsg').style.display = 'none';
}
function submitForm() {
hideError();
var missing = [];
var swimmerFirst = document.getElementById('swimmerFirst').value.trim();
var swimmerLast = document.getElementById('swimmerLast').value.trim();
var age = document.getElementById('age').value.trim();
var parentFirst = document.getElementById('parentFirst').value.trim();
var parentLast = document.getElementById('parentLast').value.trim();
var email = document.getElementById('email').value.trim();
var phone = document.getElementById('phone').value.trim();
var levelEl = document.querySelector('.level-btn.selected');
if (!swimmerFirst || !swimmerLast) missing.push("swimmer's name");
if (!age) missing.push("swimmer's age");
if (!parentFirst || !parentLast) missing.push("parent/guardian name");
if (!email) missing.push("email");
if (!phone) missing.push("phone");
if (!levelEl) missing.push("swim level");
if (selectedSessions.size === 0) missing.push("at least one session");
var missingPrefs = false;
selectedSessions.forEach(function(s) {
var vals = Object.values(prefs[s]).filter(function(v) { return v !== null; });
if (new Set(vals).size 0) {
showError("Please complete the following: " + missing.join(", ") + ".");
return;
}
var prefSummary = Array.from(selectedSessions).sort(function(a,b){return +a-+b;}).map(function(s) {
var sess = sessions.find(function(x){ return x.n === +s; });
var rankMap = {};
Object.entries(prefs[s]).forEach(function(entry) {
var ti = entry[0], rank = entry[1];
if (rank !== null) rankMap[rank] = times[ti];
});
return 'Session ' + s + ' (' + sess.dates + '): 1st=' + (rankMap[1]||'?') + ', 2nd=' + (rankMap[2]||'?') + ', 3rd=' + (rankMap[3]||'?');
}).join(' | ');
var sessionList = Array.from(selectedSessions).sort(function(a,b){return +a-+b;}).map(function(s) {
var sess = sessions.find(function(x){ return x.n === +s; });
return 'Session ' + s + ' (' + sess.dates + ')';
}).join(', ');
var payload = {
swimmerFirstName: swimmerFirst,
swimmerLastName: swimmerLast,
dob: document.getElementById('dob').value,
age: age,
parentFirstName: parentFirst,
parentLastName: parentLast,
email: email,
phone: phone,
level: levelEl.textContent,
sessions: sessionList,
timePreferences: prefSummary,
notes: document.getElementById('notes').value.trim()
};
var btn = document.getElementById('submitBtn');
btn.disabled = true;
btn.textContent = 'Submitting...';
fetch(SCRIPT_URL, {
method: 'POST',
mode: 'no-cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function() {
document.getElementById('formBody').style.display = 'none';
document.getElementById('successMsg').style.display = 'block';
window.scrollTo({ top: 0, behavior: 'smooth' });
}).catch(function() {
btn.disabled = false;
btn.textContent = 'Submit registration →';
showError('Something went wrong. Please try again or contact us directly.');
});
}
buildSessionGrid();