1/** 2 * KomeKaigi ã¹ã¿ãã表示æ©è½ 3 */ 4(function(window, document) { 5 'use strict'; 6 7 // è¨å® 8 const CONFIG = { 9 API_URL: 'https://fortee.jp/komekaigi-2025/api/staff?type=structured', 10 SECTION_ID: 'staff', 11 CONTENT_ID: 'staff-content' 12 }; 13 14 /** 15 * ã¹ã¿ããã»ã¯ã·ã§ã³ãé表示ã«ãã 16 */ 17 function hideStaffSection() { 18 const staffSection = document.getElementById(CONFIG.SECTION_ID); 19 if (staffSection) { 20 staffSection.style.display = 'none'; 21 } 22 } 23 24 /** 25 * ã¹ã¿ãããã¼ã¿ãåå¾ãã¦è¡¨ç¤º 26 */ 27 async function loadStaffMembers() { 28 const contentElement = document.getElementById(CONFIG.CONTENT_ID); 29 if (!contentElement) return; 30 31 try { 32 const response = await fetch(CONFIG.API_URL); 33 if (!response.ok) { 34 throw new Error(`HTTP error! status: ${response.status}`); 35 } 36 const data = await response.json(); 37 38 renderStaffList(data.staff_types, contentElement); 39 40 } catch (error) { 41 console.error('ã¹ã¿ãããã¼ã¿ã®åå¾ã¨ã©ã¼:', error); 42 contentElement.innerHTML = ''; 43 hideStaffSection(); 44 } 45 } 46 47 /** 48 * ã¹ã¿ãããªã¹ããã¬ã³ããªã³ã° 49 * @param {Array} staffTypes - ã¹ã¿ããã¿ã¤ãã®é å 50 * @param {HTMLElement} container - 表示å ã®ã³ã³ããè¦ç´ 51 */
52 function renderStaffList(staffTypes, container) { 53 if (!staffTypes || staffTypes.length === 0) { 54 container.innerHTML = ''; 55 hideStaffSection(); 56 return; 57 } 58 59 const sectionTitle = ` 60 <div class="text-center mb-8"> 61 <h3 class="text-3xl section-title">ã¹ã¿ãã</h3> 62 </div> 63 `; 64 65 const staffHTML = staffTypes.map(type => { 66 // ã¢ãã¿ã¼ç»åãããã¡ã³ãã¼ã®ã¿ãã£ã«ã¿ãªã³ã° 67 const membersWithAvatar = type.staff.filter(member => member.avatar_url); 68 69 // ã¢ãã¿ã¼ç»åãããã¡ã³ãã¼ãããªãå ´åã¯ã»ã¯ã·ã§ã³ã表示ããªã 70 if (membersWithAvatar.length === 0) { 71 return ''; 72 } 73 74 return ` 75 <div class="mb-12"> 76 <h4 class="text-2xl font-semibold text-center mb-8 text-primary"> 77 ${escapeHtml(type.name)} 78 </h4> 79 <div class="staff-grid"> 80 ${membersWithAvatar.map(member => createStaffCard(member)).join('')} 81 </div> 82 </div> 83 `; 84 }).join(''); 85 86 container.innerHTML = sectionTitle + staffHTML; 87 } 88 89 /** 90 * ã¹ã¿ããã«ã¼ãã使 91 * @param {Object} member - ã¹ã¿ããã¡ã³ãã¼ã®ãã¼ã¿ 92 * @returns {string} HTMLããã¹ã 93 */ 94 function createStaffCard(member) { 95 // ã¢ãã¿ã¼ç»åããªãå ´åã¯ç©ºæåãè¿ãï¼ãã§ã«ãã£ã«ã¿ãªã³ã°æ¸ã¿ã ã念ã®ããï¼ 96 if (!member.avatar_url) { 97 return ''; 98 } 99 100 const hasLink = member.url && member.url.trim() !== ''; 101 102 const cardContent = ` 103 <div class="staff-member"> 104 <div class="staff-avatar-wrapper"> 105 <img src="${escapeHtml(member.avatar_url)}" 106 alt="${escapeHtml(member.name)}" 107 class="staff-avatar" 108 loading="lazy"> 109 </div> 110 <div class="staff-name"> 111 ${escapeHtml(member.name)} 112 </div> 113 </div> 114 `; 115 116 return hasLink 117 ? `<a href="${escapeHtml(member.url)}" 118 target="_blank" 119 rel="noopener noreferrer" 120 class="staff-link"> 121 ${cardContent} 122 </a>` 123 : cardContent; 124 } 125 126 // åæå 127 document.addEventListener('DOMContentLoaded', loadStaffMembers); 128 129})(window, document);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.