var year = 2025
var month = 8
const monthNames = ["", "January", "February", "March", "April", "May", "June","July", "August", "September", "October", "November", "December"];
var eventsByDay = {
3: ["Chicken Stir Fry", "Salad"],
8: ["Spaghetti Bolognese"],
12: ["Fish Tacos", "Rice", "Beans"],
31: ['Brats']
};
async function changeSite(site){
console.log(site)
const response = await fetch(`/changeSite`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
site: site,
}),
});
data = await response.json();
transaction_status = "success"
if (data.error){
transaction_status = "danger"
}
UIkit.notification({
message: data.message,
status: transaction_status,
pos: 'top-right',
timeout: 5000
});
location.reload(true)
}
async function getEventsByMonth() {
const url = new URL('/planner/api/getEventsByMonth', window.location.origin);
url.searchParams.append('year', year);
url.searchParams.append('month', month);
const response = await fetch(url);
data = await response.json();
return data.events;
}
async function getEventByUUID(event_uuid) {
const url = new URL('/planner/api/getEventByUUID', window.location.origin);
url.searchParams.append('event_uuid', event_uuid);
const response = await fetch(url);
data = await response.json();
return data.event;
}
async function parseEvents(events) {
eventsByDay = {}
for (let i = 0; i < events.length; i++){
console.log(`new event -- ${events[i].event_shortname}`)
let event_date_start = new Date(events[i].event_date_start)
let event_date_end = new Date(events[i].event_date_end)
let this_month = month
let start_day = event_date_start.getUTCDate()
let start_month = event_date_start.getUTCMonth() + 1
let end_day = event_date_end.getUTCDate()
let end_month = event_date_end.getUTCMonth() + 1
if(start_month !== this_month){
start_day = 1
}
if(end_month !== this_month){
end_day = new Date(year, month, 0).getUTCDate();
}
for (let y = start_day; y <= end_day; y++){
if (!eventsByDay[y]) {
eventsByDay[y] = [];
}
let dayarray = eventsByDay[y]
dayarray.push(events[i])
eventsByDay[y] = dayarray
}
}
console.log(eventsByDay)
}
document.addEventListener('DOMContentLoaded', async function() {
let today = new Date();
year = today.getFullYear();
month = today.getMonth() + 1;
await setupCalendarAndEvents()
})
async function setupCalendarAndEvents(){
console.log(year, month)
events = await getEventsByMonth()
await parseEvents(events)
await createCalender()
document.getElementById('calender_table').addEventListener('contextmenu', function(e) {
e.preventDefault();
let recipeLabel = e.target.closest('.recipe-label');
let calendarCell = e.target.closest('.calendar-cell');
let customLabel = e.target.closest('.custom-label');
if (recipeLabel) {
recipeLabel.classList.add('recipe-label-selected')
let rect = recipeLabel.getBoundingClientRect();
let scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
let menuX = rect.left + scrollLeft;
let menuY = rect.bottom + scrollTop;
showContextMenuForEvent(recipeLabel, menuX, menuY);
} else if (customLabel) {
customLabel.classList.add('custom-label-selected')
let rect = customLabel.getBoundingClientRect();
let scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
let menuX = rect.left + scrollLeft;
let menuY = rect.bottom + scrollTop;
showContextMenuForEvent(customLabel, menuX, menuY);
} else if (calendarCell) {
calendarCell.classList.add('calendar-cell-selected')
let rect = calendarCell.getBoundingClientRect();
let scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;
let menuX = rect.left + scrollLeft;
let menuY = rect.bottom + scrollTop;
showContextMenuForCell(calendarCell, menuX, menuY);
} else {
hideContextMenu();
}
});
}
async function createCalender() {
let calender_container = document.getElementById('calendar_container')
calender_container.innerHTML = ""
let firstDay = new Date(year, month - 1, 1);
let numDays = new Date(year, month, 0).getDate();
let startDay = firstDay.getDay();
let calender_table = document.createElement('table')
calender_table.setAttribute('id', 'calender_table')
calender_table.setAttribute('class', 'uk-table uk-table-middle uk-table-large uk-table-responsive')
let table_headers = document.createElement('thead')
table_headers.innerHTML = `
| Sunday | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday |
`
calender_table.append(table_headers)
let tableRow = document.createElement('tr')
for (let i = 0; i < startDay; i++){
let table_cell = document.createElement('td')
table_cell.setAttribute('class', 'uk-table-expand uk-visible@m calendar-cell-empty')
tableRow.append(table_cell)
}
console.log(eventsByDay)
for (let day = 1; day <= numDays; day++) {
let table_cell = document.createElement('td')
let eventsHTML = "";
if (eventsByDay[day]) {
eventsByDay[day].forEach(event => {
if(event.event_type==="recipe" && event.has_missing_ingredients){
eventsHTML += `${event.event_shortname}
`;
} else if (event.event_type==="recipe" && !event.has_missing_ingredients){
eventsHTML += `${event.event_shortname}
`;
} else {
eventsHTML += `${event.event_shortname}
`;
}
});
}
table_cell.innerHTML = `${day}
${eventsHTML}
`;
table_cell.classList.add("calendar-cell");
table_cell.dataset.day = day;
tableRow.append(table_cell)
if ((startDay + day) % 7 === 0 && day !== numDays){
calender_table.append(tableRow)
tableRow = document.createElement('tr')
};
}
let lastDayOfWeek = (startDay + numDays - 1) % 7;
for (let i = lastDayOfWeek + 1; i <= 6; i++) {
let table_cell = document.createElement('td')
table_cell.setAttribute('class', 'uk-visible@m calendar-cell-empty')
tableRow.append(table_cell)
}
calender_table.append(tableRow)
let table_footer = document.createElement('tr')
table_footer.innerHTML = ` | | | | | | | `
calender_table.append(table_footer)
calender_container.append(calender_table)
document.getElementById("month-year-title").innerHTML = `${monthNames[month]} ${year}`;
}
function showContextMenuForEvent(eventLabel, x, y) {
const menu = document.getElementById('calendarContextMenu');
// Set only "Edit" and "Remove" (and optionally "Add Another")
menu.className = "uk-dropdown uk-open";
menu.innerHTML = `
`;
menu.style.display = 'block';
menu.style.left = x + 'px';
menu.style.top = y + 'px';
}
function showContextMenuForCell(calendarCell, x, y) {
const menu = document.getElementById('calendarContextMenu');
// Only "Add Event"
menu.className = "uk-dropdown uk-open";
menu.innerHTML = `
`;
menu.style.display = 'block';
menu.style.left = x + 'px';
menu.style.top = y + 'px';
}
window.addEventListener('click', function() {
document.getElementById('calendarContextMenu').style.display = 'none';
document.querySelectorAll('.calendar-cell-selected').forEach(el => el.classList.remove('calendar-cell-selected'));
document.querySelectorAll('.custom-label-selected').forEach(el => el.classList.remove('custom-label-selected'));
document.querySelectorAll('.recipe-label-selected').forEach(el => el.classList.remove('recipe-label-selected'));
});
async function addEvent(day) {
let menu = document.getElementById('calendarContextMenu');
//let day = menu.getAttribute('data-day')
console.log(year, month, day)
let customDate = new Date(year, month-1, day);
document.getElementById('event_date_start').value = customDate.toISOString().split('T')[0];
document.getElementById('event_date_end').value = customDate.toISOString().split('T')[0];
UIkit.modal(document.getElementById('eventModal')).show();
}
async function editEvent(event_uuid) {
console.log(event_uuid)
let event = await getEventByUUID(event_uuid)
console.log(event)
document.getElementById('event_uuid_edit').value = event_uuid
let event_date_start = new Date(event.event_date_start)
let y = event_date_start.getFullYear();
let m = event_date_start.getUTCMonth();
let d = event_date_start.getUTCDate();
event_date_start = new Date(y, m, d);
let event_date_end = new Date(event.event_date_end)
let end_y = event_date_end.getFullYear();
let end_m = event_date_end.getUTCMonth();
let end_d = event_date_end.getUTCDate();
event_date_end = new Date(end_y, end_m, end_d);
document.getElementById('event_date_edit_start').value = event_date_start.toISOString().split('T')[0]
document.getElementById('event_date_edit_end').value = event_date_end.toISOString().split('T')[0]
document.getElementById('event_type_edit').value = event.event_type
document.getElementById('recipe_label_modal_edit').value = event.recipe_uuid
document.getElementById('event_description_edit').value = event.event_description
document.getElementById('event_name_edit').value = event.event_shortname
if(event.event_type==="recipe"){
document.getElementById('event_name_edit').classList.add('uk-disabled')
document.getElementById('event_name_edit').classList.add('uk-form-blank')
document.getElementById('recipe_label_edit_parent').hidden = false
} else {
document.getElementById('event_name_edit').classList.remove('uk-disabled')
document.getElementById('event_name_edit').classList.remove('uk-form-blank')
document.getElementById('recipe_label_edit_parent').hidden = true
}
UIkit.modal(document.getElementById('eventEditModal')).show();
}
async function postNewEvent(){
let event_shortname = document.getElementById('event_name').value
let event_description = document.getElementById('event_description').value
let event_date_start = document.getElementById('event_date_start').value
let event_date_end = document.getElementById('event_date_end').value
let event_type = document.getElementById('event_type').value
let recipe_uuid = null
if (event_type === "recipe"){
recipe_uuid = document.getElementById('selected-recipe').value
}
const response = await fetch('/planner/api/addEvent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
event_shortname: event_shortname,
event_description: event_description,
event_date_start: event_date_start,
event_date_end: event_date_end,
recipe_uuid: recipe_uuid,
event_type: event_type
})
});
data = await response.json();
response_status = 'primary'
if (!data.status === 201){
response_status = 'danger'
}
UIkit.notification({
message: data.message,
status: response_status,
pos: 'top-right',
timeout: 5000
});
await setupCalendarAndEvents()
UIkit.modal(document.getElementById('eventModal')).hide();
}
async function postEditEvent(){
let event_uuid = document.getElementById('event_uuid_edit').value
let event_shortname = document.getElementById('event_name_edit').value
let event_description = document.getElementById('event_description_edit').value
let event_date_start = document.getElementById('event_date_edit_start').value
let event_date_end = document.getElementById('event_date_edit_end').value
let event_type = document.getElementById('event_type_edit').value
const response = await fetch('/planner/api/saveEvent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
event_uuid: event_uuid,
update: {
event_shortname: event_shortname,
event_description: event_description,
event_date_start: event_date_start,
event_date_end: event_date_end,
event_type: event_type
}
})
});
data = await response.json();
response_status = 'primary'
if (!data.status === 201){
response_status = 'danger'
}
UIkit.notification({
message: data.message,
status: response_status,
pos: 'top-right',
timeout: 5000
});
await setupCalendarAndEvents()
UIkit.modal(document.getElementById('eventEditModal')).hide();
}
async function postRemoveEvent(event_uuid){
const response = await fetch('/planner/api/removeEvent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
event_uuid: event_uuid
})
});
data = await response.json();
response_status = 'primary'
if (!data.status === 201){
response_status = 'danger'
}
UIkit.notification({
message: data.message,
status: response_status,
pos: 'top-right',
timeout: 5000
});
await setupCalendarAndEvents()
}
// main window functions
async function backOneMonth() {
if(month === 1){
year = year - 1
month = 12
} else {
month = month - 1
}
await setupCalendarAndEvents()
}
async function forwardOneMonth() {
if(month === 12){
year = year + 1
month = 1
} else {
month = month + 1
}
await setupCalendarAndEvents()
}
// Main Modal Functions
var eventModal_type = "recipe"
async function setEventTypeForm(){
let event_type = document.getElementById('event_type').value
document.getElementById('event_name').value = ""
document.getElementById('event_description').value = ""
document.getElementById('selected-recipe').value = ""
if(event_type === "custom"){
eventModal_type = "custom"
document.getElementById('recipe_button_modal').hidden = true
document.getElementById('recipe_label_modal').hidden = true
document.getElementById('event_name').classList.remove('uk-disabled')
} else if (event_type === "recipe"){
eventModal_type = "recipe"
document.getElementById('recipe_button_modal').hidden = false
document.getElementById('recipe_label_modal').hidden = false
document.getElementById('event_name').classList.add('uk-disabled')
}
}
// Select Row Modal Handlers
var eventModal_page = 1
var eventModal_end = 1
var eventModal_search = ""
var eventModal_limit = 50
async function selectRecipeEvent() {
document.getElementById('mainEventBody').hidden = true
document.getElementById('paginationModalBody').hidden = false
document.getElementById('eventsModalFooter').hidden = true
let recipes = await fetchRecipes()
await updateEventsPaginationElement()
await updateEventsTableWithRecipes(recipes)
}
async function fetchRecipes() {
const url = new URL('/planner/api/getRecipes', window.location.origin);
url.searchParams.append('page', eventModal_page);
url.searchParams.append('limit', eventModal_limit);
url.searchParams.append('search_string', eventModal_search);
const response = await fetch(url);
data = await response.json();
eventModal_end = data.end
return data.recipes;
}
async function updateEventsTableWithRecipes(recipes) {
let eventsTableBody = document.getElementById('eventsTableBody')
eventsTableBody.innerHTML = ""
for (let i = 0; i < recipes.length; i++){
let tableRow = document.createElement('tr')
let nameCell = document.createElement('td')
nameCell.innerHTML = `${recipes[i].name}`
let opCell = document.createElement('td')
let selectButton = document.createElement('button')
selectButton.setAttribute('class', 'uk-button uk-button-primary uk-button-small')
selectButton.innerHTML = "Select"
selectButton.onclick = async function() {
document.getElementById('selected-recipe').value = recipes[i].recipe_uuid
document.getElementById('event_name').value = recipes[i].name
document.getElementById('mainEventBody').hidden = false
document.getElementById('paginationModalBody').hidden = true
document.getElementById('eventsModalFooter').hidden = false
}
opCell.append(selectButton)
tableRow.append(nameCell, opCell)
eventsTableBody.append(tableRow)
}
}
async function setEventModalPage(pageNumber){
eventModal_page = pageNumber;
if (eventModal_type == "recipe"){
let records = await fetchRecipes()
}
await updateItemsModalTable(records)
await updateItemsPaginationElement()
}
async function updateEventsPaginationElement() {
let paginationElement = document.getElementById('eventPage');
paginationElement.innerHTML = "";
// previous
let previousElement = document.createElement('li')
if(eventModal_page<=1){
previousElement.innerHTML = ``;
previousElement.classList.add('uk-disabled');
}else {
previousElement.innerHTML = ``;
}
paginationElement.append(previousElement)
//first
let firstElement = document.createElement('li')
if(eventModal_page<=1){
firstElement.innerHTML = `1`;
firstElement.classList.add('uk-disabled');
}else {
firstElement.innerHTML = `1`;
}
paginationElement.append(firstElement)
// ...
if(eventModal_page-2>1){
let firstDotElement = document.createElement('li')
firstDotElement.classList.add('uk-disabled')
firstDotElement.innerHTML = `…`;
paginationElement.append(firstDotElement)
}
// last
if(eventModal_page-2>0){
let lastElement = document.createElement('li')
lastElement.innerHTML = `${eventModal_page-1}`
paginationElement.append(lastElement)
}
// current
if(eventModal_page!=1 && eventModal_page != eventModal_end){
let currentElement = document.createElement('li')
currentElement.innerHTML = `${eventModal_page}`
paginationElement.append(currentElement)
}
// next
if(eventModal_page+2${eventModal_page+1}`
paginationElement.append(nextElement)
}
// ...
if(eventModal_page+2<=eventModal_end){
let secondDotElement = document.createElement('li')
secondDotElement.classList.add('uk-disabled')
secondDotElement.innerHTML = `…`;
paginationElement.append(secondDotElement)
}
//end
let endElement = document.createElement('li')
if(eventModal_page>=eventModal_end){
endElement.innerHTML = `${eventModal_end}`;
endElement.classList.add('uk-disabled');
}else {
endElement.innerHTML = `${eventModal_end}`;
}
paginationElement.append(endElement)
//next button
let nextElement = document.createElement('li')
if(eventModal_page>=eventModal_end){
nextElement.innerHTML = ``;
nextElement.classList.add('uk-disabled');
}else {
nextElement.innerHTML = ``;
console.log(nextElement.innerHTML)
}
paginationElement.append(nextElement)
}