wp-wellnet / script.js
CSNET's picture
ออกแบบเว็บไซต์ HTML5 หน้าเดียว (Single Page Web App) แบบ mobile-first ภาษาไทยทั้งหมด สำหรับแพลตฟอร์ม WP WELLNET ที่เน้นฟื้นฟูสุขภาพและชะลอวัย (Longevity Platform) โดยใช้ข้อมูลจาก Smart Band (แนว Whoop) และ MyScale (วัดองค์ประกอบร่างกาย)
feb7fff verified
Raw
History Blame Contribute Delete
8.88 kB
// Initialize app
document.addEventListener('DOMContentLoaded', function() {
initializeCharts();
setupEventListeners();
updateRealTimeData();
});
// Navigation
function scrollToSection(sectionId) {
const section = document.getElementById(sectionId);
if (section) {
section.scrollIntoView({ behavior: 'smooth', block: 'start' });
updateActiveNav(sectionId);
}
}
function updateActiveNav(sectionId) {
const navButtons = document.querySelectorAll('nav button');
navButtons.forEach(btn => {
btn.classList.remove('text-primary');
btn.classList.add('text-gray-500');
});
const activeBtn = document.querySelector(`nav button[onclick*="${sectionId}"]`);
if (activeBtn) {
activeBtn.classList.remove('text-gray-500');
activeBtn.classList.add('text-primary');
}
}
// AI Analysis
function runAIAnalysis() {
const resultsDiv = document.getElementById('ai-results');
resultsDiv.innerHTML = '<div class="text-center py-4"><div class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-white"></div></div>';
setTimeout(() => {
const insights = [
{ icon: '🧘', text: 'ควรทำสมาธิ 10 นาที ก่อนนอนเพื่อลดความเครียด' },
{ icon: '💧', text: 'ต้องการดื่มน้ำเพิ่ม 500 มล. ในช่วงบ่าย' },
{ icon: '🥗', text: 'แนะนำเพิ่มผักใบเขียวในมื้อเย็นวันนี้' },
{ icon: '☀️', text: 'ต้องการรับแสงแดด 15 นาทีเพื่อวิตามิน D' }
];
resultsDiv.innerHTML = insights.map(insight => `
<div class="bg-white bg-opacity-20 rounded-lg p-3 slide-up">
<p class="text-sm">${insight.icon} ${insight.text}</p>
</div>
`).join('');
}, 1500);
}
// Initialize Charts
function initializeCharts() {
drawLineChart('hrvChart', [45, 48, 52, 50, 55, 52, 54], '#EF4444');
drawLineChart('sleepChart', [6.5, 7.2, 6.8, 7.5, 8.0, 7.8, 7.2], '#8B5CF6');
drawLineChart('weightChart', [76, 75.5, 75.8, 75.2, 75, 74.8, 75], '#3B82F6');
}
function drawLineChart(canvasId, data, color) {
const canvas = document.getElementById(canvasId);
if (!canvas) return;
const ctx = canvas.getContext('2d');
const width = canvas.width = canvas.offsetWidth;
const height = canvas.height = 128;
const padding = 10;
const graphWidth = width - padding * 2;
const graphHeight = height - padding * 2;
const maxValue = Math.max(...data);
const minValue = Math.min(...data);
const range = maxValue - minValue;
// Clear canvas
ctx.clearRect(0, 0, width, height);
// Draw grid lines
ctx.strokeStyle = '#E5E7EB';
ctx.lineWidth = 1;
for (let i = 0; i <= 4; i++) {
const y = padding + (graphHeight / 4) * i;
ctx.beginPath();
ctx.moveTo(padding, y);
ctx.lineTo(width - padding, y);
ctx.stroke();
}
// Draw line chart
ctx.strokeStyle = color;
ctx.lineWidth = 2;
ctx.beginPath();
data.forEach((value, index) => {
const x = padding + (graphWidth / (data.length - 1)) * index;
const y = padding + graphHeight - ((value - minValue) / range) * graphHeight;
if (index === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
});
ctx.stroke();
// Draw points
ctx.fillStyle = color;
data.forEach((value, index) => {
const x = padding + (graphWidth / (data.length - 1)) * index;
const y = padding + graphHeight - ((value - minValue) / range) * graphHeight;
ctx.beginPath();
ctx.arc(x, y, 3, 0, Math.PI * 2);
ctx.fill();
});
}
function changeTimeRange(days) {
const buttons = document.querySelectorAll('.time-btn');
buttons.forEach(btn => {
btn.classList.remove('bg-primary', 'text-white');
btn.classList.add('bg-gray-100', 'text-gray-600');
});
event.target.classList.remove('bg-gray-100', 'text-gray-600');
event.target.classList.add('bg-primary', 'text-white');
// Simulate loading new data
const hrvData = days === '7' ? [45, 48, 52, 50, 55, 52, 54] :
days === '30' ? [42, 45, 48, 46, 50, 52, 51, 53, 52, 54, 55, 53] :
[40, 42, 44, 43, 45, 47, 46, 48, 49, 48, 50, 52, 51, 53, 54, 55, 54, 53, 52, 54];
drawLineChart('hrvChart', hrvData, '#EF4444');
}
// Chat functions
function startChat() {
document.getElementById('chatModal').classList.remove('hidden');
document.body.style.overflow = 'hidden';
}
function closeChat() {
document.getElementById('chatModal').classList.add('hidden');
document.body.style.overflow = 'auto';
}
function startVideoCall() {
// Simulate video call
alert('กำลังเชื่อมต่อกับ BioCoach... ฟีเจอร์วิดีโอคอลจะเปิดใช้งานเร็วๆ นี้');
}
// Quick reorder
function quickReorder() {
// Show loading state
event.target.innerHTML = '<div class="inline-block animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div>';
event.target.disabled = true;
setTimeout(() => {
event.target.innerHTML = '✓ สั่งซื้อสำเร็จ!';
event.target.classList.remove('bg-primary');
event.target.classList.add('bg-green-500');
setTimeout(() => {
event.target.innerHTML = 'สั่งซ้ำ 1 คลิก';
event.target.disabled = false;
event.target.classList.remove('bg-green-500');
event.target.classList.add('bg-primary');
}, 2000);
}, 1500);
}
// Notifications
function toggleNotifications() {
alert('คุณมีการแจ้งเตือนใหม่: อย่าลืมทานวิตามิน ADEK ในช่วงเช้านะครับ!');
}
// Setup event listeners
function setupEventListeners() {
// Handle checkbox changes
document.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
checkbox.addEventListener('change', function() {
updateProgress();
});
});
}
// Update progress
function updateProgress() {
const checkboxes = document.querySelectorAll('#plan input[type="checkbox"]');
const checked = document.querySelectorAll('#plan input[type="checkbox"]:checked');
const percentage = Math.round((checked.length / checkboxes.length) * 100);
const progressBar = document.querySelector('#plan .bg-primary.h-2');
const percentageText = document.querySelector('#plan .font-semibold');
if (progressBar) {
progressBar.style.width = `${percentage}%`;
}
if (percentageText) {
percentageText.textContent = `${percentage}%`;
}
}
// Update real-time data
function updateRealTimeData() {
setInterval(() => {
// Simulate real-time updates
const stressElement = document.querySelector('.text-yellow-500').parentElement.parentElement.querySelector('.text-2xl');
if (stressElement && Math.random() > 0.7) {
const newStress = Math.floor(Math.random() * 20) + 30;
stressElement.textContent = newStress;
}
}, 10000);
}
// Handle pull-to-refresh
let startY = 0;
let isPulling = false;
document.addEventListener('touchstart', function(e) {
if (window.scrollY === 0) {
startY = e.touches[0].pageY;
isPulling = true;
}
});
document.addEventListener('touchmove', function(e) {
if (!isPulling) return;
const currentY = e.touches[0].pageY;
const pullDistance = currentY - startY;
if (pullDistance > 0 && pullDistance < 100) {
e.preventDefault();
document.body.style.transform = `translateY(${pullDistance * 0.5}px)`;
}
});
document.addEventListener('touchend', function(e) {
if (!isPulling) return;
isPulling = false;
document.body.style.transform = '';
const currentY = e.changedTouches[0].pageY;
const pullDistance = currentY - startY;
if (pullDistance > 80) {
location.reload();
}
});
// Lazy load images
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
document.querySelectorAll('img[data-src]').forEach(img => {
imageObserver.observe(img);
});