Folks, ChatGPT is just going around in circles with this.
Here's the problem.
(See picture)
Normally the Zoom is 133%.
So this is really stepping back from things.
It is supposed to be a calendar that shows me upcoming bills. (red) and 4 days leading up to them.
Today is circled in blue.
But I'm working on how to add new bills - in case I missed them and want to add them.
So at the bottom is/are buttons to add bills.
(and there are two for reasons unknown.)
This is what it should look like - WRT zom
Here's the code:
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:5px">
<button id="prevBtn">◀ Prev</button>
<span id="monthLabel" style="font-weight:bold"></span>
<button id="nextBtn">Next ▶</button>
</div>
<div id="calendar"></div>
<div style="margin-top:10px;border-top:1px solid #666;padding-top:10px">
<h4>Add Bill</h4>
<label>Day <input type="number" id="billDay" min="1" max="31"></label>
<label>Month <input type="number" id="billMonth" min="1" max="12"></label>
<label>Label <input type="text" id="billLabel"></label>
<label>Color <input type="color" id="billColor" value="#e53935"></label>
<label>Lead Days <input type="number" id="billLead" min="0" max="10" value="4"></label>
<button id="addBillBtn">Add Bill</button>
</div>
<script>
(function(scope){
const leadDayColor = "#CE93D8"
let billsData = []
let viewMonth = (new Date()).getMonth()
let viewYear = (new Date()).getFullYear()
function renderCalendar(bills, month, year){
const calendarEl = document.getElementById("calendar")
const monthLabel = document.getElementById("monthLabel")
if(!calendarEl || !monthLabel) return
const today = new Date()
const todayDate = today.getDate()
const currentMonth = today.getMonth()
const currentYear = today.getFullYear()
const firstDay = new Date(year, month, 1).getDay()
const daysInMonth = new Date(year, month+1, 0).getDate()
const monthNames = ["January","February","March","April","May","June","July","August","September","October","November","December"]
monthLabel.textContent = monthNames[month] + " " + year
const billsThisMonth = bills.filter(b => b.month === month+1)
const billMap = {}, leadMap = {}
billsThisMonth.forEach(bill => {
if(!billMap[bill.day]) billMap[bill.day] = { color: bill.color, labels: [] }
billMap[bill.day].labels.push(bill.label)
for(let i=1;i<=bill.leadDays;i++){
const leadDay = bill.day-i
if(leadDay>0 && !billMap[leadDay]){
if(!leadMap[leadDay]) leadMap[leadDay] = { color: leadDayColor, labels: [] }
leadMap[leadDay].labels.push(bill.label)
}
}
})
let html = "<table><thead><tr><th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th></tr></thead><tbody><tr>"
for(let i=0;i<firstDay;i++) html += "<td></td>"
for(let day=1;day<=daysInMonth;day++){
const isBillDay = billMap[day], isLeadDay = leadMap[day]
let bgColor='', textColor='', tooltip=''
if(isBillDay){ bgColor=isBillDay.color; textColor='black'; tooltip=isBillDay.labels.join("\n") }
else if(isLeadDay){ bgColor=isLeadDay.color; textColor='black'; tooltip=isLeadDay.labels.join("\n") }
else { bgColor='#2a2a2a'; textColor='#eee' }
const isToday = day===todayDate && month===currentMonth && year===currentYear
html += `<td style="background-color:${bgColor};color:${textColor}" title="${tooltip}" ${isToday ? 'class="today"' : ''}>${day}</td>`
if((firstDay+day)%7===0 && day!==daysInMonth) html += "</tr><tr>"
}
const totalCells = firstDay+daysInMonth
const emptyCells = totalCells%7===0 ? 0 : 7-(totalCells%7)
for(let i=0;i<emptyCells;i++) html += "<td></td>"
html += "</tr></tbody></table>"
calendarEl.innerHTML = html
}
document.getElementById("prevBtn").onclick = () => {
viewMonth--
if(viewMonth<0){ viewMonth=11; viewYear-- }
renderCalendar(billsData, viewMonth, viewYear)
}
document.getElementById("nextBtn").onclick = () => {
viewMonth++
if(viewMonth>11){ viewMonth=0; viewYear++ }
renderCalendar(billsData, viewMonth, viewYear)
}
scope.$watch('msg.payload', function(payload){
if(payload && payload.bills){
billsData = payload.bills
const now = new Date()
viewMonth = now.getMonth()
viewYear = now.getFullYear()
renderCalendar(billsData, viewMonth, viewYear)
}
})
document.getElementById('addBillBtn').onclick = function(){
const day=parseInt(document.getElementById('billDay').value)
const month=parseInt(document.getElementById('billMonth').value)
const label=document.getElementById('billLabel').value
const color=document.getElementById('billColor').value
const leadDays=parseInt(document.getElementById('billLead').value)
if(!day || !month || !label){ alert('Day, Month, and Label are required'); return }
const newBill={ day, month, label, color, leadDays }
if(!scope.msg.payload.bills) scope.msg.payload.bills=[]
scope.msg.payload.bills.push(newBill)
billsData.push(newBill)
renderCalendar(billsData, viewMonth, viewYear)
scope.send({ payload: scope.msg.payload.bills })
}
})(scope)
</script>
Could someone have a look and help me please?
DB 1.0
Grid size 48 x 48
Widget spacing 5 x 5
Group padding 0 x 0
Group spacing 5 x 5
Not sure if there are any other Monkeys under the hood.
But I believe my CSS codes are mostly local.
Yes, there are some global ones, but they are for buttons.
Yes, I should study this a bit more, but just now is not a good time for me - yeah, maybe an excuse.
But as I see it, it is more a reason than excuse.
Anyway...... Please?


