← back to jiho5755-maker__pressco21

Function bodies 302 total

All specs Real LLM only Function bodies
openReplyModal function · javascript · L1043-L1087 (45 LOC)
파트너클래스/파트너/js.js
    function openReplyModal(reviewId) {
        var modal = document.getElementById('pdReplyModal');
        if (!modal) return;

        // 원본 후기 찾기 (querySelector injection 방지: 루프로 안전하게 검색)
        var reviewCard = null;
        var allReviewCards = document.querySelectorAll('.partner-dashboard .pd-review-card');
        for (var rc = 0; rc < allReviewCards.length; rc++) {
            if (allReviewCards[rc].getAttribute('data-review-id') === reviewId) {
                reviewCard = allReviewCards[rc];
                break;
            }
        }
        var previewEl = document.getElementById('pdReplyReviewPreview');
        var textarea = document.getElementById('pdReplyTextarea');
        var charCountEl = document.getElementById('pdReplyCharCount');
        var submitBtn = document.getElementById('pdReplySubmit');

        if (previewEl && reviewCard) {
            var textEl = reviewCard.querySelector('.pd-review-card__text');
            previewEl.textContent = textEl ? textEl
submitReply function · javascript · L1094-L1120 (27 LOC)
파트너클래스/파트너/js.js
    function submitReply(reviewId, answer) {
        if (!answer || !answer.trim()) {
            showToast('\uB2F5\uBCC0 \uB0B4\uC6A9\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.', 'error');
            return;
        }

        showLoading();

        postGAS('replyToReview', {
            member_id: memberId,
            review_id: reviewId,
            answer: answer.trim()
        }, function(err, data) {
            hideLoading();

            if (err || !data || !data.success) {
                showToast('\uB2F5\uBCC0 \uC800\uC7A5\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.', 'error');
                return;
            }

            showToast('\uB2F5\uBCC0\uC774 \uC800\uC7A5\uB418\uC5C8\uC2B5\uB2C8\uB2E4.', 'success');
            closeModal('pdReplyModal');

            // 후기 새로고침
            loadReviews();
        });
    }
renderReviewPagination function · javascript · L1126-L1174 (49 LOC)
파트너클래스/파트너/js.js
    function renderReviewPagination(pagination) {
        var container = document.getElementById('pdReviewPagination');
        if (!container) return;

        /* GAS 응답: total_pages (스네이크 케이스) */
        var totalPages = pagination.total_pages || pagination.totalPages || 1;
        var page = pagination.page || 1;

        if (totalPages <= 1) {
            container.style.display = 'none';
            return;
        }

        container.style.display = 'flex';

        var html = '';

        // 이전 버튼
        html += '<button class="pd-pagination__btn' + (page <= 1 ? ' is-disabled' : '') + '" data-page="' + (page - 1) + '"'
            + (page <= 1 ? ' disabled' : '') + '>'
            + '<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M9 3L5 7l4 4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>'
            + '</button>';

        // 페이지 번호
        for (var p = 1; p <= totalPages; p++) {
            html += '<b
bindMonthSelector function · javascript · L1184-L1199 (16 LOC)
파트너클래스/파트너/js.js
    function bindMonthSelector() {
        var prevBtn = document.getElementById('pdMonthPrev');
        var nextBtn = document.getElementById('pdMonthNext');

        if (prevBtn) {
            prevBtn.addEventListener('click', function() {
                changeMonth(-1);
            });
        }

        if (nextBtn) {
            nextBtn.addEventListener('click', function() {
                changeMonth(1);
            });
        }
    }
changeMonth function · javascript · L1205-L1219 (15 LOC)
파트너클래스/파트너/js.js
    function changeMonth(delta) {
        var parts = currentMonth.split('-');
        var year = parseInt(parts[0]);
        var month = parseInt(parts[1]);

        month += delta;
        if (month > 12) { month = 1; year++; }
        if (month < 1) { month = 12; year--; }

        currentMonth = year + '-' + padZero(month);
        updateMonthLabel();

        // 데이터 새로고침
        loadDashboard();
    }
updateMonthLabel function · javascript · L1224-L1230 (7 LOC)
파트너클래스/파트너/js.js
    function updateMonthLabel() {
        var labelEl = document.getElementById('pdMonthLabel');
        if (!labelEl) return;

        var parts = currentMonth.split('-');
        labelEl.textContent = parts[0] + '\uB144 ' + parseInt(parts[1]) + '\uC6D4';
    }
populateClassDropdowns function · javascript · L1240-L1260 (21 LOC)
파트너클래스/파트너/js.js
    function populateClassDropdowns() {
        var dropdowns = ['pdBookingClass', 'pdReviewClass'];

        for (var d = 0; d < dropdowns.length; d++) {
            var select = document.getElementById(dropdowns[d]);
            if (!select) continue;

            // 기존 옵션 (첫 번째 "전체 강의"는 유지)
            var firstOption = select.querySelector('option');
            select.innerHTML = '';
            if (firstOption) select.appendChild(firstOption);

            for (var i = 0; i < myClasses.length; i++) {
                var cls = myClasses[i];
                var option = document.createElement('option');
                option.value = cls.class_id || '';
                option.textContent = cls.class_name || '';
                select.appendChild(option);
            }
        }
    }
Repobility analyzer · published findings · https://repobility.com
populateRevenueMonths function · javascript · L1265-L1283 (19 LOC)
파트너클래스/파트너/js.js
    function populateRevenueMonths() {
        var select = document.getElementById('pdRevenueMonth');
        if (!select) return;

        select.innerHTML = '';

        var now = new Date();
        for (var i = 0; i < 6; i++) {
            var d = new Date(now.getFullYear(), now.getMonth() - i, 1);
            var val = d.getFullYear() + '-' + padZero(d.getMonth() + 1);
            var label = d.getFullYear() + '\uB144 ' + (d.getMonth() + 1) + '\uC6D4';

            var option = document.createElement('option');
            option.value = val;
            option.textContent = label;
            if (val === currentMonth) option.selected = true;
            select.appendChild(option);
        }
    }
bindModalEvents function · javascript · L1293-L1318 (26 LOC)
파트너클래스/파트너/js.js
    function bindModalEvents() {
        // 닫기 버튼, 배경 클릭, 취소 버튼
        var modals = document.querySelectorAll('.partner-dashboard .pd-modal');
        for (var i = 0; i < modals.length; i++) {
            (function(modal) {
                var closeBtn = modal.querySelector('.pd-modal__close');
                var cancelBtn = modal.querySelector('.pd-modal__cancel');
                var backdrop = modal.querySelector('.pd-modal__backdrop');

                if (closeBtn) closeBtn.addEventListener('click', function() { closeModal(modal.id); });
                if (cancelBtn) cancelBtn.addEventListener('click', function() { closeModal(modal.id); });
                if (backdrop) backdrop.addEventListener('click', function() { closeModal(modal.id); });
            })(modals[i]);
        }

        // 후기 답변 저장 버튼
        var replySubmitBtn = document.getElementById('pdReplySubmit');
        if (replySubmitBtn) {
            replySubmitBtn.addEventListener('click', function() {
           
openModal function · javascript · L1324-L1330 (7 LOC)
파트너클래스/파트너/js.js
    function openModal(modalId) {
        var modal = document.getElementById(modalId);
        if (modal) {
            modal.style.display = 'flex';
            document.body.style.overflow = 'hidden';
        }
    }
closeModal function · javascript · L1336-L1342 (7 LOC)
파트너클래스/파트너/js.js
    function closeModal(modalId) {
        var modal = document.getElementById(modalId);
        if (modal) {
            modal.style.display = 'none';
            document.body.style.overflow = '';
        }
    }
showToast function · javascript · L1354-L1373 (20 LOC)
파트너클래스/파트너/js.js
    function showToast(message, type) {
        var container = document.getElementById('pdToastContainer');
        if (!container) return;

        var toast = document.createElement('div');
        toast.className = 'pd-toast pd-toast--' + (type || 'success');
        toast.textContent = message;

        container.appendChild(toast);

        // 3초 후 자동 제거
        setTimeout(function() {
            toast.style.animation = 'pdToastOut 0.3s ease-out forwards';
            setTimeout(function() {
                if (toast.parentNode) {
                    toast.parentNode.removeChild(toast);
                }
            }, 300);
        }, 3000);
    }
callGAS function · javascript · L1386-L1416 (31 LOC)
파트너클래스/파트너/js.js
    function callGAS(action, params, callback) {
        var queryParams = new URLSearchParams();
        queryParams.append('action', action);

        if (params) {
            var keys = Object.keys(params);
            for (var i = 0; i < keys.length; i++) {
                var val = params[keys[i]];
                if (val !== undefined && val !== null && val !== '') {
                    queryParams.append(keys[i], val);
                }
            }
        }

        var url = GAS_URL + '?' + queryParams.toString();

        fetch(url, { method: 'GET', redirect: 'follow' })
            .then(function(response) {
                if (!response.ok) {
                    throw new Error('HTTP ' + response.status);
                }
                return response.json();
            })
            .then(function(data) {
                callback(null, data);
            })
            .catch(function(err) {
                console.error('[PartnerDash] API \uD638\uCD9C \uC2E4\uD328
postGAS function · javascript · L1424-L1446 (23 LOC)
파트너클래스/파트너/js.js
    function postGAS(action, data, callback) {
        var url = GAS_URL + '?action=' + encodeURIComponent(action);

        fetch(url, {
            method: 'POST',
            redirect: 'follow',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(data)
        })
            .then(function(response) {
                if (!response.ok) {
                    throw new Error('HTTP ' + response.status);
                }
                return response.json();
            })
            .then(function(resData) {
                callback(null, resData);
            })
            .catch(function(err) {
                console.error('[PartnerDash] POST \uC2E4\uD328 (' + action + '):', err);
                callback(err, null);
            });
    }
renderStars function · javascript · L1459-L1471 (13 LOC)
파트너클래스/파트너/js.js
    function renderStars(rating, prefix) {
        var html = '';
        var filled = '<svg class="' + prefix + '__star ' + prefix + '__star--filled" viewBox="0 0 14 14" width="14" height="14" fill="#F5A623" xmlns="http://www.w3.org/2000/svg">'
            + '<path d="M7 1l1.76 3.57 3.94.57-2.85 2.78.67 3.93L7 10.07l-3.52 1.78.67-3.93L1.3 5.14l3.94-.57L7 1z"/></svg>';
        var empty = '<svg class="' + prefix + '__star ' + prefix + '__star--empty" viewBox="0 0 14 14" width="14" height="14" fill="#DDD" xmlns="http://www.w3.org/2000/svg">'
            + '<path d="M7 1l1.76 3.57 3.94.57-2.85 2.78.67 3.93L7 10.07l-3.52 1.78.67-3.93L1.3 5.14l3.94-.57L7 1z"/></svg>';

        for (var i = 1; i <= 5; i++) {
            html += (rating >= i) ? filled : empty;
        }

        return html;
    }
All rows above produced by Repobility · https://repobility.com
formatPrice function · javascript · L1483-L1487 (5 LOC)
파트너클래스/파트너/js.js
    function formatPrice(price) {
        var num = Number(price);
        if (isNaN(num)) return '0';
        return String(num).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    }
formatDate function · javascript · L1494-L1498 (5 LOC)
파트너클래스/파트너/js.js
    function formatDate(dateStr) {
        if (!dateStr) return '-';
        var d = String(dateStr).substring(0, 10);
        return d.replace(/-/g, '.');
    }
padZero function · javascript · L1505-L1507 (3 LOC)
파트너클래스/파트너/js.js
    function padZero(n) {
        return n < 10 ? '0' + n : '' + n;
    }
escapeHtml function · javascript · L1514-L1518 (5 LOC)
파트너클래스/파트너/js.js
    function escapeHtml(str) {
        if (!str) return '';
        var map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' };
        return String(str).replace(/[&<>"']/g, function(m) { return map[m]; });
    }
escapeAttr function · javascript · L1525-L1527 (3 LOC)
파트너클래스/파트너/js.js
    function escapeAttr(str) {
        return escapeHtml(str);
    }
escapeText function · javascript · L1534-L1536 (3 LOC)
파트너클래스/파트너/js.js
    function escapeText(str) {
        return str ? String(str) : '';
    }
showElement function · javascript · L1542-L1545 (4 LOC)
파트너클래스/파트너/js.js
    function showElement(id) {
        var el = document.getElementById(id);
        if (el) el.style.display = '';
    }
hideElement function · javascript · L1551-L1554 (4 LOC)
파트너클래스/파트너/js.js
    function hideElement(id) {
        var el = document.getElementById(id);
        if (el) el.style.display = 'none';
    }
Repobility · code-quality intelligence platform · https://repobility.com
setTextById function · javascript · L1561-L1564 (4 LOC)
파트너클래스/파트너/js.js
    function setTextById(id, text) {
        var el = document.getElementById(id);
        if (el) el.textContent = text;
    }
showLoading function · javascript · L1569-L1571 (3 LOC)
파트너클래스/파트너/js.js
    function showLoading() {
        showElement('pdLoadingOverlay');
    }
hideLoading function · javascript · L1576-L1578 (3 LOC)
파트너클래스/파트너/js.js
    function hideLoading() {
        hideElement('pdLoadingOverlay');
    }
debounce function · javascript · L1584-L1587 (4 LOC)
파트너클래스/파트너/js.js
    function debounce(fn) {
        if (debounceTimer) clearTimeout(debounceTimer);
        debounceTimer = setTimeout(fn, DEBOUNCE_DELAY);
    }
calculatePeriodDates function · javascript · L1594-L1632 (39 LOC)
파트너클래스/파트너/js.js
    function calculatePeriodDates(period) {
        var now = new Date();
        var from, to;

        switch (period) {
            case 'this_week':
                var dayOfWeek = now.getDay();
                var diff = dayOfWeek === 0 ? 6 : dayOfWeek - 1; /* 월요일 기준 */
                from = new Date(now);
                from.setDate(now.getDate() - diff);
                to = new Date(from);
                to.setDate(from.getDate() + 6);
                break;

            case 'last_month':
                from = new Date(now.getFullYear(), now.getMonth() - 1, 1);
                to = new Date(now.getFullYear(), now.getMonth(), 0);
                break;

            case 'custom':
                var fromInput = document.getElementById('pdBookingDateFrom');
                var toInput = document.getElementById('pdBookingDateTo');
                return {
                    from: fromInput ? fromInput.value : '',
                    to: toInput ? toInput.value : ''
         
init function · javascript · L72-L100 (29 LOC)
파트너클래스/목록/js.js
    function init() {
        // 카테고리 목록 동적 로드
        loadCategories();

        // 필터 이벤트 바인딩
        bindFilters();

        // 정렬 이벤트 바인딩
        bindSort();

        // 모바일 필터 드로어 초기화
        initFilterDrawer();

        // 필터 그룹 토글(접기/펼치기) 초기화
        initFilterGroupToggles();

        // 가격 슬라이더 초기화
        initPriceRange();

        // 빈결과/에러 상태 버튼 바인딩
        bindStateButtons();

        // URL 파라미터에서 필터 복원 (딥링크 지원)
        restoreFiltersFromURL();

        // 스켈레톤 표시 후 첫 데이터 로드
        renderSkeleton();
        fetchClasses(currentFilters);
    }
fetchClasses function · javascript · L111-L181 (71 LOC)
파트너클래스/목록/js.js
    function fetchClasses(filters) {
        if (isLoading) return;

        // 캐시 확인
        var cacheKey = buildCacheKey(filters);
        var cached = getCached(cacheKey);
        if (cached) {
            handleClassesResponse(cached);
            return;
        }

        isLoading = true;
        renderSkeleton();
        hideElement('catalogEmpty');
        hideElement('catalogError');

        // API 쿼리 파라미터 구성
        var params = new URLSearchParams();
        params.append('action', 'getClasses');

        if (filters.category && filters.category.length > 0) {
            params.append('category', filters.category.join(','));
        }
        if (filters.level && filters.level.length > 0) {
            params.append('level', filters.level.join(','));
        }
        if (filters.type && filters.type.length > 0) {
            params.append('type', filters.type.join(','));
        }
        if (filters.region && filters.region.length > 0) {
            params.append('region
handleClassesResponse function · javascript · L187-L208 (22 LOC)
파트너클래스/목록/js.js
    function handleClassesResponse(data) {
        var classes = (data.data && Array.isArray(data.data)) ? data.data : [];
        var pagination = data.pagination || { page: 1, totalCount: 0, totalPages: 1 };

        currentClasses = classes;

        // 결과 건수 업데이트
        updateResultCount(pagination.totalCount || classes.length);

        if (classes.length === 0) {
            clearGrid();
            renderEmpty();
            hidePagination();
        } else {
            renderCards(classes);
            renderPagination(pagination);
            // Schema.org 구조화 데이터 주입
            injectSchemaOrg(classes);
            // 스크롤 애니메이션 초기화
            initScrollReveal();
        }
    }
Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
loadCategories function · javascript · L213-L240 (28 LOC)
파트너클래스/목록/js.js
    function loadCategories() {
        var cached = getCached('categories');
        if (cached) {
            renderCategoryFilters(cached);
            return;
        }

        var params = new URLSearchParams();
        params.append('action', 'getCategories');
        var url = GAS_URL + '?' + params.toString();

        fetch(url, { method: 'GET', redirect: 'follow' })
            .then(function(response) {
                return response.json();
            })
            .then(function(data) {
                if (data && data.success && Array.isArray(data.data)) {
                    setCache('categories', data.data);
                    renderCategoryFilters(data.data);
                }
            })
            .catch(function(err) {
                console.error('[ClassCatalog] 카테고리 로드 실패:', err);
                // 폴백: 기본 카테고리
                var fallback = ['\uC555\uD654', '\uBCF4\uC874\uD654', '\uCE94\uB4E4', '\uB9AC\uC2A4', '\uD558\uBC14\uB9AC\uC6C0', '\uB808\uC9C4\u
renderCategoryFilters function · javascript · L246-L267 (22 LOC)
파트너클래스/목록/js.js
    function renderCategoryFilters(categories) {
        var container = document.getElementById('categoryFilters');
        if (!container) return;

        var html = '';
        for (var i = 0; i < categories.length; i++) {
            var cat = escapeHtml(categories[i]);
            html += '<label class="filter-checkbox">'
                + '<input type="checkbox" name="category" value="' + cat + '">'
                + '<span class="filter-checkbox__mark"></span>'
                + '<span class="filter-checkbox__label">' + cat + '</span>'
                + '</label>';
        }

        container.innerHTML = html;

        // 새로 생성된 체크박스에 이벤트 바인딩
        var checkboxes = container.querySelectorAll('input[type="checkbox"]');
        for (var j = 0; j < checkboxes.length; j++) {
            checkboxes[j].addEventListener('change', onFilterChange);
        }
    }
getCached function · javascript · L279-L293 (15 LOC)
파트너클래스/목록/js.js
    function getCached(key) {
        try {
            var raw = localStorage.getItem(CACHE_PREFIX + key);
            if (!raw) return null;

            var entry = JSON.parse(raw);
            if (Date.now() - entry.timestamp > CACHE_TTL) {
                localStorage.removeItem(CACHE_PREFIX + key);
                return null;
            }
            return entry.data;
        } catch (e) {
            return null;
        }
    }
setCache function · javascript · L300-L311 (12 LOC)
파트너클래스/목록/js.js
    function setCache(key, data) {
        try {
            var entry = {
                timestamp: Date.now(),
                data: data
            };
            localStorage.setItem(CACHE_PREFIX + key, JSON.stringify(entry));
        } catch (e) {
            // localStorage 용량 초과 시 기존 캐시 정리
            clearExpiredCache();
        }
    }
buildCacheKey function · javascript · L318-L334 (17 LOC)
파트너클래스/목록/js.js
    function buildCacheKey(filters) {
        var keyObj = {
            c: filters.category ? filters.category.join(',') : '',
            l: filters.level ? filters.level.join(',') : '',
            t: filters.type ? filters.type.join(',') : '',
            r: filters.region ? filters.region.join(',') : '',
            s: filters.sort || 'latest',
            p: filters.page || 1,
            m: filters.maxPrice || 200000
        };

        try {
            return btoa(unescape(encodeURIComponent(JSON.stringify(keyObj))));
        } catch (e) {
            return JSON.stringify(keyObj);
        }
    }
clearExpiredCache function · javascript · L339-L360 (22 LOC)
파트너클래스/목록/js.js
    function clearExpiredCache() {
        try {
            var keysToRemove = [];
            for (var i = 0; i < localStorage.length; i++) {
                var key = localStorage.key(i);
                if (key && key.indexOf(CACHE_PREFIX) === 0) {
                    var raw = localStorage.getItem(key);
                    if (raw) {
                        var entry = JSON.parse(raw);
                        if (Date.now() - entry.timestamp > CACHE_TTL) {
                            keysToRemove.push(key);
                        }
                    }
                }
            }
            for (var j = 0; j < keysToRemove.length; j++) {
                localStorage.removeItem(keysToRemove[j]);
            }
        } catch (e) {
            /* 무시 */
        }
    }
renderCards function · javascript · L371-L387 (17 LOC)
파트너클래스/목록/js.js
    function renderCards(classes) {
        var grid = document.getElementById('classGrid');
        if (!grid) return;

        // 반별(half star) 그라데이션 SVG defs를 한 번만 선언 (id 중복 방지)
        var html = '<svg width="0" height="0" style="position:absolute" aria-hidden="true">'
            + '<defs><linearGradient id="ccHalfStarGrad">'
            + '<stop offset="50%" stop-color="#F5A623"/>'
            + '<stop offset="50%" stop-color="#DDD"/>'
            + '</linearGradient></defs></svg>';

        for (var i = 0; i < classes.length; i++) {
            html += renderCard(classes[i]);
        }

        grid.innerHTML = html;
    }
renderCard function · javascript · L394-L478 (85 LOC)
파트너클래스/목록/js.js
    function renderCard(cls) {
        var classId = escapeHtml(cls.class_id || '');
        var className = escapeHtml(cls.class_name || '');
        var category = escapeHtml(cls.category || '');
        var level = escapeHtml(cls.level || '');
        var typeRaw = cls.type || '';
        var typeLabel = escapeHtml(typeRaw);
        var typeCss = TYPE_CLASS_MAP[typeRaw] || 'oneday';
        var price = formatPrice(cls.price || 0);
        var duration = cls.duration_min || 0;
        var durationText = duration >= 60
            ? Math.floor(duration / 60) + '\uC2DC\uAC04' + (duration % 60 > 0 ? ' ' + (duration % 60) + '\uBD84' : '')
            : duration + '\uBD84';
        var thumbnail = cls.thumbnail_url || '';
        var location = escapeHtml(cls.location || '');
        var partnerName = escapeHtml(cls.partner_name || '');
        var avgRating = parseFloat(cls.avg_rating) || 0;
        var classCount = parseInt(cls.class_count) || 0;
        var detailUrl = '../\uC0C1\uC138
Repobility analyzer · published findings · https://repobility.com
renderSkeleton function · javascript · L483-L501 (19 LOC)
파트너클래스/목록/js.js
    function renderSkeleton() {
        var grid = document.getElementById('classGrid');
        if (!grid) return;

        var html = '';
        for (var i = 0; i < SKELETON_COUNT; i++) {
            html += '<div class="skeleton-card" aria-hidden="true">'
                + '<div class="skeleton-card__thumb"></div>'
                + '<div class="skeleton-card__body">'
                + '<div class="skeleton-card__line skeleton-card__line--medium"></div>'
                + '<div class="skeleton-card__line skeleton-card__line--short"></div>'
                + '<div class="skeleton-card__line skeleton-card__line--short"></div>'
                + '<div class="skeleton-card__line skeleton-card__line--price"></div>'
                + '</div>'
                + '</div>';
        }

        grid.innerHTML = html;
    }
clearGrid function · javascript · L506-L509 (4 LOC)
파트너클래스/목록/js.js
    function clearGrid() {
        var grid = document.getElementById('classGrid');
        if (grid) grid.innerHTML = '';
    }
renderStars function · javascript · L521-L545 (25 LOC)
파트너클래스/목록/js.js
    function renderStars(rating) {
        var html = '';
        var fullStarSvg = '<svg class="class-card__star class-card__star--filled" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg">'
            + '<path d="M7 1l1.76 3.57 3.94.57-2.85 2.78.67 3.93L7 10.07l-3.52 1.78.67-3.93L1.3 5.14l3.94-.57L7 1z"/>'
            + '</svg>';
        /* 반별: defs를 개별 SVG에 넣지 않고, renderCards()에서 한 번 선언한 공유 gradient 참조 */
        var halfStarSvg = '<svg class="class-card__star class-card__star--half" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg">'
            + '<path d="M7 1l1.76 3.57 3.94.57-2.85 2.78.67 3.93L7 10.07l-3.52 1.78.67-3.93L1.3 5.14l3.94-.57L7 1z" fill="url(#ccHalfStarGrad)"/>'
            + '</svg>';
        var emptyStarSvg = '<svg class="class-card__star class-card__star--empty" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg">'
            + '<path d="M7 1l1.76 3.57 3.94.57-2.85 2.78.67 3.93L7 10.07l-3.52 1.78.67-3.93L1.3
bindFilters function · javascript · L555-L572 (18 LOC)
파트너클래스/목록/js.js
    function bindFilters() {
        // 이벤트 위임: filter-panel 내 체크박스 변경 감지
        var panel = document.getElementById('filterPanel');
        if (!panel) return;

        panel.addEventListener('change', function(e) {
            var target = e.target;
            if (target && target.type === 'checkbox') {
                onFilterChange();
            }
        });

        // 필터 초기화 버튼
        var resetBtns = panel.querySelectorAll('.filter-reset');
        for (var i = 0; i < resetBtns.length; i++) {
            resetBtns[i].addEventListener('click', resetFilters);
        }
    }
onFilterChange function · javascript · L577-L590 (14 LOC)
파트너클래스/목록/js.js
    function onFilterChange() {
        if (debounceTimer) {
            clearTimeout(debounceTimer);
        }

        debounceTimer = setTimeout(function() {
            collectFilterValues();
            currentFilters.page = 1; // 필터 변경 시 1페이지로
            updateFilterBadge();
            updateActiveChips();
            updateURLParams();
            fetchClasses(currentFilters);
        }, DEBOUNCE_DELAY);
    }
collectFilterValues function · javascript · L595-L600 (6 LOC)
파트너클래스/목록/js.js
    function collectFilterValues() {
        currentFilters.category = getCheckedValues('category');
        currentFilters.level = getCheckedValues('level');
        currentFilters.type = getCheckedValues('type');
        currentFilters.region = getCheckedValues('region');
    }
getCheckedValues function · javascript · L607-L618 (12 LOC)
파트너클래스/목록/js.js
    function getCheckedValues(name) {
        var values = [];
        var panel = document.getElementById('filterPanel');
        if (!panel) return values;

        var checkboxes = panel.querySelectorAll('input[name="' + name + '"]:checked');
        for (var i = 0; i < checkboxes.length; i++) {
            var val = checkboxes[i].value;
            if (val) values.push(val);
        }
        return values;
    }
resetFilters function · javascript · L623-L661 (39 LOC)
파트너클래스/목록/js.js
    function resetFilters() {
        var panel = document.getElementById('filterPanel');
        if (!panel) return;

        // 모든 체크박스 해제
        var checkboxes = panel.querySelectorAll('input[type="checkbox"]');
        for (var i = 0; i < checkboxes.length; i++) {
            checkboxes[i].checked = false;
        }

        // 가격 슬라이더 초기화
        var priceSlider = document.getElementById('priceRange');
        if (priceSlider) {
            priceSlider.value = 200000;
            updatePriceDisplay(200000);
            updateSliderTrack(priceSlider);
        }

        // 정렬 초기화
        var sortSelect = document.getElementById('sortSelect');
        if (sortSelect) sortSelect.value = 'latest';

        // 필터 상태 초기화
        currentFilters = {
            category: [],
            level: [],
            type: [],
            region: [],
            sort: 'latest',
            page: 1,
            limit: PAGE_LIMIT,
            maxPrice: 200000
        };

        updateFilterBadge(
All rows above produced by Repobility · https://repobility.com
bindSort function · javascript · L671-L681 (11 LOC)
파트너클래스/목록/js.js
    function bindSort() {
        var sortSelect = document.getElementById('sortSelect');
        if (!sortSelect) return;

        sortSelect.addEventListener('change', function() {
            currentFilters.sort = this.value;
            currentFilters.page = 1;
            updateURLParams();
            fetchClasses(currentFilters);
        });
    }
initPriceRange function · javascript · L691-L711 (21 LOC)
파트너클래스/목록/js.js
    function initPriceRange() {
        var slider = document.getElementById('priceRange');
        if (!slider) return;

        // 슬라이더 트랙 초기 색상
        updateSliderTrack(slider);

        // input 이벤트 (드래그 중 실시간 표시)
        slider.addEventListener('input', function() {
            var value = parseInt(this.value);
            updatePriceDisplay(value);
            updateSliderTrack(this);
        });

        // change 이벤트 (드래그 완료 후 API 호출)
        slider.addEventListener('change', function() {
            var value = parseInt(this.value);
            currentFilters.maxPrice = value;
            onFilterChange();
        });
    }
updatePriceDisplay function · javascript · L717-L726 (10 LOC)
파트너클래스/목록/js.js
    function updatePriceDisplay(value) {
        var label = document.getElementById('priceRangeValue');
        if (label) {
            if (value >= 200000) {
                label.textContent = '200,000\uC6D0+';
            } else {
                label.textContent = formatPrice(value) + '\uC6D0';
            }
        }
    }
‹ prevpage 3 / 7next ›