Function bodies 302 total
updateTimelineProgress function · javascript · L679-L684 (6 LOC)브랜드스토리/브랜드페이지/js/heritage.js
function updateTimelineProgress() {
if (timelineLine && timelineItems.length > 0) {
var progress = (revealedCount / timelineItems.length) * 100;
timelineLine.style.setProperty('--timeline-progress', progress + '%');
}
}debounce function · javascript · L19-L29 (11 LOC)브랜드스토리/브랜드페이지/js.js
function debounce(func, wait) {
var timeout;
return function() {
var context = this;
var args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
};
}throttle function · javascript · L37-L50 (14 LOC)브랜드스토리/브랜드페이지/js.js
function throttle(func, limit) {
var inThrottle;
return function() {
var args = arguments;
var context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(function() {
inThrottle = false;
}, limit);
}
};
}adjustPadding function · javascript · L118-L121 (4 LOC)브랜드스토리/브랜드페이지/js.js
function adjustPadding() {
var paddingTop = (jQuery(window).width() >= 768) ? '0' : '104px';
jqContainer.css('padding-top', paddingTop);
}debounce function · javascript · L156-L166 (11 LOC)브랜드스토리/브랜드페이지/js.js
function debounce(func, wait) {
var timeout;
return function() {
var context = this;
var args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
};
}isInViewport function · javascript · L173-L176 (4 LOC)브랜드스토리/브랜드페이지/js.js
function isInViewport(el) {
var rect = el.getBoundingClientRect();
return rect.top < window.innerHeight && rect.bottom > 0;
}initScrollProgress function · javascript · L186-L200 (15 LOC)브랜드스토리/브랜드페이지/js.js
function initScrollProgress() {
var progressBar = document.querySelector('.scroll-progress');
if (!progressBar) return;
function updateProgress() {
var scrollTop = window.scrollY;
var docHeight = document.documentElement.scrollHeight - window.innerHeight;
var progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
/* 메이크샵 이스케이프 주의: 템플릿 리터럴 미사용 */
progressBar.style.width = progress + '%';
}
window.addEventListener('scroll', updateProgress, { passive: true });
updateProgress();
}Repobility (the analyzer behind this table) · https://repobility.com
updateProgress function · javascript · L190-L196 (7 LOC)브랜드스토리/브랜드페이지/js.js
function updateProgress() {
var scrollTop = window.scrollY;
var docHeight = document.documentElement.scrollHeight - window.innerHeight;
var progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
/* 메이크샵 이스케이프 주의: 템플릿 리터럴 미사용 */
progressBar.style.width = progress + '%';
}initSectionNav function · javascript · L207-L251 (45 LOC)브랜드스토리/브랜드페이지/js.js
function initSectionNav() {
var sections = document.querySelectorAll('section[id]');
var desktopNavLinks = document.querySelectorAll('.section-nav a');
var sectionNav = document.querySelector('.section-nav');
var heroSection = document.querySelector('.hero-section');
if (!sections.length) return;
/* 현재 섹션 감지 */
var sectionObserver = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var sectionId = entry.target.id;
/* 데스크톱 네비게이션 */
desktopNavLinks.forEach(function(link) {
link.classList.remove('active');
});
var activeLink = document.querySelector('.section-nav a[data-section="' + sectionId + '"]');
if (activeLink) {
initAchievementTabs function · javascript · L258-L285 (28 LOC)브랜드스토리/브랜드페이지/js.js
function initAchievementTabs() {
var tabBtns = document.querySelectorAll('.tab-btn');
var tabContents = document.querySelectorAll('.tab-content');
if (!tabBtns.length) return;
tabBtns.forEach(function(btn) {
btn.addEventListener('click', function() {
var tabId = this.getAttribute('data-tab');
tabBtns.forEach(function(b) {
b.classList.remove('active');
b.setAttribute('aria-selected', 'false');
});
this.classList.add('active');
this.setAttribute('aria-selected', 'true');
tabContents.forEach(function(content) {
content.classList.remove('active');
});
var selectedContent = document.querySelector('.tab-content[data-tab-id="' + tabId + '"]');
if (selectedContent) {
animateCount function · javascript · L292-L312 (21 LOC)브랜드스토리/브랜드페이지/js.js
function animateCount(element, target, duration) {
duration = duration || 2000;
var startTime = performance.now();
function animate(currentTime) {
var elapsed = currentTime - startTime;
var progress = Math.min(elapsed / duration, 1);
/* easeOutCubic */
var easedProgress = 1 - Math.pow(1 - progress, 3);
var current = Math.floor(target * easedProgress);
element.textContent = current + '+';
if (progress < 1) {
requestAnimationFrame(animate);
} else {
element.textContent = target + '+';
}
}
requestAnimationFrame(animate);
}animate function · javascript · L296-L309 (14 LOC)브랜드스토리/브랜드페이지/js.js
function animate(currentTime) {
var elapsed = currentTime - startTime;
var progress = Math.min(elapsed / duration, 1);
/* easeOutCubic */
var easedProgress = 1 - Math.pow(1 - progress, 3);
var current = Math.floor(target * easedProgress);
element.textContent = current + '+';
if (progress < 1) {
requestAnimationFrame(animate);
} else {
element.textContent = target + '+';
}
}initStatsCounter function · javascript · L314-L337 (24 LOC)브랜드스토리/브랜드페이지/js.js
function initStatsCounter() {
var statsSection = document.querySelector('.stats-counter');
if (!statsSection) return;
var statsObserver = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var statNumbers = document.querySelectorAll('.stat-number');
statNumbers.forEach(function(stat) {
if (!stat.hasAttribute('data-animated')) {
var value = parseInt(stat.getAttribute('data-value'), 10);
if (!isNaN(value)) {
animateCount(stat, value);
stat.setAttribute('data-animated', 'true');
}
}
});
statsObserver.unobserve(entry.target);
initBookCarousel function · javascript · L344-L373 (30 LOC)브랜드스토리/브랜드페이지/js.js
function initBookCarousel() {
if (typeof jQuery === 'undefined' || typeof jQuery.fn.slick === 'undefined') return;
jQuery('.book-carousel').slick({
slidesToShow: 4,
slidesToScroll: 1,
infinite: true,
dots: true,
arrows: true,
autoplay: false,
responsive: [
{
breakpoint: 1200,
settings: { slidesToShow: 3, slidesToScroll: 1 }
},
{
breakpoint: 992,
settings: { slidesToShow: 2.5, slidesToScroll: 1 }
},
{
breakpoint: 768,
settings: { slidesToShow: 2, slidesToScroll: 1 }
},
{
breakpoint: 640,
settings: { slidesToShow: 1.2, initGalleryLightbox function · javascript · L380-L528 (149 LOC)브랜드스토리/브랜드페이지/js.js
function initGalleryLightbox() {
var galleryItems = document.querySelectorAll('.gallery-item');
var lightboxEl = document.querySelector('.heritage-lightbox');
if (!galleryItems.length || !lightboxEl) return;
var swiperInstance = null;
var closeBtn = lightboxEl.querySelector('.lightbox-close-btn');
var previousFocus = null;
/* Swiper 인스턴스 생성 */
function createSwiper() {
if (typeof Swiper === 'undefined') return null;
return new Swiper('.heritage-lightbox .swiper', {
loop: false,
keyboard: {
enabled: true,
onlyInViewport: false
},
navigation: {
nextEl: '.heritage-lightbox .swiper-button-next',
prevEl: '.heritage-lightbox .swiper-button-prev'
},
About: code-quality intelligence by Repobility · https://repobility.com
createSwiper function · javascript · L391-L412 (22 LOC)브랜드스토리/브랜드페이지/js.js
function createSwiper() {
if (typeof Swiper === 'undefined') return null;
return new Swiper('.heritage-lightbox .swiper', {
loop: false,
keyboard: {
enabled: true,
onlyInViewport: false
},
navigation: {
nextEl: '.heritage-lightbox .swiper-button-next',
prevEl: '.heritage-lightbox .swiper-button-prev'
},
pagination: {
el: '.heritage-lightbox .swiper-pagination',
clickable: true
},
zoom: {
maxRatio: 3
}
});
}openLightbox function · javascript · L415-L471 (57 LOC)브랜드스토리/브랜드페이지/js.js
function openLightbox(index) {
/* 현재 보이는 갤러리 아이템으로 슬라이드 생성 */
var visibleItems = [];
galleryItems.forEach(function(item) {
if (!item.classList.contains('hidden')) {
visibleItems.push(item);
}
});
/* 슬라이드 Wrapper 업데이트 */
var swiperWrapper = lightboxEl.querySelector('.swiper-wrapper');
if (!swiperWrapper) return;
swiperWrapper.innerHTML = '';
visibleItems.forEach(function(item) {
var img = item.querySelector('img');
if (img) {
var slide = document.createElement('div');
slide.className = 'swiper-slide';
var slideImg = document.createElement('img');
slideImg.src = img.src;
slideImg.alt = img.alt;
closeLightbox function · javascript · L474-L484 (11 LOC)브랜드스토리/브랜드페이지/js.js
function closeLightbox() {
lightboxEl.classList.remove('active');
document.body.style.overflow = '';
if (swiperInstance) {
swiperInstance.destroy(true, true);
swiperInstance = null;
}
if (previousFocus) {
previousFocus.focus();
}
}initGalleryFilter function · javascript · L535-L564 (30 LOC)브랜드스토리/브랜드페이지/js.js
function initGalleryFilter() {
var filterBtns = document.querySelectorAll('.filter-btn');
var galleryItems = document.querySelectorAll('.gallery-item[data-category]');
if (!filterBtns.length || !galleryItems.length) return;
filterBtns.forEach(function(btn) {
btn.addEventListener('click', function() {
var category = this.getAttribute('data-category');
filterBtns.forEach(function(b) {
b.classList.remove('active');
b.setAttribute('aria-selected', 'false');
});
this.classList.add('active');
this.setAttribute('aria-selected', 'true');
galleryItems.forEach(function(item) {
var itemCategory = item.getAttribute('data-category');
if (category === 'all' || itemCategory === category) {
initSmoothScroll function · javascript · L571-L588 (18 LOC)브랜드스토리/브랜드페이지/js.js
function initSmoothScroll() {
var anchorLinks = document.querySelectorAll('a[href^="#"]');
anchorLinks.forEach(function(link) {
link.addEventListener('click', function(e) {
var href = this.getAttribute('href');
if (href !== '#') {
e.preventDefault();
var target = document.querySelector(href);
if (target) {
window.scrollTo({
top: target.offsetTop,
behavior: 'smooth'
});
}
}
});
});
}initMobileDrawer function · javascript · L595-L658 (64 LOC)브랜드스토리/브랜드페이지/js.js
function initMobileDrawer() {
var hamburgerBtn = document.querySelector('.hamburger-btn');
var drawer = document.querySelector('.mobile-drawer');
var drawerClose = document.querySelector('.drawer-close');
var drawerOverlay = document.querySelector('.drawer-overlay');
var drawerLinks = document.querySelectorAll('.drawer-nav a');
if (!hamburgerBtn || !drawer) return;
function openDrawer() {
drawer.classList.add('active');
drawerOverlay.classList.add('active');
hamburgerBtn.classList.add('active');
hamburgerBtn.setAttribute('aria-expanded', 'true');
document.body.style.overflow = 'hidden';
if (drawerClose) drawerClose.focus();
}
function closeDrawer() {
drawer.classList.remove('active');
drawerOverlay.classList.remove('active');
hopenDrawer function · javascript · L604-L611 (8 LOC)브랜드스토리/브랜드페이지/js.js
function openDrawer() {
drawer.classList.add('active');
drawerOverlay.classList.add('active');
hamburgerBtn.classList.add('active');
hamburgerBtn.setAttribute('aria-expanded', 'true');
document.body.style.overflow = 'hidden';
if (drawerClose) drawerClose.focus();
}closeDrawer function · javascript · L613-L620 (8 LOC)브랜드스토리/브랜드페이지/js.js
function closeDrawer() {
drawer.classList.remove('active');
drawerOverlay.classList.remove('active');
hamburgerBtn.classList.remove('active');
hamburgerBtn.setAttribute('aria-expanded', 'false');
document.body.style.overflow = '';
hamburgerBtn.focus();
}Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
initTimelineModal function · javascript · L665-L772 (108 LOC)브랜드스토리/브랜드페이지/js.js
function initTimelineModal() {
var timelineItems = document.querySelectorAll('.timeline-item');
var modal = document.getElementById('timelineModal');
if (!modal || !timelineItems.length) return;
var modalClose = modal.querySelector('.modal-close');
var modalYear = document.getElementById('modalYear');
var modalTitle = document.getElementById('modalTitle');
var modalDescription = document.getElementById('modalDescription');
var previousFocus = null;
/* 타임라인 상세 데이터 */
var timelineData = {
'1985': {
title: '\uC138\uACC4\uD50C\uB77C\uC6CC \uC62C\uB9BC\uD53D \uB3D9\uC0C1 \uC218\uC0C1',
description: '\uC555\uD654 \uACF5\uC608\uC758 \uAD6D\uC81C\uC801 \uC778\uC815\uC744 \uBC1B\uC740 \uCCAB \uD574. \uC774 \uC21C\uAC04\uBD80\uD130 "\uC5B4\uB5BB\uAC8C \uD558\uBA74 \uC774 \uC544\uB984\uB2E4\uC6C0\uC744 \uC601\uC6openModal function · javascript · L725-L737 (13 LOC)브랜드스토리/브랜드페이지/js.js
function openModal(year) {
var data = timelineData[year];
if (!data) return;
if (modalYear) modalYear.textContent = year;
if (modalTitle) modalTitle.textContent = data.title;
if (modalDescription) modalDescription.textContent = data.description;
modal.classList.add('active');
document.body.style.overflow = 'hidden';
previousFocus = document.activeElement;
if (modalClose) modalClose.focus();
}closeModal function · javascript · L739-L743 (5 LOC)브랜드스토리/브랜드페이지/js.js
function closeModal() {
modal.classList.remove('active');
document.body.style.overflow = '';
if (previousFocus) previousFocus.focus();
}initScrollAnimations function · javascript · L779-L844 (66 LOC)브랜드스토리/브랜드페이지/js.js
function initScrollAnimations() {
var scrollRevealObserver = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
entry.target.classList.add('scroll-revealed');
scrollRevealObserver.unobserve(entry.target);
}
});
}, { threshold: 0.1, rootMargin: '50px 0px 0px 0px' });
/* 섹션 타이틀 */
document.querySelectorAll('#heritage-main .section-title').forEach(function(el) {
if (isInViewport(el)) {
el.classList.add('scroll-revealed');
} else {
el.classList.add('animate-on-scroll');
scrollRevealObserver.observe(el);
}
});
/* 카드들 */
document.querySelectorAll('#heritage-main .value-card, #heritage-main .education-card, #heritage-mainupdateTimelineProgress function · javascript · L814-L819 (6 LOC)브랜드스토리/브랜드페이지/js.js
function updateTimelineProgress() {
if (timelineLine && timelineItems.length > 0) {
var progress = (revealedCount / timelineItems.length) * 100;
timelineLine.style.setProperty('--timeline-progress', progress + '%');
}
}init function · javascript · L68-L99 (32 LOC)파트너클래스/파트너/js.js
function init() {
// GAS URL 검증
if (!GAS_URL) {
console.error('[PartnerDash] GAS_URL이 설정되지 않았습니다.');
return;
}
// 현재 월 설정
var now = new Date();
currentMonth = now.getFullYear() + '-' + padZero(now.getMonth() + 1);
// 회원 ID 읽기 (가상태그에서)
var memberEl = document.getElementById('pdMemberId');
if (memberEl) {
memberId = (memberEl.textContent || '').trim();
}
// 미로그인 처리
if (!memberId) {
showNotice('login');
return;
}
// 로딩 표시 후 파트너 인증
showLoading();
authenticatePartner();
// 이벤트 바인딩
bindTabEvents();
bindModalEvents();
bindMonthSelector();
}authenticatePartner function · javascript · L109-L148 (40 LOC)파트너클래스/파트너/js.js
function authenticatePartner() {
callGAS('getPartnerAuth', { member_id: memberId }, function(err, data) {
hideLoading();
if (err || !data || !data.success) {
showNotice('nonpartner');
return;
}
var partner = data.data;
if (!partner || !partner.partner_code) {
showNotice('nonpartner');
return;
}
// 상태별 분기
var status = (partner.status || '').toLowerCase();
if (status === 'pending' || status === 'review') {
showNotice('pending');
return;
}
if (status === 'inactive' || status === 'suspended') {
showNotice('inactive');
return;
}
if (status !== 'active') {
showNotice('nonpartner');
return;
}
// 인증 성공
partnerData = partner;
showNotice function · javascript · L154-L176 (23 LOC)파트너클래스/파트너/js.js
function showNotice(type) {
showElement('pdNoticeArea');
hideElement('pdMainArea');
// 모든 안내 숨기기
hideElement('pdNoticeLogin');
hideElement('pdNoticeNonPartner');
hideElement('pdNoticePending');
hideElement('pdNoticeInactive');
// 해당 안내만 표시
var noticeMap = {
'login': 'pdNoticeLogin',
'nonpartner': 'pdNoticeNonPartner',
'pending': 'pdNoticePending',
'inactive': 'pdNoticeInactive'
};
var targetId = noticeMap[type];
if (targetId) {
showElement(targetId);
}
}Repobility · code-quality intelligence platform · https://repobility.com
renderDashboardHeader function · javascript · L186-L211 (26 LOC)파트너클래스/파트너/js.js
function renderDashboardHeader() {
if (!partnerData) return;
// 파트너 이름
var nameEl = document.getElementById('pdPartnerName');
if (nameEl) {
nameEl.textContent = escapeText(partnerData.partner_name || partnerData.member_id) + '\uB2D8, \uC548\uB155\uD558\uC138\uC694!';
}
// 등급 배지
var badgeEl = document.getElementById('pdGradeBadge');
if (badgeEl) {
var grade = (partnerData.grade || 'SILVER').toUpperCase();
badgeEl.textContent = grade + ' PARTNER';
badgeEl.className = 'pd-grade-badge pd-grade-badge--' + grade.toLowerCase();
}
// 서브타이틀
var subtitleEl = document.getElementById('pdHeaderSubtitle');
if (subtitleEl) {
subtitleEl.textContent = '\uC624\uB298\uC758 \uC218\uC5C5 \uD604\uD669\uC774\uC5D0\uC694.';
}
// 월 레이블
updateMonthLabel();
}loadDashboard function · javascript · L221-L250 (30 LOC)파트너클래스/파트너/js.js
function loadDashboard() {
showLoading();
callGAS('getPartnerDashboard', {
member_id: memberId,
month: currentMonth
}, function(err, data) {
hideLoading();
if (err || !data || !data.success) {
showToast('\uB300\uC2DC\uBCF4\uB4DC \uB370\uC774\uD130\uB97C \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.', 'error');
return;
}
dashboardData = data.data || {};
myClasses = dashboardData.classes || [];
// 요약 카드 렌더링
renderSummaryCards();
// 강의 필터 드롭다운 채우기
populateClassDropdowns();
// 수익 월 드롭다운 채우기
populateRevenueMonths();
// 현재 탭 데이터 로드
loadTabData(currentTab);
});
}renderSummaryCards function · javascript · L260-L269 (10 LOC)파트너클래스/파트너/js.js
function renderSummaryCards() {
if (!dashboardData) return;
var summary = dashboardData.summary || {};
setTextById('pdSumRevenue', formatPrice(summary.total_revenue || 0) + '\uC6D0');
setTextById('pdSumFee', formatPrice(summary.total_fee || 0) + '\uC6D0');
setTextById('pdSumReserve', formatPrice(summary.available_reserve || 0) + '\uC6D0');
setTextById('pdSumBooking', (summary.total_bookings || 0) + '\uAC74');
}bindTabEvents function · javascript · L279-L292 (14 LOC)파트너클래스/파트너/js.js
function bindTabEvents() {
var tabContainer = document.querySelector('.partner-dashboard .pd-tabs');
if (!tabContainer) return;
tabContainer.addEventListener('click', function(e) {
var btn = e.target.closest('.pd-tabs__btn');
if (!btn || btn.classList.contains('is-active')) return;
var tabName = btn.getAttribute('data-tab');
if (tabName) {
switchTab(tabName);
}
});
}switchTab function · javascript · L298-L330 (33 LOC)파트너클래스/파트너/js.js
function switchTab(tabName) {
currentTab = tabName;
// 탭 버튼 활성화
var tabBtns = document.querySelectorAll('.partner-dashboard .pd-tabs__btn');
for (var i = 0; i < tabBtns.length; i++) {
var isTarget = tabBtns[i].getAttribute('data-tab') === tabName;
tabBtns[i].classList.toggle('is-active', isTarget);
tabBtns[i].setAttribute('aria-selected', isTarget ? 'true' : 'false');
}
// 탭 콘텐츠 활성화
var tabPanels = document.querySelectorAll('.partner-dashboard .pd-tab-content');
for (var j = 0; j < tabPanels.length; j++) {
tabPanels[j].classList.remove('is-active');
}
var targetMap = {
'classes': 'pdTabClasses',
'bookings': 'pdTabBookings',
'revenue': 'pdTabRevenue',
'reviews': 'pdTabReviews'
};
var targetId = targetMap[tabName];
if (targetId) {
var panel = document.getElementById(targeloadTabData function · javascript · L336-L352 (17 LOC)파트너클래스/파트너/js.js
function loadTabData(tabName) {
switch (tabName) {
case 'classes':
renderMyClasses();
break;
case 'bookings':
loadBookings();
break;
case 'revenue':
loadRevenue();
break;
case 'reviews':
reviewPage = 1;
loadReviews();
break;
}
}renderMyClasses function · javascript · L362-L392 (31 LOC)파트너클래스/파트너/js.js
function renderMyClasses() {
var container = document.getElementById('pdClassList');
var emptyEl = document.getElementById('pdClassEmpty');
if (!container) return;
var classes = myClasses;
if (!classes || classes.length === 0) {
container.innerHTML = '';
if (emptyEl) emptyEl.style.display = '';
return;
}
if (emptyEl) emptyEl.style.display = 'none';
// SVG defs (반별 그라데이션)
var html = '<svg width="0" height="0" style="position:absolute" aria-hidden="true">'
+ '<defs><linearGradient id="pdHalfStarGrad">'
+ '<stop offset="50%" stop-color="#F5A623"/>'
+ '<stop offset="50%" stop-color="#DDD"/>'
+ '</linearGradient></defs></svg>';
for (var i = 0; i < classes.length; i++) {
html += renderClassCard(classes[i]);
}
container.innerHTML = html;
// 상태 토글 버튼 이벤트
bindClassStatusButtons()renderClassCard function · javascript · L399-L444 (46 LOC)파트너클래스/파트너/js.js
function renderClassCard(cls) {
var classId = escapeAttr(cls.class_id || '');
var className = escapeHtml(cls.class_name || '');
var category = escapeHtml(cls.category || '');
var status = (cls.status || 'active').toLowerCase();
var statusLabel = { 'active': '\uD65C\uC131', 'inactive': '\uBE44\uD65C\uC131', 'pending': '\uC2EC\uC0AC\uC911' }[status] || status;
var avgRating = parseFloat(cls.avg_rating) || 0;
var bookingCount = parseInt(cls.booking_count) || 0;
var thumbnail = cls.thumbnail_url || '';
var starsHtml = renderStars(avgRating, 'pd-review-card');
var thumbHtml = thumbnail
? '<img src="' + escapeAttr(thumbnail) + '" alt="' + escapeAttr(cls.class_name || '') + '" loading="lazy">'
: '';
var toggleBtnText = status === 'active' ? '\uBE44\uD65C\uC131\uD654' : '\uD65C\uC131\uD654';
var toggleBtnClass = status === 'active' ? 'pd-btn--outline pd-btn--sm' : 'pd-bRepobility (the analyzer behind this table) · https://repobility.com
bindClassStatusButtons function · javascript · L449-L471 (23 LOC)파트너클래스/파트너/js.js
function bindClassStatusButtons() {
var container = document.getElementById('pdClassList');
if (!container) return;
container.addEventListener('click', function(e) {
var btn = e.target.closest('.js-toggle-status');
if (!btn) return;
var classId = btn.getAttribute('data-class-id');
var currentStatus = btn.getAttribute('data-status');
var newStatus = currentStatus === 'active' ? 'inactive' : 'active';
toggleClassStatus(classId, newStatus);
});
// 새 강의 등록 버튼
var newClassBtn = document.getElementById('pdBtnNewClass');
if (newClassBtn) {
newClassBtn.addEventListener('click', function() {
openModal('pdNewClassModal');
});
}
}toggleClassStatus function · javascript · L478-L505 (28 LOC)파트너클래스/파트너/js.js
function toggleClassStatus(classId, newStatus) {
showLoading();
postGAS('updateClassStatus', {
member_id: memberId,
class_id: classId,
status: newStatus
}, function(err, data) {
hideLoading();
if (err || !data || !data.success) {
showToast('\uC0C1\uD0DC \uBCC0\uACBD\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.', 'error');
return;
}
// 로컬 데이터 업데이트
for (var i = 0; i < myClasses.length; i++) {
if (myClasses[i].class_id === classId) {
myClasses[i].status = newStatus;
break;
}
}
var statusLabel = newStatus === 'active' ? '\uD65C\uC131\uD654' : '\uBE44\uD65C\uC131\uD654';
showToast('\uAC15\uC758\uAC00 ' + statusLabel + '\uB418\uC5C8\uC2B5\uB2C8\uB2E4.', 'success');
renderMyClasses();
});
}loadBookings function · javascript · L515-L572 (58 LOC)파트너클래스/파트너/js.js
function loadBookings() {
var periodSelect = document.getElementById('pdBookingPeriod');
var classSelect = document.getElementById('pdBookingClass');
if (!periodSelect) return;
// 기간 필터에 따른 날짜 계산
var dates = calculatePeriodDates(periodSelect.value);
var params = {
member_id: memberId,
date_from: dates.from,
date_to: dates.to
};
if (classSelect && classSelect.value) {
params.class_id = classSelect.value;
}
showLoading();
callGAS('getPartnerBookings', params, function(err, data) {
hideLoading();
if (err || !data || !data.success) {
showToast('\uC608\uC57D \uD604\uD669\uC744 \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.', 'error');
return;
}
var bookingsData = data.data || {};
var bookings = bookingsData.bookings || [];
renderBookings(brenderBookings function · javascript · L578-L686 (109 LOC)파트너클래스/파트너/js.js
function renderBookings(bookings) {
var tableWrap = document.getElementById('pdBookingTable');
var emptyEl = document.getElementById('pdBookingEmpty');
var summaryEl = document.getElementById('pdBookingSummary');
if (!tableWrap) return;
if (!bookings || bookings.length === 0) {
tableWrap.innerHTML = '';
if (emptyEl) emptyEl.style.display = '';
if (summaryEl) summaryEl.innerHTML = '';
return;
}
if (emptyEl) emptyEl.style.display = 'none';
// 상태별 카운트
var statusCounts = {};
for (var i = 0; i < bookings.length; i++) {
var st = bookings[i].status || 'unknown';
statusCounts[st] = (statusCounts[st] || 0) + 1;
}
// 요약 렌더링
if (summaryEl) {
var summaryHtml = '';
var statusLabels = {
'confirmed': '\uD655\uC815',
'pending': '\uB300\uAE30',
'comploadRevenue function · javascript · L696-L724 (29 LOC)파트너클래스/파트너/js.js
function loadRevenue() {
var monthSelect = document.getElementById('pdRevenueMonth');
var selectedMonth = monthSelect ? monthSelect.value : currentMonth;
showLoading();
callGAS('getPartnerDashboard', {
member_id: memberId,
month: selectedMonth
}, function(err, data) {
hideLoading();
if (err || !data || !data.success) {
showToast('\uC218\uC775 \uB370\uC774\uD130\uB97C \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.', 'error');
return;
}
var revenueData = data.data || {};
renderRevenue(revenueData);
});
// 월 변경 이벤트 (한 번만)
if (monthSelect && !monthSelect._pdBound) {
monthSelect._pdBound = true;
monthSelect.addEventListener('change', function() {
loadRevenue();
});
}
}renderRevenue function · javascript · L730-L835 (106 LOC)파트너클래스/파트너/js.js
function renderRevenue(data) {
var summaryEl = document.getElementById('pdRevenueSummary');
var tableWrap = document.getElementById('pdRevenueTable');
var emptyEl = document.getElementById('pdRevenueEmpty');
var settlement = data.settlement || {};
var items = settlement.items || [];
// 집계 카드
if (summaryEl) {
summaryEl.innerHTML = '<div class="pd-revenue-card">'
+ '<p class="pd-revenue-card__label">\uCD1D \uB9E4\uCD9C</p>'
+ '<p class="pd-revenue-card__value">' + formatPrice(settlement.total_revenue || 0) + '\uC6D0</p>'
+ '</div>'
+ '<div class="pd-revenue-card">'
+ '<p class="pd-revenue-card__label">\uC218\uC218\uB8CC</p>'
+ '<p class="pd-revenue-card__value">' + formatPrice(settlement.total_fee || 0) + '\uC6D0</p>'
+ '</div>'
+ '<div class="pd-revenue-card">'
+ '<p classloadReviews function · javascript · L845-L898 (54 LOC)파트너클래스/파트너/js.js
function loadReviews() {
var classSelect = document.getElementById('pdReviewClass');
var params = {
member_id: memberId,
page: reviewPage,
limit: REVIEW_LIMIT
};
if (classSelect && classSelect.value) {
params.class_id = classSelect.value;
}
showLoading();
callGAS('getPartnerReviews', params, function(err, data) {
hideLoading();
if (err || !data || !data.success) {
showToast('\uD6C4\uAE30\uB97C \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.', 'error');
return;
}
var reviewData = data.data || {};
var reviews = reviewData.reviews || [];
var pagination = reviewData.pagination || {};
/* GAS 응답: summary.rating_distribution (키가 숫자 5,4,3,2,1),
summary.avg_rating, summary.total_count */
var summary = reviewData.summary || {};
renderRatingDistribution function · javascript · L904-L933 (30 LOC)파트너클래스/파트너/js.js
function renderRatingDistribution(dist) {
var container = document.getElementById('pdRatingDist');
if (!container) return;
var avg = parseFloat(dist.avg) || 0;
var total = parseInt(dist.total) || 0;
var starsHtml = renderStars(avg, 'pd-rating-dist');
var barsHtml = '';
for (var s = 5; s >= 1; s--) {
var count = parseInt(dist['star' + s]) || 0;
var pct = total > 0 ? Math.round((count / total) * 100) : 0;
barsHtml += '<div class="pd-rating-bar">'
+ '<span class="pd-rating-bar__label">' + s + '</span>'
+ '<div class="pd-rating-bar__track">'
+ '<div class="pd-rating-bar__fill" style="width:' + pct + '%"></div>'
+ '</div>'
+ '<span class="pd-rating-bar__count">' + count + '</span>'
+ '</div>';
}
container.innerHTML = '<div class="pd-rating-dist__avg">'
+ '<div class="pdAbout: code-quality intelligence by Repobility · https://repobility.com
renderReviews function · javascript · L939-L967 (29 LOC)파트너클래스/파트너/js.js
function renderReviews(reviews) {
var container = document.getElementById('pdReviewList');
var emptyEl = document.getElementById('pdReviewEmpty');
if (!container) return;
if (!reviews || reviews.length === 0) {
container.innerHTML = '';
if (emptyEl) emptyEl.style.display = '';
return;
}
if (emptyEl) emptyEl.style.display = 'none';
// SVG defs
var html = '<svg width="0" height="0" style="position:absolute" aria-hidden="true">'
+ '<defs><linearGradient id="pdRevHalfStarGrad">'
+ '<stop offset="50%" stop-color="#F5A623"/>'
+ '<stop offset="50%" stop-color="#DDD"/>'
+ '</linearGradient></defs></svg>';
for (var i = 0; i < reviews.length; i++) {
html += renderReviewCard(reviews[i]);
}
container.innerHTML = html;
// 답변 버튼 이벤트
bindReviewReplyButtons();
}renderReviewCard function · javascript · L974-L1021 (48 LOC)파트너클래스/파트너/js.js
function renderReviewCard(review) {
var rating = parseInt(review.rating) || 0;
var starsHtml = renderStars(rating, 'pd-review-card');
var reviewId = escapeAttr(review.review_id || '');
/* GAS 응답 필드: partner_answer (답변), reviewer_name_masked (리뷰어), has_answer */
var replyText = review.partner_answer || '';
var hasReply = review.has_answer || (replyText && replyText.trim());
var html = '<div class="pd-review-card" data-review-id="' + reviewId + '">'
+ '<div class="pd-review-card__header">'
+ '<div class="pd-review-card__stars">' + starsHtml + '</div>'
+ '<span class="pd-review-card__date">' + formatDate(review.created_at) + '</span>'
+ '</div>';
if (review.class_name) {
html += '<div class="pd-review-card__class">' + escapeHtml(review.class_name) + '</div>';
}
html += '<div class="pd-review-card__text">' + escapeHtml(review.content || '') + '<bindReviewReplyButtons function · javascript · L1026-L1037 (12 LOC)파트너클래스/파트너/js.js
function bindReviewReplyButtons() {
var container = document.getElementById('pdReviewList');
if (!container) return;
container.addEventListener('click', function(e) {
var btn = e.target.closest('.js-reply-btn');
if (!btn) return;
var reviewId = btn.getAttribute('data-review-id');
openReplyModal(reviewId);
});
}