GNU/skin/board/daily/write/write.script.php
<script>
(function() {
    window.updateFileName = function(input, index) {
        const fileName = input.files[0] ? input.files[0].name : 'No file selected';
        const fileNameElement = document.getElementById('file_name_' + index);
        if (!fileNameElement) return;
        fileNameElement.innerText = fileName;
        fileNameElement.style.color = '#00f2ff';
    };

    window.file_add = function() {
        const rows = document.querySelectorAll('.file-row:not(.active)');
        if (rows.length > 0) rows[0].classList.add('active');
    };

    function getCurrentDateTimeText() {
        const now = new Date();
        const year = now.getFullYear();
        const month = String(now.getMonth() + 1).padStart(2, '0');
        const day = String(now.getDate()).padStart(2, '0');
        const hour = String(now.getHours()).padStart(2, '0');
        const minute = String(now.getMinutes()).padStart(2, '0');
        const second = String(now.getSeconds()).padStart(2, '0');
        return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
    }

    function createWorkLineRow(contentValue, timeValue) {
        const wrap = document.createElement('div');
        wrap.className = 'work-line-row';

        const timeWrap = document.createElement('div');
        timeWrap.className = 'work-line-time-wrap';

        const caption = document.createElement('span');
        caption.className = 'field-caption no-margin';
        caption.textContent = '기록 시간';

        const timeInput = document.createElement('input');
        timeInput.type = 'text';
        timeInput.className = 'work-line-time';
        timeInput.readOnly = true;
        timeInput.value = timeValue && String(timeValue).trim() !== '' ? timeValue : getCurrentDateTimeText();

        const contentArea = document.createElement('textarea');
        contentArea.className = 'work-line-content';
        contentArea.rows = 4;
        contentArea.placeholder = '작업 내용을 입력하세요';
        contentArea.value = contentValue || '';

        timeWrap.appendChild(caption);
        timeWrap.appendChild(timeInput);
        wrap.appendChild(timeWrap);
        wrap.appendChild(contentArea);

        return wrap;
    }

    function serializeWorkLine() {
        const serializedInput = document.getElementById('x2_line_serialized');
        if (!serializedInput) return;

        const rows = document.querySelectorAll('#workLineRows .work-line-row');
        const chunks = [];

        rows.forEach(function(row) {
            const contentElement = row.querySelector('.work-line-content');
            const timeElement = row.querySelector('.work-line-time');
            const content = contentElement ? contentElement.value.trim() : '';
            const time = timeElement ? timeElement.value.trim() : getCurrentDateTimeText();

            if (!content) return;

            const cleanedContent = content.replace(/[\^@]/g, ' ');
            const cleanedTime = (time || getCurrentDateTimeText()).replace(/[\^@]/g, ' ');
            chunks.push(cleanedContent + '^' + cleanedTime);
        });

        serializedInput.value = chunks.length > 0 ? chunks.join('@') + '@' : '';
    }

    function bindNoteDrawer() {
        const memoButton = document.getElementById('note-toggle-btn');
        const drawer = document.getElementById('note-drawer');
        const backdrop = document.getElementById('note-drawer-backdrop');
        const closeButton = document.getElementById('note-drawer-close');
        if (!memoButton || !drawer || !backdrop || !closeButton) return;

        const syncState = function(opened) {
            drawer.classList.toggle('open', opened);
            backdrop.classList.toggle('open', opened);
            drawer.setAttribute('aria-hidden', opened ? 'false' : 'true');
            memoButton.setAttribute('aria-expanded', opened ? 'true' : 'false');
        };

        memoButton.addEventListener('click', function() {
            syncState(!drawer.classList.contains('open'));
        });

        closeButton.addEventListener('click', function() {
            syncState(false);
        });

        backdrop.addEventListener('click', function() {
            syncState(false);
        });
    }

    function bindMemoToggle() {
        const memoButton = document.getElementById('memo-toggle-btn');
        const memoArea = document.getElementById('memo-area');
        if (!memoButton || !memoArea) return;

        memoButton.addEventListener('click', function() {
            const opened = !memoArea.classList.contains('open');
            memoArea.classList.toggle('open', opened);
            memoButton.setAttribute('aria-expanded', opened ? 'true' : 'false');
        });
    }

    function bindRoutinePopup() {
        const openButton = document.getElementById('routine-popup-open');
        const popup = document.getElementById('routine-popup');
        const backdrop = document.getElementById('routine-popup-backdrop');
        const closeButton = document.getElementById('routine-popup-close');
        if (!openButton || !popup || !backdrop || !closeButton) return;

        const syncState = function(opened) {
            popup.classList.toggle('open', opened);
            popup.setAttribute('aria-hidden', opened ? 'false' : 'true');
        };

        openButton.addEventListener('click', function() {
            syncState(true);
        });

        closeButton.addEventListener('click', function() {
            syncState(false);
        });

        backdrop.addEventListener('click', function() {
            syncState(false);
        });
    }

    function bindWorkLineAdd() {
        const addButton = document.getElementById('btn-add-work-line');
        const rowsContainer = document.getElementById('workLineRows');
        if (!addButton || !rowsContainer) return;

        addButton.addEventListener('click', function() {
            rowsContainer.appendChild(createWorkLineRow('', getCurrentDateTimeText()));
        });
    }

    function bindDateTimePicker() {
        ['wr_date_custom', 'wr_time_custom'].forEach(function(id) {
            const field = document.getElementById(id);
            if (!field) return;

            const openPicker = function() {
                if (typeof field.showPicker === 'function') {
                    field.showPicker();
                }
            };

            field.addEventListener('click', openPicker);
            field.addEventListener('focus', openPicker);
        });
    }

    function bindOptionToggleSwitches() {
        const toggleSwitches = document.querySelectorAll('.option-toggle-switch[data-target]');
        if (!toggleSwitches.length) return;

        toggleSwitches.forEach(function(toggle) {
            const targetId = toggle.getAttribute('data-target');
            const targetPanel = targetId ? document.getElementById(targetId) : null;
            const toggleInput = toggle.querySelector('.option-toggle-input');
            if (!targetPanel) return;

            const syncState = function(opened) {
                targetPanel.classList.toggle('open', opened);
                toggle.classList.toggle('is-on', opened);
                toggle.setAttribute('aria-expanded', opened ? 'true' : 'false');
                if (toggleInput) {
                    toggleInput.checked = opened;
                }
            };

            syncState(targetPanel.classList.contains('open'));

            if (toggleInput) {
                toggleInput.addEventListener('change', function() {
                    syncState(toggleInput.checked);
                });
            }

            toggle.addEventListener('click', function(event) {
                if (event.target && event.target.classList && event.target.classList.contains('option-toggle-input')) {
                    return;
                }
                event.preventDefault();
                syncState(!targetPanel.classList.contains('open'));
            });
        });
    }

    window.fwrite_submit = function(f) {
        <?php echo $editor_js; ?>

        if (!f.x2_ca2.value || !f.x2_ca3.value || !f.x2_ca4.value) {
            alert('종류, 형태, 상태는 필수 입력입니다.');
            return false;
        }

        serializeWorkLine();
        return true;
    };

    bindNoteDrawer();
    bindMemoToggle();
    bindRoutinePopup();
    bindWorkLineAdd();
    bindDateTimePicker();
    bindOptionToggleSwitches();
})();
</script>

<script>
$(function() {
    $('.weather-toggle-input').on('change click', function(e) {
        e.stopPropagation();
        e.preventDefault();
    });

    $('.extra-toggle-input').on('change click', function(e) {
        e.stopPropagation();
        e.preventDefault();
    });

    $('#weather-toggle-btn').on('click', function(e) {
        e.stopPropagation();
        e.preventDefault();
        var $inner = $('#weather-row-inner');
        var $label = $(this);
        var isOn = $label.hasClass('is-on');
        if (isOn) {
            $label.removeClass('is-on').attr('aria-expanded', 'false');
            $label.find('.weather-toggle-input').prop('checked', false);
            $inner.slideUp();
        } else {
            $label.addClass('is-on').attr('aria-expanded', 'true');
            $label.find('.weather-toggle-input').prop('checked', true);
            $inner.slideDown();
        }
    });

    $('#extra-toggle-btn').on('click', function(e) {
        e.stopPropagation();
        e.preventDefault();
        var $inner = $('#extra-row-inner');
        var $label = $(this);
        var isOn = $label.hasClass('is-on');
        if (isOn) {
            $label.removeClass('is-on').attr('aria-expanded', 'false');
            $label.find('.extra-toggle-input').prop('checked', false);
            $inner.slideUp();
        } else {
            $label.addClass('is-on').attr('aria-expanded', 'true');
            $label.find('.extra-toggle-input').prop('checked', true);
            $inner.slideDown();
        }
    });
});
</script>