JSFiddle - React, Tailwind, and code Playground
by Haze32
HTML
<div class="tracker-container">
<h1>2025 Tracker Calendar</h1>
<div id="calendar"></div>
</div>
CSS
.tracker-container {
font-family: 'Segoe UI', Arial, sans-serif;
max-width: 900px;
margin: 30px auto;
background: #f9f9f9;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
color: #2c3e50;
margin-bottom: 25px;
font-size: 28px;
}
.month-section {
margin-bottom: 20px;
border-bottom: 1px solid #ddd;
padding-bottom: 15px;
}
.month-header {
background: #3498db;
color: white;
padding: 8px 15px;
border-radius: 5px;
margin-bottom: 10px;
font-size: 18px;
}
.week-row {
display: flex;
align-items: center;
margin: 8px 0;
padding: 5px;
background: white;
border-radius: 5px;
transition: all 0.2s ease;
}
.week-row.success {
background: #e8f5e9; /* Light green */
}
.week-row.failure {
background: #ffebee; /* Light red */
}
.week-row:hover {
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.tracker-box {
width: 35px;
height: 35px;
border: 2px solid #34495e;
border-radius: 4px;
position: relative;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
background: white;
margin: 0 3px;
transition: all 0.2s ease;
}
.tracker-box:hover:not(.locked) {
border-color: #2980b9;
}
.tracker-box.checked {
background: #c8e6c9; /* Light green for checked */
border-color: #27ae60;
}
...
JavaScript
const autoCheckDates = [
'2025-03-10',
'2025-04-15',
'2025-06-20'
];
function isAutoCheckDate(date) {
const dateString = date.toISOString().split('T')[0];
return autoCheckDates.includes(dateString);
}
function updateNotifier(weekRow) {
const boxes = weekRow.querySelectorAll('.tracker-box');
let allChecks = true;
let hasX = false;
boxes.forEach(box => {
const mark = box.dataset.mark || '';
if (mark === '✗') {
hasX = true;
allChecks = false;
} else if (mark !== '✓') {
allChecks = false;
}
});
const notifier = weekRow.querySelector('.notifier');
weekRow.classList.remove('success', 'failure');
if (allChecks && boxes.length === 5) {
notifier.textContent = '$';
notifier.style.color = '#27ae60';
weekRow.classList.add('success');
} else if (hasX) {
notifier.textContent = '✗';
notifier.style.color = '#e74c3c';
weekRow.classList.add('failure');
} else {
notifier.textContent = '';
}
}
function updateBoxStyle(box) {
box.classList.remove('checked', 'crossed');
const mark = box.dataset.mark || '';
if (mark === '✓') {
box.classList.add('checked');
} else if (mark === '✗') {
box.classList.add('crossed');
}
}
function closeAllOptions() {
document.querySelectorAll('.options.active').forEach(options => {
options.classList.remove('active');
});
}
function createCalendar() {
const calendar = document.getElementById('calendar');
...