384 lines
9.3 KiB
Plaintext
384 lines
9.3 KiB
Plaintext
{% assign event = '' %}
|
|
{% if basic_3p_user %}
|
|
{% assign te = training_events.enrolled %}
|
|
{% else %}
|
|
{% assign te = training_events.available %}
|
|
{% endif %}
|
|
|
|
{% for training_event in te %}
|
|
{% assign event = event | append: training_event.title | append: ',' | append: training_event.sessions.first.day | append: ',' | append: training_event.sessions.first.month | append: ',' | append: training_event.sessions.first.year | append: ',' | append: training_event.sessions.first.id | append: '$$' %}
|
|
{% endfor %}
|
|
|
|
|
|
|
|
<div class="wrapper-cal">
|
|
<div class="calendar">
|
|
<div class="calendar-header">
|
|
<button id="prev" class="calendar-header-button"><i class="far fa-chevron-left"></i></button>
|
|
<span id="monthYear"></span>
|
|
<button id="next" class="calendar-header-button"><i class="far fa-chevron-right"></i></button>
|
|
</div>
|
|
<div class="day-names">
|
|
<div>Sun</div><div>Mon</div><div>Tue</div><div>Wed</div><div>Thu</div><div>Fri</div><div>Sat</div>
|
|
</div>
|
|
<div class="calendar-grid" id="calendarGrid"></div>
|
|
<div class="calendar-footer">
|
|
<div class="agenda">
|
|
<div class="red-agenda"></div>
|
|
<div class="agenda-desc">Today</div>
|
|
</div>
|
|
<div class="agenda">
|
|
<div class="blue-agenda"></div>
|
|
<div class="agenda-desc">Upcoming Event</div>
|
|
</div>
|
|
<div id="divToday" class="divToday">Today</div>
|
|
</div>
|
|
</div>
|
|
<div class="event-info" id="eventInfo">
|
|
Select a date
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.calendar-header-button {
|
|
background-color: #ebe8f3;
|
|
border-radius: 50%;
|
|
width: 40px;
|
|
height: 40px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
color: #3c228a;
|
|
cursor: pointer;
|
|
transition: opacity 0.2s;
|
|
border: none;
|
|
}
|
|
.divToday:hover {
|
|
cursor: pointer;
|
|
}
|
|
.divToday {
|
|
background-color: black;
|
|
color: white;
|
|
font-weight: 700;
|
|
padding: 7px;
|
|
border-radius: 10px;
|
|
align-items: center;
|
|
text-align: center;
|
|
border: 1px solid;
|
|
width: 100px;
|
|
align-self: center;
|
|
color: white;
|
|
}
|
|
.calendar-footer {
|
|
margin-top: 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
.agenda {
|
|
display: flex;
|
|
gap: 10px;
|
|
}
|
|
.red-agenda {
|
|
width: 15px;
|
|
height: 15px;
|
|
background-color: #bd0074;
|
|
border-radius: 50%;
|
|
}
|
|
.blue-agenda {
|
|
width: 15px;
|
|
height: 15px;
|
|
background-color: #B5ABD3;
|
|
border-radius: 50%;
|
|
}
|
|
.wrapper-cal {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
/* background-color: #f4f4f4; */
|
|
flex-direction: column;
|
|
}
|
|
.calendar {
|
|
background: #fff;
|
|
padding: 1.5rem;
|
|
border-radius: 16px;
|
|
border: 1px solid;
|
|
box-shadow: 1px 10px 20px 6px rgba(0, 0, 0, 0.1);
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
.calendar-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
|
|
|
|
.calendar-header span {
|
|
font-size: 1rem;
|
|
font-weight: bold;
|
|
color: #5f676e;
|
|
}
|
|
|
|
.day-names, .calendar-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(7, 1fr);
|
|
text-align: center;
|
|
}
|
|
|
|
.day-names div {
|
|
font-weight: 400;
|
|
color: #5f676e;
|
|
padding-bottom: 0.5rem;
|
|
font-size: 0.85rem;
|
|
}
|
|
.calendar-grid div {
|
|
padding: 0.7rem 0;
|
|
border-radius: 50%;
|
|
position: relative;
|
|
font-size: 0.9rem;
|
|
color: #222;
|
|
width: 40px;
|
|
height: 40px;
|
|
line-height: 36px;
|
|
margin: 2px auto;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
color: #5f676e;
|
|
}
|
|
.agenda-desc {
|
|
font-weight: 400;
|
|
color: #5f676e;
|
|
}
|
|
.calendar-grid div:hover {
|
|
background: #8080802e;
|
|
color: #5f676e !important;
|
|
}
|
|
|
|
.other-month {
|
|
color: #ccc !important;
|
|
}
|
|
|
|
.fade-message {
|
|
animation: fadeSlideIn 0.4s ease both;
|
|
}
|
|
|
|
.today {
|
|
background-color: #bd0074;
|
|
color: #fff !important;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.has-event {
|
|
background-color: #B5ABD3;
|
|
color: #fff !important;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.today.has-event {
|
|
background-color: purple;
|
|
color: #fff !important;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.event-info {
|
|
margin-top: 2rem;
|
|
background: #eee;
|
|
padding: 1rem;
|
|
border-radius: 8px;
|
|
font-size: 0.95rem;
|
|
text-align: center;
|
|
width: 100%;
|
|
/* min-height: 300px; */
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.event-card {
|
|
background: white;
|
|
padding: 1rem;
|
|
border-radius: 8px;
|
|
margin-bottom: 0.5rem;
|
|
text-align: left;
|
|
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
|
width: 100%;
|
|
animation: fadeSlideIn 0.4s ease both;
|
|
}
|
|
|
|
.event-card h4 {
|
|
margin: 0 0 0.25rem;
|
|
}
|
|
|
|
.event-card .date {
|
|
color: #555;
|
|
font-size: 0.85rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.event-card a {
|
|
display: inline-block;
|
|
margin-top: 0.5rem;
|
|
text-decoration: none;
|
|
color: white;
|
|
background: #007BFF;
|
|
padding: 0.4rem 0.8rem;
|
|
border-radius: 6px;
|
|
font-size: 0.85rem;
|
|
}
|
|
|
|
.selected-day {
|
|
outline: 2px solid #9C9C9C;
|
|
background: #8080802e;
|
|
color: #5f676e !important;
|
|
}
|
|
@keyframes fadeSlideIn {
|
|
0% {
|
|
opacity: 0;
|
|
transform: translateY(10px);
|
|
}
|
|
100% {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
const rawEventData = "{{ event | strip_newlines }}";
|
|
const events = rawEventData
|
|
.split('$$')
|
|
.filter(e => e)
|
|
.map(item => {
|
|
const [title, day, month, year, id] = item.split(',');
|
|
return {
|
|
title: title.trim(),
|
|
day: parseInt(day),
|
|
month: month.trim(),
|
|
year: parseInt(year),
|
|
id: id.trim()
|
|
};
|
|
});
|
|
|
|
const monthYear = document.getElementById('monthYear');
|
|
const calendarGrid = document.getElementById('calendarGrid');
|
|
const prevBtn = document.getElementById('prev');
|
|
const nextBtn = document.getElementById('next');
|
|
const eventInfo = document.getElementById('eventInfo');
|
|
const divToday = document.getElementById('divToday');
|
|
|
|
let currentDate = new Date();
|
|
let selectedDayElement = null;
|
|
|
|
function renderCalendar(date) {
|
|
const year = date.getFullYear();
|
|
const month = date.getMonth();
|
|
|
|
const firstDayOfMonth = new Date(year, month, 1);
|
|
const startDay = firstDayOfMonth.getDay();
|
|
|
|
const lastDateOfMonth = new Date(year, month + 1, 0).getDate();
|
|
const lastDatePrevMonth = new Date(year, month, 0).getDate();
|
|
|
|
const monthName = date.toLocaleString('en-US', { month: 'long' });
|
|
monthYear.textContent = `${monthName} ${year}`;
|
|
calendarGrid.innerHTML = '';
|
|
|
|
const today = new Date();
|
|
const isToday = (d) =>
|
|
d.getDate() === today.getDate() &&
|
|
d.getMonth() === today.getMonth() &&
|
|
d.getFullYear() === today.getFullYear();
|
|
|
|
for (let i = 0; i < 42; i++) {
|
|
const dayCell = document.createElement('div');
|
|
let dayNum, actualMonth = month, actualYear = year;
|
|
|
|
if (i < startDay) {
|
|
dayNum = lastDatePrevMonth - startDay + i + 1;
|
|
actualMonth = month - 1;
|
|
if (actualMonth < 0) {
|
|
actualMonth = 11;
|
|
actualYear -= 1;
|
|
}
|
|
dayCell.classList.add('other-month');
|
|
} else if (i >= startDay + lastDateOfMonth) {
|
|
dayNum = i - (startDay + lastDateOfMonth) + 1;
|
|
actualMonth = month + 1;
|
|
if (actualMonth > 11) {
|
|
actualMonth = 0;
|
|
actualYear += 1;
|
|
}
|
|
dayCell.classList.add('other-month');
|
|
} else {
|
|
dayNum = i - startDay + 1;
|
|
}
|
|
|
|
dayCell.textContent = dayNum;
|
|
const displayDate = new Date(actualYear, actualMonth, dayNum);
|
|
const displayMonthName = displayDate.toLocaleString('en-US', { month: 'long' });
|
|
|
|
const isTodayDate = isToday(displayDate);
|
|
const matchingEvents = events.filter(ev =>
|
|
ev.day === dayNum &&
|
|
ev.month === displayMonthName &&
|
|
ev.year === actualYear
|
|
);
|
|
|
|
if (isTodayDate) dayCell.classList.add('today');
|
|
if (matchingEvents.length > 0) dayCell.classList.add('has-event');
|
|
|
|
dayCell.addEventListener('click', () => {
|
|
if (selectedDayElement) {
|
|
selectedDayElement.classList.remove('selected-day');
|
|
}
|
|
dayCell.classList.add('selected-day');
|
|
selectedDayElement = dayCell;
|
|
renderEventInfo(displayDate, matchingEvents);
|
|
});
|
|
|
|
calendarGrid.appendChild(dayCell);
|
|
}
|
|
}
|
|
|
|
function renderEventInfo(dateObj, matchedEvents) {
|
|
if (matchedEvents.length === 0) {
|
|
eventInfo.innerHTML = `<p class="fade-message">No events for selected date</p>`;
|
|
return;
|
|
}
|
|
|
|
eventInfo.innerHTML = matchedEvents.map(ev => `
|
|
<div class="event-card">
|
|
<h4>${ev.title}</h4>
|
|
<div class="date">${ev.day} ${ev.month} ${ev.year}</div>
|
|
<a href="/app/training_sessions/${ev.id}">View</a>
|
|
</div>
|
|
`).join('');
|
|
}
|
|
|
|
divToday.addEventListener('click', () => {
|
|
currentDate = new Date();
|
|
renderCalendar(currentDate);
|
|
eventInfo.innerHTML = "Select a date";
|
|
});
|
|
|
|
prevBtn.addEventListener('click', () => {
|
|
currentDate.setMonth(currentDate.getMonth() - 1);
|
|
renderCalendar(currentDate);
|
|
eventInfo.innerHTML = "Select a date";
|
|
});
|
|
|
|
nextBtn.addEventListener('click', () => {
|
|
currentDate.setMonth(currentDate.getMonth() + 1);
|
|
renderCalendar(currentDate);
|
|
eventInfo.innerHTML = "Select a date";
|
|
});
|
|
|
|
renderCalendar(currentDate);
|
|
</script> |