230 lines
7.9 KiB
HTML
230 lines
7.9 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Agenda - Edward Betts</title>
|
|
<link href="{{ url_for("static", filename="bootstrap5/css/bootstrap.min.css") }}" rel="stylesheet">
|
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>📅</text></svg>">
|
|
|
|
<!-- TOAST UI Calendar CSS -->
|
|
<link rel="stylesheet" href="https://uicdn.toast.com/calendar/latest/toastui-calendar.min.css" />
|
|
<style>
|
|
/* Custom styles to better integrate with Bootstrap */
|
|
.toastui-calendar-layout {
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 0.375rem;
|
|
}
|
|
#calendar-header {
|
|
margin-bottom: 1rem;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
{% set event_labels = {
|
|
"economist": "📰 The Economist",
|
|
"mothers_day": "Mothers' day",
|
|
"fathers_day": "Fathers' day",
|
|
"uk_financial_year_end": "End of financial year",
|
|
"bank_holiday": "UK bank holiday",
|
|
"us_holiday": "US holiday",
|
|
"uk_clock_change": "UK clock change",
|
|
"us_clock_change": "US clock change",
|
|
"us_presidential_election": "US pres. election",
|
|
"xmas_last_second": "Christmas last posting 2nd class",
|
|
"xmas_last_first": "Christmas last posting 1st class",
|
|
"up_series": "Up documentary",
|
|
"waste_schedule": "Waste schedule",
|
|
"gwr_advance_tickets": "GWR advance tickets",
|
|
"critical_mass": "Critical Mass",
|
|
}
|
|
%}
|
|
|
|
{% from "navbar.html" import navbar with context %}
|
|
<body>
|
|
{{ navbar() }}
|
|
|
|
<div class="container-fluid mt-2">
|
|
<h1>Agenda</h1>
|
|
<p>
|
|
<a href="/tools">← personal tools</a>
|
|
</p>
|
|
|
|
{% if errors %}
|
|
{% for error in errors %}
|
|
<div class="alert alert-danger" role="alert">
|
|
Error: {{ error }}
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
<div>
|
|
Markets:
|
|
<a href="{{ url_for(request.endpoint) }}">Hide while away</a>
|
|
| <a href="{{ url_for(request.endpoint, markets="show") }}">Show all</a>
|
|
| <a href="{{ url_for(request.endpoint, markets="hide") }}">Hide all</a>
|
|
</div>
|
|
|
|
<!-- Header for calendar controls -->
|
|
<div id="calendar-header" class="d-flex justify-content-between align-items-center mt-3">
|
|
<div class="btn-group" role="group">
|
|
<button type="button" class="btn btn-primary" id="prevBtn">Prev</button>
|
|
<button type="button" class="btn btn-primary" id="nextBtn">Next</button>
|
|
<button type="button" class="btn btn-outline-primary" id="todayBtn">Today</button>
|
|
</div>
|
|
<h3 id="calendar-title" class="mb-0"></h3>
|
|
<div class="btn-group" role="group">
|
|
<button type="button" class="btn btn-outline-primary" id="monthViewBtn">Month</button>
|
|
<button type="button" class="btn btn-outline-primary" id="weekViewBtn">Week</button>
|
|
<button type="button" class="btn btn-outline-primary" id="dayViewBtn">Day</button>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div class="mb-3" id="calendar" style="height: 80vh;"></div>
|
|
|
|
{#
|
|
<div class="mt-2">
|
|
<h5>Page generation time</h5>
|
|
<ul>
|
|
<li>Data gather took {{ "%.1f" | format(data_gather_seconds) }} seconds</li>
|
|
<li>Stock market open/close took
|
|
{{ "%.1f" | format(stock_market_times_seconds) }} seconds</li>
|
|
{% for name, seconds in timings %}
|
|
<li>{{ name }} took {{ "%.1f" | format(seconds) }} seconds</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
#}
|
|
|
|
</div>
|
|
|
|
|
|
<!-- TOAST UI Calendar JS -->
|
|
<script src="https://uicdn.toast.com/calendar/latest/toastui-calendar.min.js"></script>
|
|
<script src="{{ url_for("static", filename="bootstrap5/js/bootstrap.bundle.min.js") }}"></script>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const Calendar = tui.Calendar;
|
|
const container = document.getElementById('calendar');
|
|
|
|
// --- Configuration ---
|
|
const calendars = {{ toastui_calendars | tojson }};
|
|
const events = {{ toastui_events | tojson }};
|
|
|
|
function getSavedView() {
|
|
return localStorage.getItem('toastUiCalendarDefaultView') || 'month';
|
|
}
|
|
|
|
function saveView(view) {
|
|
localStorage.setItem('toastUiCalendarDefaultView', view);
|
|
}
|
|
|
|
const options = {
|
|
defaultView: getSavedView(),
|
|
useDetailPopup: true,
|
|
useCreationPopup: false,
|
|
calendars: calendars,
|
|
week: {
|
|
startDayOfWeek: 1, // Monday
|
|
taskView: false,
|
|
eventView: ['time'],
|
|
showNowIndicator: true,
|
|
},
|
|
month: {
|
|
startDayOfWeek: 1, // Monday
|
|
// We've removed `visibleWeeksCount: 6` to allow the calendar
|
|
// to dynamically show 4, 5, or 6 weeks as needed.
|
|
},
|
|
timezone: {
|
|
zones: [{
|
|
timezoneName: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
}]
|
|
},
|
|
template: {
|
|
allday(event) {
|
|
return `<span title="${event.title}">${event.title}</span>`;
|
|
},
|
|
time(event) {
|
|
return `<span title="${event.title}">${event.title}</span>`;
|
|
},
|
|
},
|
|
};
|
|
|
|
const calendar = new Calendar(container, options);
|
|
calendar.createEvents(events);
|
|
|
|
// --- Event Handlers ---
|
|
calendar.on('clickEvent', ({ event }) => {
|
|
if (event.raw && event.raw.url) {
|
|
window.open(event.raw.url, '_blank');
|
|
}
|
|
});
|
|
|
|
calendar.on('afterRenderEvent', () => {
|
|
const currentView = calendar.getViewName();
|
|
saveView(currentView);
|
|
updateCalendarTitle();
|
|
});
|
|
|
|
|
|
// --- UI Control Logic ---
|
|
const prevBtn = document.getElementById('prevBtn');
|
|
const nextBtn = document.getElementById('nextBtn');
|
|
const todayBtn = document.getElementById('todayBtn');
|
|
const monthViewBtn = document.getElementById('monthViewBtn');
|
|
const weekViewBtn = document.getElementById('weekViewBtn');
|
|
const dayViewBtn = document.getElementById('dayViewBtn');
|
|
const calendarTitle = document.getElementById('calendar-title');
|
|
|
|
function updateCalendarTitle() {
|
|
const tzDate = calendar.getDate();
|
|
const nativeDate = tzDate.toDate();
|
|
|
|
const year = nativeDate.getFullYear();
|
|
const monthName = nativeDate.toLocaleDateString('en-GB', { month: 'long' });
|
|
|
|
calendarTitle.textContent = `${monthName} ${year}`;
|
|
}
|
|
|
|
// --- CORRECTED NAVIGATION LOGIC ---
|
|
prevBtn.addEventListener('click', () => {
|
|
const currentDate = calendar.getDate().toDate();
|
|
// Go to the previous month
|
|
currentDate.setMonth(currentDate.getMonth() - 1);
|
|
// **Crucially, set the day to the 1st to align the view**
|
|
currentDate.setDate(1);
|
|
calendar.setDate(currentDate);
|
|
updateCalendarTitle();
|
|
});
|
|
|
|
nextBtn.addEventListener('click', () => {
|
|
const currentDate = calendar.getDate().toDate();
|
|
// Go to the next month
|
|
currentDate.setMonth(currentDate.getMonth() + 1);
|
|
// **Crucially, set the day to the 1st to align the view**
|
|
currentDate.setDate(1);
|
|
calendar.setDate(currentDate);
|
|
updateCalendarTitle();
|
|
});
|
|
|
|
todayBtn.addEventListener('click', () => {
|
|
calendar.today();
|
|
updateCalendarTitle();
|
|
});
|
|
|
|
monthViewBtn.addEventListener('click', () => calendar.changeView('month'));
|
|
weekViewBtn.addEventListener('click', () => calendar.changeView('week'));
|
|
dayViewBtn.addEventListener('click', () => calendar.changeView('day'));
|
|
|
|
// Initial setup
|
|
updateCalendarTitle();
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|