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');
        ...