Spaces:
No application file
No application file
/** | |
* RAG ๊ฒ์ ์ฑ๋ด ์ฅ์น ๊ด๋ฆฌ JavaScript | |
*/ | |
// DOM ์์ | |
const deviceTab = document.getElementById('deviceTab'); | |
const deviceSection = document.getElementById('deviceSection'); | |
const checkDeviceStatusButton = document.getElementById('checkDeviceStatusButton'); | |
const deviceStatusLoading = document.getElementById('deviceStatusLoading'); | |
const deviceStatusResult = document.getElementById('deviceStatusResult'); | |
const statusIcon = document.getElementById('statusIcon'); | |
const statusText = document.getElementById('statusText'); | |
const refreshDevicesButton = document.getElementById('refreshDevicesButton'); | |
const deviceList = document.getElementById('deviceList'); | |
const devicesLoading = document.getElementById('devicesLoading'); | |
const noDevicesMessage = document.getElementById('noDevicesMessage'); | |
const loadProgramsButton = document.getElementById('loadProgramsButton'); | |
const programsLoading = document.getElementById('programsLoading'); | |
const programsList = document.getElementById('programsList'); | |
const noProgramsMessage = document.getElementById('noProgramsMessage'); | |
// ์ฅ์น ์๋ฒ URL ์ค์ | |
// ์ง์ ์ ๊ทผ ์ค์ : ๋น ๋ฌธ์์ด์ด๋ฉด ํ์ฌ ํธ์คํธ์ 5050 ํฌํธ๋ฅผ ์ฌ์ฉ | |
let DEVICE_SERVER_URL = ''; // ์๋ฒ์์ ์ ๋ฌ๋ URL์ด ์์ผ๋ฉด ์ด๊ธฐํ ์ ์ค์ ๋จ | |
/** | |
* ์ฅ์น ์๋ฒ API ๊ฒฝ๋ก ์์ฑ ํจ์ | |
* @param {string} endpoint - API ์๋ํฌ์ธํธ ๊ฒฝ๋ก | |
* @returns {string} - ์์ ํ API URL | |
*/ | |
function getDeviceApiUrl(endpoint) { | |
// ์ง์ ์ ๊ทผ ๋ชจ๋์ธ ๊ฒฝ์ฐ (๋ณ๋ ์๋ฒ์ ์ง์ ์์ฒญ) | |
if (DEVICE_SERVER_URL) { | |
return `${DEVICE_SERVER_URL}${endpoint}`; | |
} | |
// ํ๋ก์ ๋ชจ๋์ธ ๊ฒฝ์ฐ (๋ด๋ถ API ๊ฒฝ๋ก ์ฌ์ฉ) | |
return endpoint; | |
} | |
/** | |
* ์ฅ์น ์๋ฒ ์ค์ ์ด๊ธฐํ (ํ์ด์ง ๋ก๋ ์ ํธ์ถ) | |
*/ | |
function initDeviceServerSettings() { | |
console.log("์ฅ์น ์๋ฒ ์ค์ ์ด๊ธฐํ ์์"); | |
// ์๋ฒ URL ์ค์ (์น ์๋ฒ๋ก๋ถํฐ ์ค์ ๋ถ๋ฌ์ค๊ธฐ) | |
fetch('/api/device/settings') | |
.then(response => { | |
if (!response.ok) { | |
throw new Error('์ค์ ์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค'); | |
} | |
return response.json(); | |
}) | |
.then(data => { | |
if (data.server_url) { | |
console.log(`์ฅ์น ์๋ฒ URL ์ค์ ๋จ: ${data.server_url}`); | |
DEVICE_SERVER_URL = data.server_url; | |
} else { | |
// ์ค์ ์์ - ์๋ ์์ฑ (ํ์ฌ ํธ์คํธ + ํฌํธ 5050) | |
const currentHost = window.location.hostname; | |
const protocol = window.location.protocol; | |
DEVICE_SERVER_URL = `${protocol}//${currentHost}:5051`; | |
console.log(`์ฅ์น ์๋ฒ URL ์๋ ์ค์ : ${DEVICE_SERVER_URL}`); | |
} | |
}) | |
.catch(error => { | |
console.error('์ฅ์น ์๋ฒ ์ค์ ์ด๊ธฐํ ์ค๋ฅ:', error); | |
// ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ (ํ์ฌ ํธ์คํธ + ํฌํธ 5051) | |
const currentHost = window.location.hostname; | |
const protocol = window.location.protocol; | |
DEVICE_SERVER_URL = `${protocol}//${currentHost}:5051`; | |
console.log(`์ฅ์น ์๋ฒ URL ๊ธฐ๋ณธ๊ฐ ์ค์ : ${DEVICE_SERVER_URL}`); | |
}); | |
} | |
// ํ์ด์ง ๋ก๋ ์ ์ด๊ธฐํ | |
document.addEventListener('DOMContentLoaded', () => { | |
console.log("์ฅ์น ๊ด๋ฆฌ ๋ชจ๋ ์ด๊ธฐํ"); | |
// ์ฅ์น ์๋ฒ ์ค์ ์ด๊ธฐํ | |
initDeviceServerSettings(); | |
// ํญ ์ ํ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ ์ด๋ฏธ app.js์์ ๋ฑ๋ก๋์ด ์์ผ๋ฏ๋ก ์ฌ๊ธฐ์๋ ๋ฑ๋กํ์ง ์์ | |
// ๋์ ์ ์ญ ํจ์๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ค์ ๋์ด ์๋์ง ํ์ธ | |
if (typeof window.switchTab !== 'function') { | |
console.log("window.switchTab ํจ์๊ฐ ์ ์๋์ง ์์์ต๋๋ค. ๋ด๋ถ ๊ตฌํ์ ์ฌ์ฉํฉ๋๋ค."); | |
} else { | |
console.log("window.switchTab ํจ์ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค."); | |
} | |
// ์ฅ์น ์ํ ํ์ธ ๋ฒํผ ์ด๋ฒคํธ ๋ฆฌ์ค๋ | |
checkDeviceStatusButton.addEventListener('click', () => { | |
console.log("์ฅ์น ์ํ ํ์ธ ๋ฒํผ ํด๋ฆญ"); | |
checkDeviceStatus(); | |
}); | |
// ์ฅ์น ๋ชฉ๋ก ์๋ก๊ณ ์นจ ๋ฒํผ ์ด๋ฒคํธ ๋ฆฌ์ค๋ | |
refreshDevicesButton.addEventListener('click', () => { | |
console.log("์ฅ์น ๋ชฉ๋ก ์๋ก๊ณ ์นจ ๋ฒํผ ํด๋ฆญ"); | |
loadDevices(); | |
}); | |
// ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ๋ก๋ ๋ฒํผ ์ด๋ฒคํธ ๋ฆฌ์ค๋ | |
loadProgramsButton.addEventListener('click', () => { | |
console.log("ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ๋ก๋ ๋ฒํผ ํด๋ฆญ"); | |
loadPrograms(); | |
}); | |
}); | |
/** | |
* ์๋ฌ ์ฒ๋ฆฌ ํฌํผ ํจ์ | |
* @param {Error} error - ๋ฐ์ํ ์ค๋ฅ | |
* @returns {string} - ์ฌ์ฉ์์๊ฒ ํ์ํ ์ค๋ฅ ๋ฉ์์ง | |
*/ | |
function handleError(error) { | |
console.error("์ค๋ฅ ๋ฐ์:", error); | |
if (error.name === 'AbortError') { | |
return '์์ฒญ ์๊ฐ์ด ์ด๊ณผ๋์์ต๋๋ค. ์๋ฒ๊ฐ ์๋ตํ์ง ์์ต๋๋ค.'; | |
} | |
if (error.message && (error.message.includes('NetworkError') || error.message.includes('Failed to fetch'))) { | |
return '๋คํธ์ํฌ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์๋ฒ์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.'; | |
} | |
return `์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: ${error.message || '์ ์ ์๋ ์ค๋ฅ'}`; | |
} | |
/** | |
* HTML ์ด์ค์ผ์ดํ ํจ์ (XSS ๋ฐฉ์ง) | |
* @param {string} unsafe - ์ด์ค์ผ์ดํ ์ ๋ฌธ์์ด | |
* @returns {string} - ์ด์ค์ผ์ดํ ํ ๋ฌธ์์ด | |
*/ | |
function escapeHtml(unsafe) { | |
if (typeof unsafe !== 'string') return unsafe; | |
return unsafe | |
.replace(/&/g, "&") | |
.replace(/</g, "<") | |
.replace(/>/g, ">") | |
.replace(/"/g, """) | |
.replace(/'/g, "'"); | |
} | |
/** | |
* ์ฅ์น ๊ด๋ฆฌ ์๋ฒ ์ํ ํ์ธ ํจ์ - ์ ์ญ ํจ์๋ก export | |
*/ | |
async function checkDeviceStatus() { | |
console.log("์ฅ์น ์ํ ํ์ธ ์ค..."); | |
// UI ์ ๋ฐ์ดํธ | |
deviceStatusResult.classList.add('hidden'); | |
deviceStatusLoading.classList.remove('hidden'); | |
try { | |
// ํ์์์ ์ค์ ์ ์ํ ์ปจํธ๋กค๋ฌ | |
const controller = new AbortController(); | |
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5์ด ํ์์์ | |
// API ์์ฒญ - ์์ ๋ URL ๊ตฌ์ฑ ์ฌ์ฉ | |
const response = await fetch(getDeviceApiUrl('/api/status'), { | |
signal: controller.signal | |
}); | |
clearTimeout(timeoutId); // ํ์์์ ํด์ | |
// ์๋ต ์ฒ๋ฆฌ | |
if (!response.ok) { | |
throw new Error(`HTTP ์ค๋ฅ: ${response.status}`); | |
} | |
const data = await response.json(); | |
console.log("์ฅ์น ์ํ ์๋ต:", data); | |
// UI ์ ๋ฐ์ดํธ | |
deviceStatusLoading.classList.add('hidden'); | |
deviceStatusResult.classList.remove('hidden'); | |
if (data.status === "online") { | |
// ์จ๋ผ์ธ ์ํ์ธ ๊ฒฝ์ฐ | |
statusIcon.innerHTML = '<i class="fas fa-circle online"></i>'; | |
statusText.textContent = `์๋ฒ ์ํ: ${data.status || '์ ์'}`; | |
// ์๋์ผ๋ก ์ฅ์น ๋ชฉ๋ก ๋ก๋ | |
loadDevices(); | |
} else { | |
// ์คํ๋ผ์ธ ๋๋ ์ค๋ฅ ์ํ์ธ ๊ฒฝ์ฐ | |
statusIcon.innerHTML = '<i class="fas fa-circle offline"></i>'; | |
statusText.textContent = `์๋ฒ ์ค๋ฅ: ${data.error || '์ ์ ์๋ ์ค๋ฅ'}`; | |
} | |
} catch (error) { | |
console.error("์ฅ์น ์ํ ํ์ธ ์ค๋ฅ:", error); | |
// UI ์ ๋ฐ์ดํธ | |
deviceStatusLoading.classList.add('hidden'); | |
deviceStatusResult.classList.remove('hidden'); | |
statusIcon.innerHTML = '<i class="fas fa-circle offline"></i>'; | |
statusText.textContent = handleError(error); | |
} | |
} | |
/** | |
* ์ฅ์น ๋ชฉ๋ก ๋ก๋ ํจ์ | |
*/ | |
async function loadDevices() { | |
console.log("์ฅ์น ๋ชฉ๋ก ๋ก๋ ์ค..."); | |
// UI ์ ๋ฐ์ดํธ | |
deviceList.innerHTML = ''; | |
noDevicesMessage.classList.add('hidden'); | |
devicesLoading.classList.remove('hidden'); | |
try { | |
// ํ์์์ ์ค์ ์ ์ํ ์ปจํธ๋กค๋ฌ | |
const controller = new AbortController(); | |
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5์ด ํ์์์ | |
// API ์์ฒญ - ์์ ๋ URL ๊ตฌ์ฑ ์ฌ์ฉ | |
const response = await fetch(getDeviceApiUrl('/api/devices'), { | |
signal: controller.signal | |
}); | |
clearTimeout(timeoutId); // ํ์์์ ํด์ | |
// ์๋ต ์ฒ๋ฆฌ | |
if (!response.ok) { | |
throw new Error(`HTTP ์ค๋ฅ: ${response.status}`); | |
} | |
const data = await response.json(); | |
console.log("์ฅ์น ๋ชฉ๋ก ์๋ต:", data); | |
// UI ์ ๋ฐ์ดํธ | |
devicesLoading.classList.add('hidden'); | |
if (data.devices && data.devices.length > 0) { | |
// ์ฅ์น ๋ชฉ๋ก ํ์ | |
data.devices.forEach(device => { | |
const deviceElement = createDeviceItem(device); | |
deviceList.appendChild(deviceElement); | |
}); | |
} else { | |
// ์ฅ์น ์์ ๋ฉ์์ง ํ์ | |
noDevicesMessage.classList.remove('hidden'); | |
} | |
} catch (error) { | |
console.error("์ฅ์น ๋ชฉ๋ก ๋ก๋ ์ค๋ฅ:", error); | |
// UI ์ ๋ฐ์ดํธ | |
devicesLoading.classList.add('hidden'); | |
noDevicesMessage.classList.remove('hidden'); | |
noDevicesMessage.textContent = handleError(error); | |
} | |
} | |
/** | |
* ์ฅ์น ์์ดํ ์์ฑ ํจ์ | |
* @param {Object} device - ์ฅ์น ์ ๋ณด ๊ฐ์ฒด | |
* @returns {HTMLElement} - ์ฅ์น ์์ดํ DOM ์์ | |
*/ | |
function createDeviceItem(device) { | |
const deviceItem = document.createElement('div'); | |
deviceItem.classList.add('device-item'); | |
// ์ํ์ ๋ฐ๋ฅธ ํด๋์ค ์ถ๊ฐ | |
if (device.status === 'online' || device.status === '์จ๋ผ์ธ') { | |
deviceItem.classList.add('online'); | |
} else if (device.status === 'offline' || device.status === '์คํ๋ผ์ธ') { | |
deviceItem.classList.add('offline'); | |
} else if (device.status === 'warning' || device.status === '๊ฒฝ๊ณ ') { | |
deviceItem.classList.add('warning'); | |
} | |
// ์ฅ์น ํค๋ (์ด๋ฆ ๋ฐ ์ํ) | |
const deviceHeader = document.createElement('div'); | |
deviceHeader.classList.add('device-item-header'); | |
const deviceName = document.createElement('div'); | |
deviceName.classList.add('device-name'); | |
deviceName.textContent = device.name || '์ ์ ์๋ ์ฅ์น'; | |
const deviceStatusBadge = document.createElement('div'); | |
deviceStatusBadge.classList.add('device-status-badge'); | |
// ์ํ์ ๋ฐ๋ฅธ ๋ฐฐ์ง ์ค์ | |
if (device.status === 'online' || device.status === '์จ๋ผ์ธ') { | |
deviceStatusBadge.classList.add('online'); | |
deviceStatusBadge.textContent = '์จ๋ผ์ธ'; | |
} else if (device.status === 'offline' || device.status === '์คํ๋ผ์ธ') { | |
deviceStatusBadge.classList.add('offline'); | |
deviceStatusBadge.textContent = '์คํ๋ผ์ธ'; | |
} else if (device.status === 'warning' || device.status === '๊ฒฝ๊ณ ') { | |
deviceStatusBadge.classList.add('warning'); | |
deviceStatusBadge.textContent = '๊ฒฝ๊ณ '; | |
} else { | |
deviceStatusBadge.textContent = device.status || '์ ์ ์์'; | |
} | |
deviceHeader.appendChild(deviceName); | |
deviceHeader.appendChild(deviceStatusBadge); | |
// ์ฅ์น ์ ๋ณด | |
const deviceInfo = document.createElement('div'); | |
deviceInfo.classList.add('device-info'); | |
deviceInfo.textContent = `์ ํ: ${device.type || '์ ์ ์์'}`; | |
// ์ฅ์น ์ธ๋ถ ์ ๋ณด | |
const deviceDetails = document.createElement('div'); | |
deviceDetails.classList.add('device-details'); | |
// ์ถ๊ฐ ์ ๋ณด๊ฐ ์๋ ๊ฒฝ์ฐ ํ์ | |
if (device.ip) { | |
deviceDetails.textContent += `IP: ${device.ip}`; | |
} | |
if (device.mac) { | |
deviceDetails.textContent += (deviceDetails.textContent ? ', ' : '') + `MAC: ${device.mac}`; | |
} | |
if (device.lastSeen) { | |
deviceDetails.textContent += (deviceDetails.textContent ? ', ' : '') + `๋ง์ง๋ง ํ๋: ${device.lastSeen}`; | |
} | |
// ์์ดํ ์ ์์ ์ถ๊ฐ | |
deviceItem.appendChild(deviceHeader); | |
deviceItem.appendChild(deviceInfo); | |
if (deviceDetails.textContent) { | |
deviceItem.appendChild(deviceDetails); | |
} | |
return deviceItem; | |
} | |
/** | |
* ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ๋ก๋ ํจ์ | |
*/ | |
async function loadPrograms() { | |
console.log("ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ๋ก๋ ์ค..."); | |
// UI ์ ๋ฐ์ดํธ | |
programsList.innerHTML = ''; | |
noProgramsMessage.classList.add('hidden'); | |
programsLoading.classList.remove('hidden'); | |
try { | |
// ํ์์์ ์ค์ ์ ์ํ ์ปจํธ๋กค๋ฌ | |
const controller = new AbortController(); | |
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5์ด ํ์์์ | |
// API ์์ฒญ - ์์ ๋ URL ๊ตฌ์ฑ ์ฌ์ฉ | |
const response = await fetch(getDeviceApiUrl('/api/programs'), { | |
signal: controller.signal | |
}); | |
clearTimeout(timeoutId); // ํ์์์ ํด์ | |
// ์๋ต ์ฒ๋ฆฌ | |
if (!response.ok) { | |
throw new Error(`HTTP ์ค๋ฅ: ${response.status}`); | |
} | |
const data = await response.json(); | |
console.log("ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ์๋ต:", data); | |
// UI ์ ๋ฐ์ดํธ | |
programsLoading.classList.add('hidden'); | |
if (data.programs && data.programs.length > 0) { | |
// ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ํ์ | |
data.programs.forEach(program => { | |
const programElement = createProgramItem(program); | |
programsList.appendChild(programElement); | |
}); | |
} else { | |
// ํ๋ก๊ทธ๋จ ์์ ๋ฉ์์ง ํ์ | |
noProgramsMessage.classList.remove('hidden'); | |
} | |
} catch (error) { | |
console.error("ํ๋ก๊ทธ๋จ ๋ชฉ๋ก ๋ก๋ ์ค๋ฅ:", error); | |
// UI ์ ๋ฐ์ดํธ | |
programsLoading.classList.add('hidden'); | |
noProgramsMessage.classList.remove('hidden'); | |
noProgramsMessage.textContent = handleError(error); | |
} | |
} | |
/** | |
* ํ๋ก๊ทธ๋จ ์์ดํ ์์ฑ ํจ์ | |
* @param {Object} program - ํ๋ก๊ทธ๋จ ์ ๋ณด ๊ฐ์ฒด | |
* @returns {HTMLElement} - ํ๋ก๊ทธ๋จ ์์ดํ DOM ์์ | |
*/ | |
function createProgramItem(program) { | |
const programItem = document.createElement('div'); | |
programItem.classList.add('program-item'); | |
// ํ๋ก๊ทธ๋จ ํค๋ (์ด๋ฆ) | |
const programHeader = document.createElement('div'); | |
programHeader.classList.add('program-item-header'); | |
const programName = document.createElement('div'); | |
programName.classList.add('program-name'); | |
programName.textContent = program.name || '์ ์ ์๋ ํ๋ก๊ทธ๋จ'; | |
programHeader.appendChild(programName); | |
// ํ๋ก๊ทธ๋จ ์ค๋ช | |
if (program.description) { | |
const programDescription = document.createElement('div'); | |
programDescription.classList.add('program-description'); | |
programDescription.textContent = program.description; | |
programItem.appendChild(programDescription); | |
} | |
// ์คํ ๋ฒํผ | |
const executeButton = document.createElement('button'); | |
executeButton.classList.add('execute-btn'); | |
executeButton.textContent = '์คํ'; | |
executeButton.addEventListener('click', () => { | |
executeProgram(program.id, program.name); | |
}); | |
// ์์ดํ ์ ์์ ์ถ๊ฐ | |
programItem.appendChild(programHeader); | |
programItem.appendChild(executeButton); | |
return programItem; | |
} | |
/** | |
* ํ๋ก๊ทธ๋จ ์คํ ํจ์ | |
* @param {string} programId - ์คํํ ํ๋ก๊ทธ๋จ ID | |
* @param {string} programName - ํ๋ก๊ทธ๋จ ์ด๋ฆ (์๋ฆผ์ฉ) | |
*/ | |
async function executeProgram(programId, programName) { | |
if (!programId) return; | |
console.log(`ํ๋ก๊ทธ๋จ ์คํ ์์ฒญ: ${programId} (${programName})`); | |
// ์คํ ํ์ธ | |
if (!confirm(`'${programName}' ํ๋ก๊ทธ๋จ์ ์คํํ์๊ฒ ์ต๋๊น?`)) { | |
console.log('ํ๋ก๊ทธ๋จ ์คํ ์ทจ์๋จ'); | |
return; | |
} | |
try { | |
// ๋ก๋ฉ ์๋ฆผ ํ์ | |
showNotification(`'${programName}' ์คํ ์ค...`, 'info'); | |
// API ์์ฒญ - ์์ ๋ URL ๊ตฌ์ฑ ์ฌ์ฉ | |
const response = await fetch(getDeviceApiUrl(`/api/programs/${programId}/execute`), { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({}) // ํ์ ์ ์ถ๊ฐ ํ๋ผ๋ฏธํฐ ์ ๋ฌ | |
}); | |
// ์๋ต ์ฒ๋ฆฌ | |
if (!response.ok) { | |
throw new Error(`HTTP ์ค๋ฅ: ${response.status}`); | |
} | |
const data = await response.json(); | |
console.log(`ํ๋ก๊ทธ๋จ ์คํ ์๋ต:`, data); | |
// ๊ฒฐ๊ณผ ์ฒ๋ฆฌ | |
if (data.success) { | |
showNotification(`'${programName}' ์คํ ์ฑ๊ณต: ${data.message}`, 'success'); | |
} else { | |
showNotification(`'${programName}' ์คํ ์คํจ: ${data.message || '์ ์ ์๋ ์ค๋ฅ'}`, 'error'); | |
} | |
} catch (error) { | |
console.error(`ํ๋ก๊ทธ๋จ ์คํ ์ค๋ฅ (${programId}):`, error); | |
showNotification(`'${programName}' ์คํ ์ค๋ฅ: ${handleError(error)}`, 'error'); | |
} | |
} | |
/** | |
* ์๋ฆผ ํ์ ํจ์ | |
* @param {string} message - ์๋ฆผ ๋ฉ์์ง | |
* @param {string} type - ์๋ฆผ ์ ํ ('success', 'error', 'warning') | |
*/ | |
function showNotification(message, type = 'info') { | |
// ๊ธฐ์กด ์๋ฆผ์ด ์์ผ๋ฉด ์ ๊ฑฐ | |
const existingNotification = document.querySelector('.notification'); | |
if (existingNotification) { | |
existingNotification.remove(); | |
} | |
// ์ ์๋ฆผ ์์ฑ | |
const notification = document.createElement('div'); | |
notification.classList.add('notification', type); | |
notification.textContent = message; | |
// ์๋ฆผ ๋ซ๊ธฐ ๋ฒํผ | |
const closeButton = document.createElement('button'); | |
closeButton.classList.add('notification-close'); | |
closeButton.innerHTML = '×'; | |
closeButton.addEventListener('click', () => { | |
notification.remove(); | |
}); | |
notification.appendChild(closeButton); | |
// ๋ฌธ์์ ์๋ฆผ ์ถ๊ฐ | |
document.body.appendChild(notification); | |
// ์ผ์ ์๊ฐ ํ ์๋์ผ๋ก ์ฌ๋ผ์ง๋๋ก ์ค์ | |
setTimeout(() => { | |
if (document.body.contains(notification)) { | |
notification.remove(); | |
} | |
}, 5000); // 5์ด ํ ์ฌ๋ผ์ง | |
} | |
// checkDeviceStatus ํจ์๋ฅผ ์ ์ญ์ผ๋ก ๋ ธ์ถ | |
window.checkDeviceStatus = checkDeviceStatus; |