Files

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>