Files
Bar-menu-and-calendar-events/events.html
2026-03-17 10:46:25 -04:00

373 lines
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Axis — Events</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- ===================================================
ADMIN: Edit the events array below to update the
events page. Each object supports:
name (string) — event title
date (string) — "YYYY-MM-DD"
time (string) — display string e.g. "9 PM"
description (string) — short blurb
tag (string) — optional label e.g. "Live Music"
==================================================== -->
<script id="events-data" type="application/json">
[
{
"name": "Trivia Night",
"date": "2026-03-17",
"time": "8 PM 10 PM",
"description": "Teams of up to 6. Prizes include bar tabs and Axis merchandise. Arrive early to grab a table.",
"tag": "Social"
},
{
"name": "Live Music",
"date": "2026-03-20",
"time": "9 PM",
"description": "Local and touring acts across folk, rock, soul, and jazz. No cover charge, ever.",
"tag": "Live Music"
},
{
"name": "Trivia Night",
"date": "2026-03-24",
"time": "8 PM 10 PM",
"description": "Teams of up to 6. Prizes include bar tabs and Axis merchandise. Arrive early to grab a table.",
"tag": "Social"
},
{
"name": "Live Music",
"date": "2026-03-27",
"time": "9 PM",
"description": "Local and touring acts across folk, rock, soul, and jazz. No cover charge, ever.",
"tag": "Live Music"
},
{
"name": "Live Music",
"date": "2026-03-30",
"time": "9 PM",
"description": "Local and touring acts across folk, rock, soul, and jazz. No cover charge, ever.",
"tag": "Live Music"
},
{
"name": "Trivia Night",
"date": "2026-03-31",
"time": "8 PM 10 PM",
"description": "Teams of up to 6. Prizes include bar tabs and Axis merchandise. Arrive early to grab a table.",
"tag": "Social"
},
{
"name": "Live Music",
"date": "2026-04-03",
"time": "9 PM",
"description": "Local and touring acts across folk, rock, soul, and jazz. No cover charge, ever.",
"tag": "Live Music"
},
{
"name": "Trivia Night",
"date": "2026-04-07",
"time": "8 PM 10 PM",
"description": "Teams of up to 6. Prizes include bar tabs and Axis merchandise. Arrive early to grab a table.",
"tag": "Social"
},
{
"name": "Board Games & Chess Night",
"date": "2026-04-09",
"time": "7 PM",
"description": "The 2nd Thursday of every month. Bring your A-game. Classic board games, chess sets, and cold drinks. All skill levels welcome.",
"tag": "Social"
},
{
"name": "Live Music",
"date": "2026-04-10",
"time": "9 PM",
"description": "Local and touring acts across folk, rock, soul, and jazz. No cover charge, ever.",
"tag": "Live Music"
},
{
"name": "Trivia Night",
"date": "2026-04-14",
"time": "8 PM 10 PM",
"description": "Teams of up to 6. Prizes include bar tabs and Axis merchandise. Arrive early to grab a table.",
"tag": "Social"
},
{
"name": "Live Music",
"date": "2026-04-17",
"time": "9 PM",
"description": "Local and touring acts across folk, rock, soul, and jazz. No cover charge, ever.",
"tag": "Live Music"
},
{
"name": "Live Music",
"date": "2026-04-20",
"time": "9 PM",
"description": "Local and touring acts across folk, rock, soul, and jazz. No cover charge, ever.",
"tag": "Live Music"
},
{
"name": "Trivia Night",
"date": "2026-04-21",
"time": "8 PM 10 PM",
"description": "Teams of up to 6. Prizes include bar tabs and Axis merchandise. Arrive early to grab a table.",
"tag": "Social"
},
{
"name": "Live Music",
"date": "2026-04-24",
"time": "9 PM",
"description": "Local and touring acts across folk, rock, soul, and jazz. No cover charge, ever.",
"tag": "Live Music"
},
{
"name": "Trivia Night",
"date": "2026-04-28",
"time": "8 PM 10 PM",
"description": "Teams of up to 6. Prizes include bar tabs and Axis merchandise. Arrive early to grab a table.",
"tag": "Social"
},
{
"name": "Live Music",
"date": "2026-04-27",
"time": "9 PM",
"description": "Local and touring acts across folk, rock, soul, and jazz. No cover charge, ever.",
"tag": "Live Music"
},
{
"name": "Board Games & Chess Night",
"date": "2026-05-14",
"time": "7 PM",
"description": "The 2nd Thursday of every month. Bring your A-game. Classic board games, chess sets, and cold drinks. All skill levels welcome.",
"tag": "Social"
}
]
</script>
<!-- ===== Navbar ===== -->
<nav class="navbar">
<a href="index.html" class="navbar__brand">Axis</a>
<button class="navbar__toggle" aria-label="Toggle menu" onclick="toggleNav()">
<span></span><span></span><span></span>
</button>
<ul class="navbar__links" id="nav-links">
<li><a href="index.html">Home</a></li>
<li><a href="menu.html">Menu</a></li>
<li><a href="events.html" class="active">Events</a></li>
</ul>
</nav>
<!-- ===== Hero ===== -->
<header class="page-hero">
<p class="page-hero__eyebrow">What's On</p>
<h1 class="page-hero__title">Upcoming Events</h1>
<p class="page-hero__sub">Live music &middot; Trivia &middot; Board games &middot; Special nights</p>
</header>
<!-- ===== Calendar Widget ===== -->
<div class="container">
<div class="cal-widget" id="cal-widget"></div>
</div>
<!-- ===== Main Content ===== -->
<main>
<div class="container">
<div class="events-grid" id="events-container">
<!-- Populated by JS below -->
</div>
</div>
</main>
<!-- ===== Footer ===== -->
<footer>
<p><span>Axis</span> &mdash; 3048 Dundas Street West &mdash; Open TueSun 5pm2am &mdash; Brunch ThuSun 9am3pm</p>
<p style="margin-top:0.4rem;">Events subject to change. Follow us for updates.</p>
</footer>
<script>
/* ---- Mobile nav ---- */
function toggleNav() {
document.getElementById('nav-links').classList.toggle('open');
}
/* ---- Calendar Widget ---- */
(function () {
const calEl = document.getElementById('cal-widget');
const MONTH_NAMES = ['January','February','March','April','May','June','July','August','September','October','November','December'];
const today = new Date();
let viewYear = today.getFullYear();
let viewMonth = today.getMonth();
function is2ndThursday(y, m, d) {
if (new Date(y, m, d).getDay() !== 4) return false;
let count = 0;
for (let i = 1; i <= d; i++) {
if (new Date(y, m, i).getDay() === 4) count++;
}
return count === 2;
}
function getDots(y, m, d) {
const dow = new Date(y, m, d).getDay();
const dots = [];
if (dow === 2) dots.push({ color: 'var(--gold)', label: 'Trivia Night' });
if (dow === 1 || dow === 5) dots.push({ color: '#e07020', label: 'Live Music' });
if (is2ndThursday(y, m, d)) dots.push({ color: '#8844cc', label: 'Board Games & Chess Night' });
return dots;
}
function isBrunchDay(dow) {
// Thu=4, Fri=5, Sat=6, Sun=0
return dow === 0 || dow === 4 || dow === 5 || dow === 6;
}
function render() {
const firstDow = new Date(viewYear, viewMonth, 1).getDay();
const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
let html = '<div class="cal-header">';
html += '<button class="cal-nav-btn" id="cal-prev">&#8249;</button>';
html += '<span class="cal-month-label">' + MONTH_NAMES[viewMonth] + ' ' + viewYear + '</span>';
html += '<button class="cal-nav-btn" id="cal-next">&#8250;</button>';
html += '</div>';
html += '<div class="cal-grid">';
// Day-of-week headers
['Sun','Mon','Tue','Wed','Thu','Fri','Sat'].forEach(function (d) {
html += '<div class="cal-dow-header">' + d + '</div>';
});
// Empty leading cells
for (let i = 0; i < firstDow; i++) {
html += '<div class="cal-cell cal-cell--empty"></div>';
}
// Day cells
for (let d = 1; d <= daysInMonth; d++) {
const dow = new Date(viewYear, viewMonth, d).getDay();
const isToday = (today.getFullYear() === viewYear && today.getMonth() === viewMonth && today.getDate() === d);
const brunch = isBrunchDay(dow);
const dots = getDots(viewYear, viewMonth, d);
let cls = 'cal-cell';
if (brunch) cls += ' cal-cell--brunch';
if (isToday) cls += ' cal-cell--today';
html += '<div class="' + cls + '">';
html += '<span class="cal-day-num">' + d + '</span>';
if (dots.length > 0) {
html += '<div class="cal-dots">';
dots.forEach(function (dot) {
html += '<span class="cal-dot" style="background:' + dot.color + '" title="' + dot.label + '"></span>';
});
html += '</div>';
}
html += '</div>';
}
html += '</div>'; // .cal-grid
// Legend
html += '<div class="cal-legend">';
html += '<span class="cal-legend-item"><span class="cal-dot" style="background:var(--gold)"></span> Trivia Night (Tue)</span>';
html += '<span class="cal-legend-item"><span class="cal-dot" style="background:#e07020"></span> Live Music (Mon &amp; Fri)</span>';
html += '<span class="cal-legend-item"><span class="cal-dot" style="background:#8844cc"></span> Board Games &amp; Chess (2nd Thu)</span>';
html += '<span class="cal-legend-item"><span class="cal-legend-brunch-swatch"></span> Brunch hours (ThuSun)</span>';
html += '</div>';
calEl.innerHTML = html;
document.getElementById('cal-prev').addEventListener('click', function () {
viewMonth--;
if (viewMonth < 0) { viewMonth = 11; viewYear--; }
render();
});
document.getElementById('cal-next').addEventListener('click', function () {
viewMonth++;
if (viewMonth > 11) { viewMonth = 0; viewYear++; }
render();
});
}
render();
})();
/* ---- Render events ---- */
(function () {
const DAYS = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
const MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
const raw = document.getElementById('events-data').textContent;
const events = JSON.parse(raw);
const container = document.getElementById('events-container');
if (!events || events.length === 0) {
container.innerHTML = '<p class="no-events">No upcoming events at this time.<br>Check back soon.</p>';
return;
}
events.sort((a, b) => new Date(a.date) - new Date(b.date));
const today = new Date();
today.setHours(0, 0, 0, 0);
const upcoming = events.filter(e => {
const [y, m, d] = e.date.split('-').map(Number);
const dt = new Date(y, m - 1, d);
return dt >= today;
});
if (upcoming.length === 0) {
container.innerHTML = '<p class="no-events">No upcoming events at this time.<br>Check back soon.</p>';
return;
}
upcoming.forEach(event => {
const [y, m, d] = event.date.split('-').map(Number);
const dt = new Date(y, m - 1, d);
const mon = MONTHS[dt.getMonth()];
const day = dt.getDate();
const dow = DAYS[dt.getDay()];
const tagHTML = event.tag
? `<span class="event-card__tag">${escHtml(event.tag)}</span>`
: '';
const card = document.createElement('article');
card.className = 'event-card';
card.innerHTML = `
<div class="event-card__date-block">
<div class="event-card__cal">
<div class="event-card__cal-month">${mon}</div>
<div class="event-card__cal-day">${day}</div>
</div>
<div class="event-card__datetime">
<div class="event-card__dow">${dow}</div>
<div class="event-card__time">${escHtml(event.time)}</div>
</div>
</div>
<h2 class="event-card__name">${escHtml(event.name)}</h2>
<p class="event-card__desc">${escHtml(event.description)}</p>
${tagHTML}
`;
container.appendChild(card);
});
})();
function escHtml(str) {
return String(str)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
</script>
</body>
</html>